Laravel 4: Object Oriented Form & HTML Macros

In an earlier post I talked about how to utilize form and HTML macros to DRY up your views. The one thing I don’t like about these form macros is that they are global code, and it doesn’t really feel like they have a proper home. Sure, we can put that code in our routes.php , or global.php , but it definitely takes away from the object-oriented nature of the framework. Furthermore, any common functionality between macros can only be refactored into a global function rather than a class method.

In this post I’ll discuss how we can refactor that code into classes and load it with a service provider class.

Preparation

In preparation you’ll need a place to store these files. You can choose anywhere really, but a common convention in the Laravel community is to create a folder with the name of your application in the app directory.

So, if your app was called Zizzle (don’t ask) you’d create the folder app/Zizzle . You can then put the classes we’ll create in an Extensions folder, so  app/Zizzle/Extensions , and since the Laravel core namespaces both form and HTML macros under a common namespace, we’ll create another folder within called Html resulting in app/Zizzle/Extensions/Html .

Refactoring Your Form Macros

Let’s create a new home for our form macros under the directory we just created. To do so create a new file at  app/Zizzle/Extensions/Html/FormBuilder.php  and insert the following code:

As you can see it’s very simple. We are just extending the core Laravel FormBuilder class and adding our own macro methods to it. So, rather than adding macros like this:

we simply add a new method to our FormBuilder class with the name we want to give the macro.

Refactoring Your HTML Macros

The process of refactoring HTML macros is much the same. Create a new file located at app/Zizzle/Extensions/Html/HtmlBuilder.php  and add the following code:

Here we are simply extending the core Laravel HtmlBuilder class, and at this point adding HTML macros is the same process as adding form macros.

Creating a Service Provider

Now that we have extended the core Laravel HTML and form macro classes to add our own macros in a clean, object-oriented way, we need to be able to tell Laravel how to access our code. We do this by creating a service provider in order to bind our classes to the Laravel IOC container, which essentially tells Laravel to load instances of our HTML and form macro classes instead of the core Laravel classes. The code is fairly straightforward if you’ve read through the Laravel documentation. Create a new file located at  app/Zizzle/Extensions/Html/HtmlServiceProvider.php and add the following code:

Basically we override the two methods from the core Laravel HtmlServiceProvider,  registerHtmlBuilder and  registerFormBuilder , and within return instances of our newly created classes.

Bootstrap the Service Provider

With the service provider created we need to let Laravel know how to load it. Luckily that’s easy too! Open up  app/config/app.php and add the following line to the  providers array:

And that’s it! With that in place you can officially move your global macro code into classes that extend from the Laravel core and bootstrap that code within the Laravel framework.

If you have any questions please feel free to ask!

Laravel 4: Using whereHas() with HasManyThrough Relationships

I’ve discovered an issue with Eloquent in which using the whereHas() method with a HasManyThrough relationship returns the wrong results.

For instance, if I have the following model structure:

the following code will yield unexpected results:

I’ve sent a pull request to fix the issue but it needs to be discussed, so for now you can do use nested whereHas() calls like so:

 

Laravel 4: DRY Up Your Views With Form & HTML Macros

This is just a quick post to give a couple of examples where form/HTML macros are useful, and to advocate their usage in general.

Reusable Components

In my larger projects I like to create form and HTML macros to DRY up repetitive view-related tasks and also make the views more clean and concise. Here are a couple of examples:

Here we have created a couple of reusable components: a Select Province drop-down and a Select Country drop-down. The great thing about this is that the logic for populating the dropdowns is contained to one method (including caching!), and usage throughout the app is extremely simple:

Wrapping jQuery

I also like to use form/HTML macros to wrap elements that have added jQuery functionality. For example, I may have a city field using typeahead.js to automatically suggest cities populated from the database as the user starts typing. The form macro literally acts as a wrapper around a text field and applies the typeahead class to it, and then jQuery does this rest. For example:

