Localization
Localization in Laravel enables your application to support multiple languages and regional settings, making your package accessible to a global audience. In Bagisto, localization is deeply integrated into the system, supporting both frontend customer interfaces and backend administrative panels with consistent translation patterns.
For our RMA package, we'll implement comprehensive localization that covers admin panel labels, customer-facing messages, email notifications, and validation messages, demonstrating how to create a truly international e-commerce extension.
Learning Objective
This section demonstrates how to create organized, maintainable translation files for your Bagisto package, register them properly with the service provider, and use them effectively in views, controllers, and other components.
For detailed information on Laravel localization features, visit the Laravel Documentation on Localization.
Bagisto Localization Architecture
Bagisto's localization system extends Laravel's built-in functionality with additional features for e-commerce applications:
Translation Organization
- Admin Translations: Interface elements, form labels, buttons, and messages for administrative users
- Shop Translations: Customer-facing content, product information, checkout messages, and notifications
- Email Translations: Transactional emails, notifications, and communication templates
- Validation Translations: Custom validation messages specific to your package functionality
Namespace Support
- Package Namespacing: Each package maintains its own translation namespace for isolation
- Fallback System: Graceful fallback to default language when translations are missing
- Override Capability: Ability to override core translations without modifying core files
Multi-Language Features
- RTL Support: Right-to-left language support for Arabic, Hebrew, and other RTL languages
- Currency Localization: Automatic currency formatting based on locale settings
- Date/Time Formatting: Locale-aware date and time display throughout the interface
Understanding Laravel Localization Basics
Before diving into Bagisto-specific implementation, let's understand the foundational concepts that power Laravel's localization system.
Publish Laravel Language Files (Optional)
Laravel's default installation doesn't include the lang
directory in your project root. If you need to customize Laravel's own error messages and validation text, you can publish them:
php artisan lang:publish
This creates a lang
directory in your project root with Laravel's default English translations, which you can then modify or use as templates for other languages.
When to Use This
You typically only need to publish Laravel's language files if you want to customize framework-level messages like validation errors, authentication messages, or HTTP status messages.
Configure Application Locale
Set your default and fallback locales in config/app.php
. These settings affect how Laravel resolves translations throughout your application:
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => env('APP_LOCALE', 'en'),
'fallback_locale' => env('APP_FALLBACK_LOCALE', 'en'),
Locale Configuration Explanation
Application Locale: The primary language your application will use by default.
Fallback Locale: When a translation key is missing in the current locale, Laravel will attempt to find it in the fallback locale before displaying the key itself.
Environment Override: Using env('APP_LOCALE', 'en')
allows you to set different default locales for different environments (staging, production, etc.).
Creating Package Localization Structure
Now let's create a comprehensive localization structure for our RMA package that covers all the different types of content we'll need to translate.
Directory Structure
Create a simple language directory structure for our basic translations:
mkdir -p packages/Webkul/RMA/src/Resources/lang/en
packages
└── Webkul
└── RMA
└── src
├── ...
└── Resources
└── lang
└── en
└── app.php
Simple Translation Structure
app.php: Contains the basic translations we need for our simple admin view
Starting Simple: We're beginning with just English and one file to match our basic view implementation
Expandable: This structure can easily be expanded with more languages and specialized files as your package grows
Creating Translation Files
Let's create a simple translation file that matches our basic view implementation.
Basic Translation File
Create packages/Webkul/RMA/src/Resources/lang/en/app.php
with just the translations we need for our basic view:
<?php
return [
'admin' => [
'return-requests' => [
'title' => 'RMA Listing Title',
'content' => 'RMA Listing Content',
],
],
];
Simple Start
We're keeping the translations minimal to match our basic view implementation. This demonstrates the core concept without overwhelming complexity. As you add more features to your views, you can expand these translation files accordingly.
Registering Translations with Service Provider
Register your package translations in the service provider so they're available throughout the application. This step is crucial for Laravel to recognize and load your translation files.
Update packages/Webkul/RMA/src/Providers/RMAServiceProvider.php
:
<?php
namespace Webkul\RMA\Providers;
use Illuminate\Support\ServiceProvider;
class RMAServiceProvider extends ServiceProvider
{
/**
* Register services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
$this->loadRoutesFrom(__DIR__ . '/../Routes/admin-routes.php');
$this->loadRoutesFrom(__DIR__ . '/../Routes/shop-routes.php');
$this->loadViewsFrom(__DIR__ . '/../Resources/views', 'rma');
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'rma');
}
}
Translation Namespace
The loadTranslationsFrom()
method registers translations with the rma
namespace. This means you'll reference translation keys as rma::admin.title
or rma::shop.create-return
in your application.
Publishing Translations (Optional)
If you want to allow users to customize your package's translations, you can make them publishable:
// Add to the boot() method in RMAServiceProvider
$this->publishes([
__DIR__ . '/../Resources/lang' => resource_path('lang/vendor/rma'),
], 'rma-translations');
Users can then publish and customize your translations:
php artisan vendor:publish --tag=rma-translations
Publishing Benefits
Customization: Users can modify translations without editing your package files
Override System: Published translations take precedence over package translations
Maintenance: Users can update your package without losing their translation customizations
Localization: Teams can add new languages without modifying the original package
Using Translations in Your Package
Now that we've set up our translation structure, let's see how to use these translations in different parts of your RMA package.
In Blade Templates
Update your views to use translations instead of hardcoded text. Let's update the admin index view we created earlier to use our simple translations:
Update: packages/Webkul/RMA/src/Resources/views/admin/return-requests/index.blade.php
<x-admin::layouts>
<x-slot:title>
@lang('rma::app.admin.return-requests.title')
</x-slot:title>
@lang('rma::app.admin.return-requests.content')
</x-admin::layouts>
Matching Our Basic View
This translation implementation perfectly matches our simple view from the Views section, demonstrating how to replace hardcoded strings with translation keys without adding unnecessary complexity.
In Controllers
Use translations in controller methods for basic responses:
<?php
namespace Webkul\RMA\Http\Controllers\Admin;
use Webkul\RMA\Http\Controllers\Controller;
use Webkul\RMA\Repositories\ReturnRequestRepository;
class ReturnRequestController extends Controller
{
public function __construct(
protected ReturnRequestRepository $returnRequestRepository
) {}
public function index()
{
// Test accessing a translation
$title = trans('rma::app.admin.return-requests.title');
// This is just for demonstration
dd($title);
return view('rma::admin.return-requests.index');
}
}
Simple Controller Integration
For now, our controller simply renders the view. As we add more functionality like create, edit, and delete operations, we'll expand the translation usage for success messages and validation feedback.
Translation Helper Functions
Laravel provides several helper functions for accessing translations:
// Using trans() function
$title = trans('rma::app.admin.return-requests.title');
// Using __() helper (shorter syntax)
$content = __('rma::app.admin.return-requests.content');
// Using @lang directive in Blade templates (already shown above)
@lang('rma::app.admin.return-requests.title')
Translation Best Practices
Consistent Naming: Use descriptive, hierarchical keys that reflect your content structure
Avoid Hardcoding: Replace hardcoded strings with translation keys for better maintainability
Fallback Values: Laravel automatically falls back to the key name if translation is missing
Simple Start: Begin with basic translations and expand as your package features grow
Testing Your Translations
Verify your translations are working correctly:
# Clear cache to ensure translations are loaded
php artisan optimize:clear
# Test different language settings
php artisan tinker
Now test translation functionality in the tinker console:
// Test in tinker
App::setLocale('en');
echo __('rma::app.admin.return-requests.title'); // Should output: "RMA Listing Title"
// Test fallback behavior
App::setLocale('fr');
echo __('rma::app.admin.return-requests.title'); // Should fallback to English since French not defined
Testing Tips
Route Testing: Visit your admin routes to see translations in action
Language Switching: Test fallback behavior when translations are missing
Cache Clearing: Always clear cache after adding new translation files
Your Next Step
With comprehensive localization implemented, your RMA package now supports multiple languages and provides a professional, international user experience. The translation system you've built provides a solid foundation for expanding to additional languages and regions.
You've successfully created:
- Organized translation files for different interface sections
- Service provider registration for automatic translation loading
- Practical examples of translation usage in views and controllers
- Testing strategies for verifying translation functionality
The localization system is now ready to support your package's growth and international expansion.
Continue to: DataGrid - Learn how to create data tables with sorting, filtering, and pagination for your admin interface
Internationalization Strategy
As your package grows, consider creating translation files for major e-commerce markets (Spanish, French, German, Arabic) and implementing locale-specific features like RTL support and currency formatting.