Laravel wrapper of LightnCandy for using Handlebars (and Mustache) templates

Overview

Laravel Handlebars

Latest Stable Version Total Downloads Latest Unstable Version License

This package allows you to use Handlebars (and Mustache) templates with Laravel. You can integrate Handlebars templates into Blade templates and you can even use the Blade language directives @lang and @choice in Handlebars templates.

It's the perfect choice, if you want to use the same templates in different languages (i. e. PHP and JavaScript) and/or server- and clientside. The compiling and rendering is veeery fast, because this package wraps the super fast template engine LightnCandy.

Installation

Laravel Handlebars is distributed as a composer package. So you first have to add the package to your composer.json file:

  • For Laravel 6.x, 7.x, 8.x:

    "proai/laravel-handlebars": "^1.11"
  • For Laravel 5.5+:

    "proai/laravel-handlebars": "~1.8"
  • For Laravel 5.1 to 5.4:

    "proai/laravel-handlebars": "~1.5.0"

Then you have to run composer update to install the package. Once this is completed, you have to add the service provider to the providers array in config/app.php:

/*
 * Package Service Providers...
 */
ProAI\Handlebars\HandlebarsServiceProvider::class,

You can publish the package configuration with the following command:

php artisan vendor:publish --tag=laravel-handlebars

Usage

Configuration

Most of the options in config/handlebars.php are also used by LightnCandy. So please have a look at the LightnCandy readme for more information.

Only the basedir option can't be set in this config file. Instead the package uses the paths option in config/view.php to define base directories and also the compiled option in the same file to define the directory for the compiled templates (i. e. the cache directory).

In addition to the LightnCandy options there are the options language_helpers, optional_raw_output and translate_raw_output. These options are described below.

Basics

You can use Handlebars templates the same way you use Blade templates. You can return them with View::make('articles', ['name' => 'Taylor']) or include them with the Blade @include directive, i. e. @include('articles', ['name' => 'Taylor']).

By default all views which have a .hbs or .handlebars file extension are automatically detected as Handlebars templates. You can add more file extensions that should be treated as Handlebars templates in the fileext array in config/handlebars.php.

Language Helpers

If you wish, you can use the Blade language directives @lang and @choice in Handlebars templates, too. You have to set $language_helpers = true in order to use them. Here is an example:

// Blade syntax:
@lang('message', ['firstname' => 'John', 'lastname' => $lastname])
@choice('comment_count', 2, ['item' => 'Article'])
// Handlebars syntax:
{{lang 'message' firstname='John' lastname=lastname }}
{{choice 'comment_count' 2 item='Article' }}

Raw Output

This feature is currently broken. If you want to use it, use v1.1 or below or help to fix it!

If you want to output the raw code of a template (maybe because you want to use the unrendered template clientside), you can set $optional_raw_output = true in the configuration. Then you can pass a variable $raw = true to the template or more comfortable you can use the @raw Blade directive.

// Passing the $raw variable to the view:
View::make('articles', ['raw' => true])
@include('articles', ['raw' => true])
// Blade @raw directive:
@raw('articles')

If you want to output a raw template with compiled and rendered language variables, you can set $translate_raw_output = true.

Partials

This package automatically adds the directory of the current template to the basedir of LightnCandy. By that it is possible to easily include other Handlebars templates in the same directory. Just write {{> comment}} to include comment.hbs from the same directory.

Example Template

