RantFever 4

I pontificate but not in the pejorative sense of the word.

Laravel 4 Packages

Posted 11 June 2013
Written by Abinadi Ayerdis
Category Laravel

Over the weekend, I created my first package using Laravel 4.

No more bundles

Laravel 4 just came out at the end of May 2013. When it did, L3 users noticed quickly that bundles were long gone. Replacing bundles are packages. Are packages better? I have idea. I do know that they can be distributed via packagist and composer. Maybe that is why they made the switch. But really, it is all the same to me since I never really got much into L3.

Why build a package at all?

Good question. Packages are a way to add functionality to an application. But really, they are more than that. A package can have its own config files, models, views, controllers, routes, et cetera. So really, a package can be an app all by itself. HMVC, anyone?

I have a few web apps that I wrote in Codeigniter that I wanted to redo in a more cohesive way. So I created a L4 web app that I intelligently named Portal. Portal is a parent app to the other apps that I want to recode. The apps are distinct enough that they need their own configs and controllers but are related enough that it sort of makes sense to put them under the same umbrella.

eBook Trove

The first app I tackled was what I like to call eBook Trove. It is a front end for the SQLite database that Calibre creates for managing one's ebook collection. Have I mentioned that I love Calibre? Because I do. It is the standard for ebook collection software.

When I originally made the CodeIgniter app, I modified the database a bit. Mostly, I added some triggers so that tags that are not assigned to any book get deleted. That, and I strengthened some relationships. It is hard to remember all I did, really, since it has been a while. Luckily, Calibre still runs fine. 

Creating the package

Laravel 4's artisan command is helpful for building packages. It will produce a bunch of boiler plate for you in a workbench folder. All you do is go to the root of your L4 install and type:

php artisan workbench vendor/package --resources

Where vender/package is the name for your vender and package. Thus for my ebooks package, I put:

php artisan workbench abinadi/ebooks --resources

The next thing I know, I have a bunch of boilerplate made up and ready to be built on. The Laravel documentation goes into some detail about how packages are structured. A package can contain most anything your base app can, including controllers, views, models, and config files. It has its own composer.json file, so I added Twitter Bootstrap (it comes with all the LESS files). But the first file to worry about is the service provider file. It outlines how your package is registered and what it needs to do when laravel boots. And L4 knows to look for this file because you have to add it to the providers array in the app.php file. That done, I added an include for a routes file to the boot method in my service provider file. That way my package could have its own routing.

public function boot() {
    $this->package('vendor/package');
    include __DIR__.'/../../routes.php';
}

I also added an array merge to the database.connections array in the same method so that my database connection would be added:

if( \Request::is('ebooks*') ) {
    $this->app['config']['database.connections'] = array_merge($this->app['config']['database.connections'],\Config::get('ebooks::database.connections'));
}

Note the if statement. Because all the packages you have run their service provider files, you could end up merging a bunch of database connections that you don't mean to. This keeps it limited. I'm not sure if this is the best way to do this, but it worked for me. 

Once the service provider file was in place, I could add a routes file and start building my controllers, models, and views. The only other tricky business is the assets. You can keep the assets in the same package, but they are not available publicly. Artisan has a command that will copy them to the public folder:

php artisan asset:publish --bench="vendor/package"

The --bench flag is necessary if the package is within the workbench.

Comments

There are no comments

Posting comments after three months has been disabled.