Wie strukturiere ich eine modulare App in Laravel 5?

72

Ich möchte meine Bewerbung in Module aufteilen. Zum Beispiel würde es ein "Kern" -Modul geben, das die grundlegenden Anmeldefunktionen, das App-Layout / die App-Formatierung (CSS usw.), die Benutzerverwaltung und ein Tagebuch enthält.

Später kann ich andere Module wie einen Kontaktmanager erstellen, die einfach zur Anwendung hinzugefügt oder daraus entfernt werden können.

Die Apps-Navigation enthält eine gewisse Logik, um festzustellen, welche Module vorhanden sind, und um die Links zu diesen ein- / auszublenden.

Wie kann ich dies in Bezug auf Verzeichnisstruktur, Namespaces und alles andere tun, was benötigt wird?


Ich betrachte Creolab / Laravel-Module, aber es heißt, dass es für Laravel 4 ist. Kann ich es mit 5 immer noch genauso verwenden?

In der Dokumentation wird angegeben, dass Modelle, Controller und Ansichten in jedem Modulverzeichnis platziert werden sollen. Wie funktioniert dies jedoch mit Routen? Idealerweise möchte ich, dass jedes Modul eine eigene Datei route.php hat. Wie wird das alles mit den Sachen im httpund im resourcesVerzeichnis funktionieren ?


Ich dachte an so etwas:

Modulidee

Aber ich habe keine Ahnung, wie ich es zum Laufen bringen würde.


Ich habe gerade das Tutorial hier ausprobiert:

http://creolab.hr/2013/05/modules-in-laravel-4/

Ohne zusätzliche Bibliotheken usw., nur reines Laravel 5.

Ich habe anscheinend eine Mauer mit einer Fehlermeldung getroffen:

FatalErrorException in ServiceProvider.php line 16:
Call to undefined method Illuminate\Config\Repository::package()

In Bezug auf Folgendes:

<?php namespace App\Modules;

abstract class ServiceProvider extends \Illuminate\Support\ServiceProvider
{

    public function boot()
    {
        if ($module = $this->getModule(func_get_args())) {
            $this->package('app/' . $module, $module, app_path() . '/modules/' . $module);
        }
    }

    public function register()
    {
        if ($module = $this->getModule(func_get_args())) {
            $this->app['config']->package('app/' . $module, app_path() . '/modules/' . $module . '/config');

// Add routes
            $routes = app_path() . '/modules/' . $module . '/routes.php';
            if (file_exists($routes)) require $routes;
        }
    }

    public function getModule($args)
    {
        $module = (isset($args[0]) and is_string($args[0])) ? $args[0] : null;

        return $module;
    }

}

Was verursacht das und wie kann ich es beheben?


Ich habe mich jetzt ein bisschen mehr damit beschäftigt. Ich habe meine Paket- / Modulrouten und -ansichten zum Laufen gebracht, was großartig ist:

abstract class ServiceProvider extends \Illuminate\Support\ServiceProvider
{

    public function boot()
    {
        if ($module = $this->getModule(func_get_args())) {
            include __DIR__.'/'.$module.'/routes.php';
        }
        $this->loadViewsFrom(__DIR__.'/'.$module.'/Views', 'core');
    }

    public function register()
    {
        if ($module = $this->getModule(func_get_args())) {

        }
    }

    public function getModule($args)
    {
        $module = (isset($args[0]) and is_string($args[0])) ? $args[0] : null;

        return $module;
    }

}

Ich habe noch eine letzte Frage: Wie würde ich alle meine Controller aus meinem Paket laden, ähnlich wie die loadViewsFrom()Methode funktioniert?

