Base

Introduction

Base is a package for Laravel delivering essential features for getting up and running. It can be used for any kind of project though it has been mainly developed as for a backend or admin site. It will bootstrap many features such as Vue and Vuex out of the box for you.

Installing

To install Base first install it from Packagist:

composer require emilmoe/base

And then install Vuex

npm install --save-dev vuex

As Vuex can only be set to load from where Vue is initialized you must modify app.js accordingly:

store = window.Vuex;

const app = new Vue({
    el: '#app',
    store
});

Base supports my Autoloader for assets however if you haven’t installed that you should also require the Base JavaScript to your project:

require('../../vendors/emilmoe/base/src/resources/js');

If you intend to use the menu with permissions you must publish the config:

php artisan vendor:publish --provider="EmilMoe\Base\BaseServiceProvider"

Templates

The templates help you bootstrap your project, you can use the purposed templates or the snippets or even the base, you choose.

Admin

Extended by using EmilMoe\Base::templates.admin this templates purpose is to create a admin interface.

Content is yielded from page section:

@extends('EmilMoe\Base::templates.admin')

@section('page')
  // Your content here
@endsection

Breadcrumb

Breadcrumbs for the admin template are created in the controller by attaching the breadcrumb variable:

->with('breadcrumb', [
  url('/') => 'Home',
  'Users',
])

Each entry in the named array is the next step in the breadcrumb. Each entry is formed as the path and then the label, leaving the first part out will render an entry with no link, ie. the current page.

Making a menu

Currently the menu is only supporting 1 language, but that will be changed in the future.

To use the menu generator you must run the migration. You should also have published the configs.

php artisan migrate

Config

If you wish your menu entries to be depending on a users permissions, you should modify these 2 properties in the configuration found at config/base.php

/*
|--------------------------------------------------------------------------
| Global admins
|--------------------------------------------------------------------------
|
| Define a boolean attribute on \Auth::user() that identifies a
| user as an admin.
|
| For instance `is_admin` an admin user will be true if
| \Auth::user()->is_admin === true.
|
*/

'admin_attribute' => null,

/*
|--------------------------------------------------------------------------
| Get permission key
|--------------------------------------------------------------------------
|
| A closure for returning all users permission keys.
|
| For instance:
|    permission_keys_callback' => function($user) {
|       return $user->permissions();
|    },
|
*/

'permission_keys_callback' => null,

Adding entries to the menu

You should listen for base.menu.update to register your menu entries. The parameters goes as:

PropertyTypeDefaultDescription
IDBig IntegerRandom unique ID
LabelStringText display for entry
IconStringHTML containing icon
CallbackArrayA callback array with either route or url

Route: ['route', ['users.index']]
URL: ['url', ['/users']]
Active routesArrayRoutes that will render the entry active
Permission keysArrayPermission keys that can see the menu entry
PriorityIntegerNULLPriority for the menu, default is null and will be displayed in order of added
Event::listen('base.menu.update', function($menu) {
  $menu::registerItem(
    1560460291,
    'Users',
    '<i class="material-icons">person</i>',
    ['route', ['users.index']],
    ['users.index', 'users.show'],
    ['can_see_users'],
    null
  );
});

Generic template

The generic template doesn’t support for breadcrumb or menu generation, but will help you bootstrap the header and refering to scripts and styles.

Extend the generic template with EmilMoe\Base::templates.generic:

@extends('EmilMoe\Base::templates.generic')

Like the admin template, page yields the content of your page

@extends('EmilMoe\Base::templates.generic')

@section('page')
  // Your content here
@endsection

Cleanup

The cleanup command will trigger all menu events and update your menu, but it will also trigger the event base.cleanup in case you want to do other cleanups in your application when running it. Use it for some kind of maintenance command or leave it for the menu solely.

Extended Vue

A few things have been added to improve the experience when working with Vue in Laravel. The goal is not to make any dark magic but rather to eliminate redundant work from project to project.

Translations for Vue

Writing translations can be boresome, but writing the twice is just tedious. Therefor Base comes with a feature for exporting Laravel translations to Vue. Keep in mind that Vue is JavaScript and therefor in the browser, so all translations exported will be made available, you might not want to expose all of them.

In order for Base to expose your translations to Vue you must listen for the Laravel event base.translation.update and add your path to your translations to it’s path variable. First parameter is the namespace, for instance your package name and second is the root path:

Event::listen('base.translation.update', function($paths) {
  $paths->add('user', __DIR__ .'/resources');
});

To use the translations in Vue, it’s access the same way as in Laravel:

__('user::firstname')

Behind the scene Base will publish all translations to /js/lang.js choosing the language set in your application.

Easy binding for Vuex

Vuex is set up with Base, but sometimes you might just need to share a simple variable, let’s say userid. Instead of having to define such in a Vuex configuration you can benefit from the easy Vuex binding using bind().

Furthermore the bind() can be used to both set and get depending on the second parameter. You can use unbind() to remove any bindings and hasBind() to check if a binding exists – or the more sugary syntax isBound() for phonetic reasons.

For instance you want to share userid but easily between components, as bind() is a global mixin this can be done as simple as:

this.bind('userid', this.user.id);

The other components can then reach userid by:

return this.bind('userid');

Again if you want to remove the binding, this can be done with unbind():

this.unbind('userid');

Lastly to make an example of hasBind(), userid can be be set only if it’s not already defined:

if (! this.hasBind('userid')) {
  this.bind('userid', this.user.id);
}

return this.bind('userid');

Axios cache

Base will automatically cache GET requests made with Axios to help you avoid making duplicate requests. Cached requests will be deleted after 5 seconds. This allows you to call the same GET endpoint twice, ie., while loading a page from different components, but the second time and on the cached response will be returned increasing the load time of your pages.

JavaScript constants

Base will also expose a few JavaScript constants in order to help you bringing some logic to your frontend. The constants are exposed if you use any of the built in templates. All constants are attached to window.Laravel:

window.Laravel: {
  baseUrl: "http://localhost",
  debug: true,
  locale: "en",
  user: {
    admin: false
    id: 2,
    permissions: []
  }
}

Leave a Reply

Your email address will not be published. Required fields are marked *