I prefer this because the logic is contained to one method, and if we ever need to modify the markup for all typeahead search fields in the future we can do this from a centralized location.

These are all form macro examples, but the concepts are the same for HTML macros!

Stay tuned for an upcoming post where I’ll show how to move this global code into object oriented classes loaded by the Laravel core via a service provider.

Laravel Form Macro to Easily Wrap Form Elements

This trick is handy for wrapping all of your form elements with the same HTML/classes, which is especially useful for handling error states when using frameworks like Bootstrap or Foundation.

Laravel Extended Validator

I released my first Laravel 4 package today, which is a couple of classes that build on top of Laravel’s Validator library.

Take a look at this snippet, then view the project on Github to see how it can assist your validation.

The main reasons I created this package are:

  1. To ease the creation of validation services – we all know validaton should be moved out of the controller
  2. Provide an easy way to provide context for validations – such as providing a modified set of validation rules for edit vs. create
  3. Provide an easy way to group validations – that is, calling one ‘passes()’ method to validate multiple models

It is documented on Github and I’ll write a more in depth blog post about it in the near future.

For now, visit the project on Github!

Laravel 4: Elegant Growl-Like Notifications

Here is an extremely simple and elegant way to send Growl-like notifications to your users. It requires the Notifications package for Laravel 4, as well as the Alertify jQuery plugin.

Notifications in Laravel

With the Notification package installed, it’s time to get to work sending notifications to our users. The Notification package makes this dead simple. Here is a couple examples:

Creating notifications in your controller requires one line of code:

Displaying Errors with Alertify

Displaying our alerts is also dead simple. Create a partial view and include it in your master layout, or include the following code directly in your layout:

Wrapup

This is a simplified version, but it will give you some great functionality to build off of. For instance, the Notification package offers a warning notification, which I’ve left out as warning notifications are not implemented in the Alertify plugin. The notification package also allows you to create ‘instant notifications’ which are shown in the same request (i.e. don’t require a redirect), but using these requires using a different method, such as:

I hope you’ve enjoyed this post and if you have a creative way of sending notifications please share it in the comments!

Laravel 4: Setting Up and Utilizing Environments and Environment Configuration

Have you ever developed your application locally, then taken it live on your production server and had to manually change your app configuration (say, your database credentials) to match the production server? If you have, then continue reading and learn how configuring environments in Laravel can save you from this headache.

Environments

Software projects are typically deployed in various environments. You likely develop your application locally in a development environment. You then have your live server where your site resides, known as the production environment. Many applications will have a staging environment, essentially a duplicate of your production environment, where apps are deployed and tested before being pushed to production. Larger applications may have other environments in between.

Each of these environments may require different configuration, and luckily we can easily handle that in Laravel.

Default Environment and Configuration

The default environment in Laravel is production; in other words, without making any of the aforementioned changes your app will be considered in ‘production’. Any files within the root of the app/config  folder will be considered the configuration for the production environment; that includes app/config/cache.php , app/config/app.php , app/config/database.php  and others.

Setting Environments

We can set different environments in Laravel and subsequently use different configuration. Open up the bootstrap/start.php  file in your Laravel application. Here you will see the following block of code:

This is where we define our environments within the application. Each key in this array is the name of an environment and the corresponding value is an array of URLs that will match this environment. Below is an example of an environment configuration I might use in an application:

In the example above, when I view my application on my localhost the environment will be set to local. When I deploy my application to my staging server set at staging.example.com, my application environment will be staging. These can be named whatever you like. For instance, I could use the following:

to name my development environment dev rather than local.

Loading Config Based on Environment

The real power of environments comes from being able to load different configuration based on the environment, and Laravel makes this dead simple.

For instance, say you have different database credentials for your local development environment. All you need to do is copy the app/config/database.php  config file to app/config/local/database.php . If your staging environment has a different set of database credentials from your local or production environments it can have it’s own configuration stored in app/config/staging/database.php .