imperium2335
quelle
1
Die Frage ist zwar ziemlich interessant, aber sehr weit gefasst. Zitieren Sie den nahen Grund: Es gibt entweder zu viele mögliche Antworten, oder gute Antworten wären für dieses Format zu lang. Bitte fügen Sie Details hinzu, um den Antwortsatz einzugrenzen oder ein Problem zu isolieren, das in einigen Absätzen beantwortet werden kann. (Ich habe nicht abgelehnt, sondern für den Abschluss gestimmt)
lukasgeiter
1
@ukasgeiter Ich habe weitere Details hinzugefügt.
imperium2335
Herr Otwell betrachtet HMVC als ein Antimuster. Da Sie PSR-4 in Laravel 5 haben, können Sie Module mit Namespaces emulieren. Dann sollten Sie einen Modul-Controller an einen View Composer binden. laravel.com/docs/5.0/views#view-composers
user2094178
@ user2094178 Haben Sie ein Beispiel für einen modularen Ansatz mit einer solchen Methode? Ich habe meine Nüsse gegoogelt und nichts gefunden, das eine benutzerdefinierte modulare App beschreibt :(
imperium2335
Obwohl wir hier allgemeine Richtlinien haben, wonach Fragen nicht zu weit gefasst oder diskursiv sein sollten, denke ich, dass dies eine ausreichende Grauzone ist, um der Schließung (IMO) zu entgehen. Interessant zu sein / Roman hilft, denke ich. Wenn Sie in Zukunft selbst eine Lösung finden, senden Sie diese bitte als Antwort.
Halfer

Antworten:

35

Ich scheine alles herausgefunden zu haben.

Ich werde es hier posten, falls es anderen Anfängern hilft. Es ging nur darum, die Namespaces richtig zu machen.

In meiner composer.json habe ich:

...
"autoload": {
    "classmap": [
        "database",
        "app/Modules"
    ],
    "psr-4": {
        "App\\": "app/",
        "Modules\\": "Modules/"
    }
}

Mein Verzeichnis und meine Dateien endeten wie folgt:

Geben Sie hier die Bildbeschreibung ein

Ich habe mein Kernmodul router.php zum Laufen gebracht, indem ich meine Controller für dieses Modul in eine Gruppe eingeschlossen habe, die den Namespace angibt:

Route::group(array('namespace' => 'Modules\Core'), function() {
    Route::get('/test', ['uses' => 'TestController@index']);
});

Ich stelle mir vor, wenn ich meine Modelle für das Paket mache, wird es ein ähnlicher Fall sein, die Namespaces richtig zu machen.

Vielen Dank für all Ihre Hilfe und Geduld!

imperium2335
quelle
1
Vielen Dank für Ihre Frage und all die Bemühungen, die Antwort herauszufinden. Genau das brauche ich. Meiner Meinung nach funktioniert die Laravel 5-Struktur perfekt für kleine bis mittlere Anwendungen. Wenn es jedoch um große Projekte mit unterschiedlichen Modulen und Entwicklern geht, ist die Modularisierung einer L5-App unerlässlich @ imperium2335
DucCuong
1
Route :: group (Array ('Namespace' => 'Modules \ Admin'), function () {Route :: get ('/ admin / dashboard', 'AdminController @ index');}); Dies gibt immer den Fehler "Klassenmodule \ Admin \ AdminController existiert nicht" zurück. Ich habe die gleiche Ordnerstruktur und mein Problem ist bereits hier. stackoverflow.com/questions/33996528/routing-in-laravel-module/… Es wäre großartig, wenn jemand eine Lösung finden könnte.
Ich bin Nidhin
14

Lösung:

Schritt 1: Erstellen Sie den Ordner "Module" in "app /"


Schritt 2: Erstellen Sie im Ordner "Module" Ihr Modul (Modul 1 (vermutlich Admin-Modul)).

 Inside admin module : create the following folder 

 1. Controllers  (here will your controller files)
 2. Views  (here will your View files)
 3. Models  (here will your Model files)
 4. routes.php (here will your route code in this file)

Ebenso können Sie mehrere Module erstellen

Module2( suppose API )
-Controllers
-Views
-Models
-routes.php

Schritt 3: Erstellen Sie ModulesServiceProvider.php im Ordner "Modules /"


Schritt 4: Fügen Sie den folgenden Code in ModulesServiceProvider.php ein

<?php

namespace App\Modules;

/**
 * ServiceProvider
 *
 * The service provider for the modules. After being registered
 * it will make sure that each of the modules are properly loaded
 * i.e. with their routes, views etc.
 *
 * @author kundan Roy <query@programmerlab.com>
 * @package App\Modules
 */

use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class ModulesServiceProvider extends ServiceProvider {

    /**
     * Will make sure that the required modules have been fully loaded
     *
     * @return void routeModule
     */
    public function boot() {
        // For each of the registered modules, include their routes and Views
        $modules=config("module.modules");

        while (list(,$module)=each($modules)) {

            // Load the routes for each of the modules

            if (file_exists(DIR.'/'.$module.'/routes.php')) {

                include DIR.'/'.$module.'/routes.php';
            }

            if (is_dir(DIR.'/'.$module.'/Views')) {
                $this->loadViewsFrom(DIR.'/'.$module.'/Views',$module);
            }
        }
    }

    public function register() { }

}

Schritt 5: Fügen Sie die folgende Zeile in die Datei 'config / app.php' ein

App\Modules\ModulesServiceProvider::class,

Schritt 6: Erstellen Sie die Datei module.php im Ordner 'config'

Schritt 7: Fügen Sie den folgenden Code in module.php hinzu (Pfad => "config / module.php")

<?php

return [
    'modules'=>[
        'admin',
        'web',
        'api'
    ]
];

Hinweis: Sie können Ihren Modulnamen hinzufügen, je nachdem, was Sie erstellt haben. Hier gibt es Module.

Schritt 8: Führen Sie diesen Befehl aus

composer dump-autoload
Kundan Roy
quelle
8

Ein bisschen spät, aber wenn Sie Module in Ihren zukünftigen Projekten verwenden möchten, habe ich einen Modulgenerator geschrieben. Es generiert Module über php artisan make:module nameSie können auch einfach einige Module in den app/ModulesOrdner legen und sie sind einsatzbereit / arbeiten. Schau mal. Sparen Sie etwas Zeit;)

