ARCANEDEV / Localization

:globe_with_meridians: Localization package for Laravel
MIT License
186 stars 37 forks source link

Problem calling translation form other source different to resources/lang (Modular app) #54

Closed gitllermopalafox closed 8 years ago

gitllermopalafox commented 8 years ago

Hi!,

I'm developing a modular Laravel app, in each module I have controllers, views, translations and routes. Your package works perfect in each isolated routes.php file. The problem is when I try to translate a route, for example:

<?php

// app/Modules/Module1/routes.php

Route::group(['module' => 'Module1', 'namespace' => 'App\Modules\Module1\Controllers'], function() {
    Route::localizedGroup(function () {
        Route::transGet('Module1::routes.destinations, 'Module1Controller@index');
    });
});

At this point seems to be the 'transGet' function can't localize the translation.

In my views I implement the 'trans' helper this way, without any problem...

{{ trans('Module1::home.title') }}

Here I can see how your package implements the 'trans' method:

https://github.com/ARCANEDEV/Localization/blob/master/src/Utilities/RouteTranslator.php#L246

Can you help me with some clues?

This is my service provider:

// app/Providers/ModuleServiceProvider.php

class ModuleServiceProvider extends ServiceProvider {

    protected $files;

    public function boot() {

        if(is_dir(app_path().'/Modules/')) {
            $modules = config("modules.enable") ?: array_map('class_basename', $this->files->directories(app_path().'/Modules/'));
            foreach($modules as $module)  {
                // Allow routes to be cached
                if (!$this->app->routesAreCached()) {
                    $routes = app_path() . '/Modules/' . $module . '/routes.php';
                    if($this->files->exists($routes)) include $routes;
                }
                $views  = app_path().'/Modules/'.$module.'/Views';
                $trans  = app_path().'/Modules/'.$module.'/Translations';

                if($this->files->isDirectory($views)) $this->loadViewsFrom($views, $module);
                if($this->files->isDirectory($trans)) $this->loadTranslationsFrom($trans, $module);
            }
        }
    }

    public function register() {
        $this->files = new Filesystem;
    }
}

This is my folder structure:

app
...
|-- Modules
|   |-- Module1
|   |   |-- Controllers
|   |   |   `-- Module1Controller.php
|   |   |-- Translations
|   |   |   |-- en
|   |   |   |   `-- routes.php
|   |   |   `-- es
|   |   |       `-- routes.php
|   |   |-- Views
|   |   |   |-- index.blade.php
|   |   `-- routes.php
|   `-- Module2
|       |-- Controllers
|       |   `-- Module2Controller.php
|       |-- Translations
|       |   |-- en
|       |   |   `-- routes.php
|       |   `-- es
|       |       `-- routes.php
|       |-- Views
|       |   |-- index.blade.php
|       `-- routes.php
...

Thanks in advance.

arcanedev-maroc commented 8 years ago

Can you show me the providers list in you config/app.php ?

UPDATE

Can you try this ModuleServiceProvider :

// app/Providers/ModuleServiceProvider.php

class ModuleServiceProvider extends ServiceProvider {

    protected $files;

    public function boot()
    {
        if (is_dir(app_path('Modules'))) {
            $modules = config("modules.enable") ?: array_map(
                'class_basename', $this->files->directories(app_path().'/Modules/')
            );

            foreach($modules as $module)  {
                $views  = app_path("Modules/$module/Views");
                $trans  = app_path("Modules/$module/Translations");

                if ($this->files->isDirectory($views)) 
                    $this->loadViewsFrom($views, $module);
                if ($this->files->isDirectory($trans)) 
                    $this->loadTranslationsFrom($trans, $module);

                // Allow routes to be cached
                if ( ! $this->app->routesAreCached()) {
                    if ($this->files->exists($routes = app_path("Modules/$module/routes.php"))) 
                        require $routes;
                }
            }
        }
    }

    public function register()
    {
        $this->files = new Filesystem;
    }
}
gitllermopalafox commented 8 years ago

Thanks @arcanedev-maroc

I just tested and It works like a charm

Reading your code, I see the route caching was the problem. I forgot all about that code block. 😞

Thanks a lot.

arcanedev-maroc commented 8 years ago

Hi @gitllermopalafox, glad that helps you.

BTW, i think the cleanest way to create a modular app is by using service providers (like laravel packages).

Something like this:

app
...
|-- Modules
|   |-- Module1
|   |   |-- Controllers
|   |   |-- Translations
|   |   |-- Views
|       `-- Module1ServiceProvider.php
|   |   `-- routes.php
|   `-- Module2
|       |-- Controllers
|       |-- Translations
|       |-- Views
|       `-- Module2ServiceProvider.php
|       `-- routes.php
...

And in your base ModuleServiceProvider:

// app/Providers/ModuleServiceProvider.php

class ModuleServiceProvider extends ServiceProvider {

    protected $files;

    public function register()
    {
        $this->files = new Filesystem;

        if (is_dir(app_path('Modules'))) {
            $modules = config("modules.enable") ?: array_map(
                'class_basename', $this->files->directories(app_path('Modules'))
            );

            foreach($modules as $module)  {
                $this->app->register("App\\Modules\\{$module}\\{$module}ServiceProvider");
            }
        }
    }
}
gitllermopalafox commented 8 years ago

@arcanedev-maroc thanks for the advice. You're right, a service provider per module makes each module more flexible and portable.

That's a good idea for a laravel package.

A small fix on how to register the service providers of the modules.

...
foreach($modules as $module)  {
    $this->app->register("App\\Modules\\{$module}\\{$module}ServiceProvider");
}
...

Thanks for your great help! 😄