The idea is that you use the environment key you defined in  bootstrap/start.php as the folder name, and then copy any configuration files you need to override into this folder and change the values accordingly.

In fact, you don’t even need to copy the entire configuration file, you can copy only the array keys within the configuration file that you need to override and these will be merged with the default values in the production configuration files!

Environments and Artisan

By default Artisan commands are run with the default production configuration; however, if you are developing locally and need to migrate a database this doesn’t help. What you can do is pass a flag with the Artisan command that will utilize the configuration for the environment you specify. For example, if you wanted to migrate your database in your production environment it might look like this:

If you wanted to seed your database in your staging environment if might look like:

Conclusion

Environments in Laravel are extremely powerful and allow you to configure your application for various stages of development and deployment. I hope you found this article helpful and if you have any comments, questions, or additions please include them in the comments below!

Laravel 4: Methods for Staying Organized

Laravel 4 already has a place for pretty much everything, so it feels organized out of the box. However, the larger your application is the more unorganized it starts to feel. Here are a few small things I do to help keep things organized.

Namespace Controllers and Models

This one is pretty simple, but I namespace all of my controllers and models. For instance, UserController.php might look like this:

app/controllers/UserController.php

My models generally are namespaced like so:

app/models/User.php

Map Table Prefixes to Namespaces

Let’s assume the following: we have a business and the business has many executives. This is a one-to-many relationship; the business can have many executives and each executive belongs to the business.

The tables businesses  and  business_executives seems reasonable for this setup. Since the executives belong to the business we prefix the executives table with business_. To help organize the related models I like to utilize namespacing. The related models would look like this:

app/models/Business.php

app/models/business/Executive.php

Utilize Repositories

Jeffrey Way wrote an excellent article that covers the use of repositories within Laravel (scroll down to the Repositories heading), so I’ll refer you to that article if you’re not sure what repositories are.

However, in short repositories are an additional level of abstraction. They sit between your controllers and your models and act as a data-access layer, allowing your controllers to query data without accessing your models directly.

This is especially useful if you don’t want to muddy up your Eloquent models (keep them ‘pure’) or if you have specific functionality that requires several models; for instance, if your application is creating an event with several occurrences and must insert both Event and EventOccurrence models then you can perform both of these actions within a single method in the repository. An example might look like this:

app/repositories/EventRepository.php

The repository is also a great place to consolidate validations. In the previous example, validations for both models can be performed within the save() method, and validation rules for saving an event can be stored together in the repository rather than separately within the models (or together in the controller) – this helps keep your models clean and your controllers slim.

If you have any of your own methods for organizing projects please post them in the comments below!

Laravel 4: Generating Unique Slugs Elegantly

Using slugs in URLs is a great alternative to strictly using integers (ids), as it improves SEO by allowing you to get more context in the URL. However, generating them can be a pain. Here is a super simple method for generating slugs that you can adapt to your own needs.

Easy! Here I am generating slugs for events; you’ll need to modify the code for your own purposes.

Explanation

We accept the title we want to slugify as a parameter and use Laravel’s string helper to convert it to a slug. From there we query our event model using the whereRaw() method and perform a regex expression to grab all the events with slugs matching the title, or matching the title with a number appended to the end. We count the results, and if there are matching slugs we append that number to the slug to make it unique.

A more general version of the method might look like this:

Enjoy! If you have any Laravel tricks of your own please post them in the comments below.

Note: This works with MySQL but likely won’t work with other RDBMSs; the concept should work but the regular expression implementation is likely different.

Laravel 4: Easily Cache Eloquent Collections

I found an article by Mark van Eijk that outlines how to easily cache Eloquent results by using the following syntax:

I wanted to point out that in the event you want to cache all articles, the following syntax doesn’t work

What you need to do instead is the following:

You can verify the query is not run on subsequent requests by dd’ing the queries that were run during the request:

Hope this helps someone! If you have any Laravel tricks of your own post them in the comments below.