l5-modular

Gordon Freeman
quelle
1
Wäre es möglich, die Module über eine zentrale GUI zu aktivieren oder zu deaktivieren? Oder ist Ihre Struktur dafür nicht geeignet?
Aschwin Wesselius
2
Was meinst du mit "zentrale GUI"? Standardmäßig können Sie die Module in der entsprechenden app/config/modules.phpDatei deaktivieren . Wenn Sie Ihre Module dynamisch verwalten müssen, würde ich empfehlen, mein Git zu teilen und die ModuleServiceProvider.php(Zeile 19) so anzupassen, wie Sie es benötigen (FA. Holen Sie sich Ihre Modul-Ladeliste von der DB).
Gordon Freeman
2
Sie können die modules.enableKonfiguration auch zur Laufzeit festlegen . FA. config(['modules.enable' => ['customer', 'contract', 'reporting']]);
Gordon Freeman
@ GordonFreeman: Ich habe deine Arbeit überprüft. Bei der Installation haben Sie gesagt, dass Sie eine Zeile in composer.json hinzufügen sollen. aber du hast nicht gesagt, unter was und wo genau diese Zeile in composer.json hinzugefügt werden soll?
Saadk
2
@saadk Sie müssen die Zeile in den requireKnoten einfügen . genau wie jedes andere PHP-Paket, das Sie über Composer installiert haben. Werfen
Gordon Freeman
3

Sie können auch Pingpong-Labs verwenden

Dokumentationen hier .

Hier ist ein Beispiel.

Sie können den Prozess einfach installieren und überprüfen.

Hinweis: Ich mache keine Werbung. Ich habe gerade überprüft, ob cms auf Laravel mit Modulunterstützung erstellt wurde. Ich dachte, das könnte für Sie und andere hilfreich sein.

Jnanaranjan
quelle
2

Kundan roy: Ich mochte Ihre Lösung, aber ich habe Ihren Code von StackOverflow kopiert. Ich musste die Anführungszeichen und Semi-Anführungszeichen ändern, damit es funktioniert - ich denke, SOF ersetzt diese. Außerdem wurde Dir für base_path () geändert, um dem (neuen) Format von Laravel besser zu entsprechen.

namespace App\Modules;

/**
* ServiceProvider
*
* The service provider for the modules. After being registered
* it will make sure that each of the modules are properly loaded
* i.e. with their routes, views etc.
*
* @author kundan Roy <query@programmerlab.com>
* @package App\Modules
*/

use Illuminate\Support\Facades\Route;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;

class ModulesServiceProvider extends ServiceProvider
{

/**
* Will make sure that the required modules have been fully loaded
* @return void routeModule
*/
   public function boot()
{
    // For each of the registered modules, include their routes and Views
    $modules = config("module.modules");

    while (list(,$module) = each($modules)) {

        // Load the routes for each of the modules
        if(file_exists(base_path('app/Modules/'.$module.'/routes.php'))) {
            include base_path('app/Modules/'.$module.'/routes.php');
        }

        // Load the views                                           
        if(is_dir(base_path('app/Modules/'.$module.'/Views'))) {
            $this->loadViewsFrom(base_path('app/Modules/'.$module.'/Views'), $module);
        }
    }
}

public function register() {}

}
gabrielkolbe
quelle
0

pingpong/modulesist ein Laravel-Paket, das erstellt wurde, um Ihre große Laravel-App mithilfe von Modulen zu verwalten. Das Modul ist wie ein Laravel-Paket für eine einfache Struktur, es hat einige Ansichten, Controller oder Modelle.

Es funktioniert sowohl in Laravel 4 als auch in Laravel 5.

Um über Composer zu installieren, fügen Sie einfach Folgendes in Ihre composer.jsonDatei ein:

{
    "require": {
        "pingpong/modules": "~2.1"
    }
}

Führen Sie dann aus composer install, um das Paket abzurufen.

Um ein neues Modul zu erstellen, können Sie einfach Folgendes ausführen:

php artisan module:make <module-name>

- Erforderlich. Der Name des Moduls wird erstellt. Erstellen Sie ein neues Modul

php artisan module:make Blog

Erstellen Sie mehrere Module

php artisan module:make Blog User Auth

Weitere Informationen finden Sie unter: https://github.com/pingpong-labs/modules

Sagar Naliyapara
quelle