{{#each array_variable }}
	{{#if this }}
		{{ output_some_variable }} {{> include_templatename }}
	{{else}}
		{{lang 'language_variable' }}
	{{/if}}
{{/each}}

For more information about the Handlebars syntax see the Handlebars documentation. It does not matter that the examples are for JavaScript, because Handlebars templates are the same for JavaScript and PHP.

Using it with Webpack

If you want to use this package client side with webpack, have a look at this article:

Sharing templates between PHP and JavaScript in Laravel

Support

Bugs and feature requests are tracked on GitHub.

License

This package is released under the MIT License.

Comments
  • How to add a custom helper?

    How to add a custom helper?

    Hi,

    I'm quite lost on how to use the package with Laravel 5. I want to use the templates both in server and in client.

    • I've created a helper called hotness in /resources/views/helpers/hotness.js.
    • I've added 'helpers' => ['hotness'], to /config/handlebars.php.
    • Then I use {{hotness job.company.hotness }} on my .hbs template

    I have the following error:

    ErrorException in lightncandy.php line 792:
    Can not find custom helper function defination hotness() ! (View: /home/.../resources/views/job/list.blade.php)
    

    What's wrong? Also, could you share a working example?

    Thanks a lot!!

    opened by fesja 7
  • Prevent caching if modified date is out

    Prevent caching if modified date is out

    Hi there, I seem to be getting a lot of caching problems with my content. It is easy to fix but gets quite mundane to delete multiple files everytime you make a change to a template.

    May I suggest implementing something where the modified dates of both the template and the cached file are compared and if the modified date of the template is newer than the cached file then the cache gets regenerated.

    I have done this in laravel 5 before and would be willing to contribute code if needed.

    opened by Truemedia 6
  • Transition from LightnCandy v0.89 to v0.94

    Transition from LightnCandy v0.89 to v0.94

    Fixed breaking changes introduced by https://github.com/zordius/lightncandy/releases/tag/v0.90 and https://github.com/zordius/lightncandy/releases/tag/v0.91.

    opened by Lorti 4
  • Support laravel 5.5.

    Support laravel 5.5.

    Taylor made yet another breaking change in a minor version...

    Ref. https://github.com/laravel/framework/pull/20464

    What is the best way to tackle this down?

    opened by greut 3
  • View not found (with .hbs extension)

    View not found (with .hbs extension)

    Hi again, sorry just pointing out another small thing.

    When I was trying to set this up and publish the config I originally got a view not found error.

    Looking at the config I realize you have this line 'fileext' => [ '.handlebars', '.hb', ],

    Adding .hbs to this works but is the "hb" a typo or is that another file extension people use for handlebars? I know hbs and handlebars are used quite commonly as the extension.

    opened by Truemedia 3
  • publish config

    publish config

    You need to publish the config using

    php artisan vendor:publish --tag=config

    I do not see that in the readme, but its pretty important as you discuss configuration...

    Esp since you do not get support for .mustache file without modifying that file... it would also be nice to support those out-of-the-gate.

    opened by ftrotter 2
  • Support for LightnCandy v0.94

    Support for LightnCandy v0.94

    Hi Markus,

    do you plan on updating this package to use the latest LightnCandy? I have naively updated the version number in a fork and got some error messages. It seems that there have been some API changes since v0.89?

    If you don't have the time I will look further into it and maybe open up a pull request.

    Grüße aus Linz, Manuel

    opened by Lorti 2
  • Last update broke using partials from template dir

    Last update broke using partials from template dir

    hi there,

    When updated lightncandy to v0.89, it only looks for partials in resources/views

    I'm using pingpong modules

    downgrading solved the issue, but latest laravel handlebars, requires lightncandy v0.89

    help wanted 
    opened by vascopitaf 2
  • Added form token helper

    Added form token helper

    While trying to fix the issue with cached partials I had another issue.

    Not so much a problem with this package, but something additional I could use to simplify adding a csrf token to form which is needed by default for laravel 5 when working with forms.

    A lot of people like to use form helpers in blade like Form::open and Form::token but been able to also utilize them with handlebars as {{{form_token }}} I think is very handy and clean to write.

    I added the code for this and also abstracted it in the compiler so it easier to add commonly used helpers to this package.

    opened by Truemedia 2
  • Your requirements could not be resolved to an installable set of packages

    Your requirements could not be resolved to an installable set of packages

    Hi there, I was trying to setup your repo when I got this error on running composer update.

    zordius/lightncandy dev-master -> no matching package found

    I believe altering the composer.json include line to "zordius/lightncandy": "^0.20.0"

    will fix this

    opened by Truemedia 2
  • laravel 6 support added

    laravel 6 support added

    Hi I needed this package for laravel 6 so I added the support for it. the only thing is that the expected handlebars.html was different with the actual rendered html in white spaces and new lines.

    opened by saeidraei 1
  • Bad indentation in case of nested partials

    Bad indentation in case of nested partials

    I have 3 handlebars template files inside views/templates directory: test.hbs:

    <div>
      <p>Hello</p>
      {{> testPartial}}
    </div>
    

    testPartial.hbs:

    <div>
      <p>This is inside a partial</p>
        {{> testPartial2}}
    </div>
    

    testPartial2.hbs:

    <div>
      <p>This is inside partial 2</p>
    </div>
    

    The bug

    When I execute return view('templates.test');, I get:

    <div>
      <p>Hello</p>
      <div>
        <p>This is inside a partial</p>
          <div>
          <p>This is inside partial 2</p>
        </div>
    </div>
    </div>
    

    But I should get:

    <div>
      <p>Hello</p>
      <div>
        <p>This is inside a partial</p>
          <div>
            <p>This is inside partial 2</p>
          </div>
      </div>
    </div>
    

    In case of handlebars with javascript, the indentation works as expected.

    The handlebars.php config file:

    <?php
    
    use ProAI\Handlebars\Support\LightnCandy;
    
    return [
    
        /*
        |--------------------------------------------------------------------------
        | Flags
        |--------------------------------------------------------------------------
        |
        | Set Lightncandy flags here. See https://github.com/zordius/lightncandy
        | for more information.
        |
        */
    
        'flags' => LightnCandy::FLAG_HANDLEBARSJS | LightnCandy::FLAG_ERROR_EXCEPTION | LightnCandy::FLAG_HANDLEBARSJS_FULL,
    
        /*
        |--------------------------------------------------------------------------
        | File Extensions
        |--------------------------------------------------------------------------
        |
        | All file extensions that should be compiled with the Handlebars template
        | engine. Unless you specify your own partial resolver the package will
        | look for files in Laravel's view storage paths.
        |
        */
    
        'fileext' => [
            '.handlebars',
            '.hbs',
        ],
    
        /*
        |--------------------------------------------------------------------------
        | Cache Busting
        |--------------------------------------------------------------------------
        |
        | Using nested Handlebars partials makes is difficult to determine if the
        | view at a given path is expired. Therefore you can specify environments
        | where the cached views will be recompiled on each request.
        |
        */
    
        'development_environment' => [
            'local',
        ],
    
        /*
        |--------------------------------------------------------------------------
        | Partials
        |--------------------------------------------------------------------------
        |
        | https://github.com/zordius/lightncandy#partial-support
        |
        */
    
        'partials' => [],
        'partialresolver' => false,
    
        /*
        |--------------------------------------------------------------------------
        | Helpers
        |--------------------------------------------------------------------------
        |
        | https://github.com/zordius/lightncandy#custom-helper
        |
        */
    
        'helpers' => [],
        'helperresolver' => false,
    
        /*
        |--------------------------------------------------------------------------
        | Language Helpers
        |--------------------------------------------------------------------------
        |
        | Use this option, if you want to use the language helpers in a template.
        | You can use a {{lang ...}} and {{choice ...}} helper. Both have the same
        | behaviour like the @lang and @choice Blade directives.
        |
        */
    
        'language_helpers' => true,
    
        /*
        |--------------------------------------------------------------------------
        | Optional Raw Output
        |--------------------------------------------------------------------------
        |
        | If this option is set to true, you can pass a $raw variable to the data
        | array. If $raw is true, then the template will be returned without
        | rendering in raw format. This is helpful if you want to use a Handlebars
        | template clientside with javascript.
        |
        */
    
        'optional_raw_output' => true,
    
        /*
        |--------------------------------------------------------------------------
        | Translate Raw Output
        |--------------------------------------------------------------------------
        |
        | If language_helpers and optional_raw_output are set to true, this option
        | can also set to true. If so, the translation helpers will also be
        | rendered for the raw output.
        |
        */
    
        'translate_raw_output' => true,
    
    ];
    
    opened by ggunti 0
  • Laravel 8 support

    Laravel 8 support

    Thanks for this package and I realise it's quite old but it's an important piece of my app.

    Is Laravel 8 compatibility just a matter of updating the dependancies? I'm more of a front end guy and have explored trying to test this locally but have not had much luck.

    Thanks!

    opened by locii 1
  • Update HandlebarsServiceProvider.php

    Update HandlebarsServiceProvider.php

    Do not reregister BladeCompiler in Service Provider. It will already have been registered by the framework. Re-registering will cause Blade::withoutDoubleEncoding(); that has been called in AppServiceProvider to be effectively ignored, as the BladeComiler's echoFormat parameter will have been reset.

    opened by ian-nisbet 0
  • Support for view composers on partials

    Support for view composers on partials

    Ok so I realise this is a niche feature most people won't use, but I find especially useful when using a template engine like this.

    View composers work fine for the main view or layout of a page but when you register for partial included using the {{> _partialname }} syntax it never fires.

    I currently use the view composer for my layout controller which trims that down nicely, and lets me set some variables as arrays that I cannot access directly in handlebars normally. I wanted to implement a view composer for a partial called sidebar since I have a lot of custom stats being pulled in for the sidebar, but currently limited to one view composer.

    help wanted 
    opened by Truemedia 0
  • How to use this client side?

    How to use this client side?

    I'm using laravel 5.2 and raw output doesn't work for me

    File: resources/views/test/sample.hbs

    <div class="entry">
        <h1>{{title}}</h1>
        <div class="body">{{body}}</div>
    </div>
    

    File: resources/views/template/default.blade.php

    <head>
    ...
        <script id="sample-template" type="text/x-handlebars-template">
            @raw('test.sample')
        </script>
    ...
    </head>
    

    Output:

        <script id="sample-template" type="text/x-handlebars-template">
            <div class="entry">
        <h1></h1>
        <div class="body"></div>
    </div>
        </script>
    

    Basically {{title}} and {{body}} is gone, so I can't use the template in javascript. I'm using the default config file and laravel-handlebars version 1.1.0

    help wanted 
    opened by Swanty 7
Releases(1.13.0)
Owner
The goal of ProAI is to develop high-quality packages, which make a developer's life easier.
null
a laravel package to create dynamically dashboard views in several templates ( in development)

Laravel Dashboarder A laravel package for generate admin dashboard dynamically based on Tabler template use livewire - alpinejs Installation Run the c

Laravel Iran Community 7 Dec 12, 2022
A Laravel 8 and Vue 3 SPA boilerplate using tailwind styling and sanctum for authentication :ghost:

Laravel Vue Sanctum SPA Laravel and vue spa using tailwind (laravel/ui looks) for styling and sanctum for authentification Features Laravel 8 Vue + Vu

Hijen EL Khalifi 62 Dec 5, 2022
Symfony React Blank is a blank symfony and react project, use this template to start your app using Symfony as an backend api and React as a frontend library.

Symfony React Blank Symfony React Blank is a blank symfony and react project, use this template to start your app using Symfony as an backend api and

Antoine Kingue 2 Nov 5, 2021
:elephant: A Laravel 6 SPA boilerplate with a users CRUD using Vue.js 2.6, GraphQL, Bootstrap 4, TypeScript, Sass, and Pug.

Laravel Vue Boilerplate A Laravel 6 Single Page Application boilerplate using Vue.js 2.6, GraphQL, Bootstrap 4, TypeScript, Sass and Pug with: A users

Alefe Souza 533 Jan 3, 2023
Basic Crud Generator (With Code Files, like GII (YII2)) Using Laravel, Livewire and Tailwind CSS

LiveCrud Live Crud Generator. This package generates Basic Crud with Livewire. Features Generate Complete Crud With Livewire Component and Blade Files

Ritesh Singh 28 Oct 12, 2022
A template for web development using Laravel, Inertia and Svelte

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Atikur Rahman Chitholian 0 Dec 26, 2021
An open source blog, made using Laravel, Inertia.js, and React.js. Also a learning repository.

Blog An open source Laravel-based blog. Still in progress, will be updated regularly as I wrote articles on my blog. Configurations Shared-hosting, an

Aghits Nidallah 8 Dec 6, 2022
Creating authentication using sanctum, laravel and VUE

About Laravel Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experie

Mohd Aminuddin 1 May 11, 2022
High scalable boilerplate for Laravel - Vue using laravel-mix.

Why use this ? This boilerplate make developer easier to make monolith Laravel project which integrated with Vue.js and vue-router as default front-en

Carvel Saputra Martaloho 5 Sep 21, 2022
Until 2018, Backpack v3 used this Base package to offer admin authentication and a blank admin panel using AdminLTE. Backpack v4 no longer uses this package, they're now built-in - use Backpack/CRUD instead.

Note: This package is only used by Backpack v3. Starting with Backpack v4, everything this package does is included in Backpack/CRUD - one package to

Backpack for Laravel 845 Nov 29, 2022
Backpack v3 used this Base package to offer admin authentication and a blank admin panel using AdminLTE

Until 2018, Backpack v3 used this Base package to offer admin authentication and a blank admin panel using AdminLTE. Backpack v4 no longer uses this package, they're now built-in - use Backpack/CRUD instead.

Backpack for Laravel 845 Nov 29, 2022
This repository is pre-configured, clean and empty skeleton for creating a new projects using Kraken Framework.

Kraken Application Skeleton Note: This repository contains pre-configured application skeleton for fast creation of new projects with Kraken Framework

Kraken 79 Aug 6, 2022
A CRUD operation using php and Mysql database

This is a CRUD operation using php and Mysql database. In this when we add(CREATE) new user we need to submit add data in one form only in frontenf but in backend the data is storing in two different tables this is done using foreign key in Mysql.

Mohit Kumar 1 May 10, 2022
Create a new project using QuidPHP, LemurCMS and React

QuidPHP/React About QuidPHP/React repository contains a sample application project built on top of the QuidPHP framework. This application is using Le

QuidPHP 2 May 23, 2022
Basic Crud operations using smarty and php

Smarty template engine Smarty is a template engine for PHP, facilitating the separation of presentation (HTML/CSS) from application logic. Documentati

null 0 Aug 8, 2022
It's a template for using Temporal with Laravel

Temporal Integration with Laravel Make sure you have PHP 7.4 and laravel 8.* , or higher, installed. Temploral PHP SDK is available as composer packag

Improwised Technologies Pvt. Ltd. 14 Nov 5, 2022
This project is for developing an blog_api using laravel

Blog Api A TDD implementation of a weblog RESTful API. This project is a REST api implementation of my other project laravel with more features. featu

sina shariati 6 Nov 8, 2021
Package for using ReactJS with Laravel

react-laravel With react-laravel you'll be able to use ReactJS components right from your Blade views, with optional server-side rendering, and use th

Talysson de Oliveira Cassiano 900 Jan 3, 2023
A simple starter kit for using TypedCMS with the Laravel framework.

TypedCMS Starter Kit for Laravel Our stater kits are tailored solutions for each platform, unlike the simple API wrappers offered by other vendors. Th

TypedCMS 1 Nov 20, 2021