Giter Site home page Giter Site logo

blade-extensions's Introduction

Laravel Blade Extension Classes

This Laravel >=5.5 package allows you to organize your Blade extensions into classes. It provides a simple container pass that registers all your extensions with the Blade compiler using a simple tag.

Organizing Blade extensions as classes in the service container allows you to group extension functionality within one object, allowing you to inject dependencies through the service container and provide shared protected/private methods.

Installation

You can install this package via Composer using the following command:

composer require bitpress/blade-extensions

This package will automatically register the included service provider.

Usage

At a high level, the goal of this package is to make it easy and convenient to register blade extensions as classes from the service container automatically using service container tagging. Here's the gist of how it works:

  1. Create a new Extension class with php artisan make:blade Example
  2. Register the Extension in a service provider's register() method
  3. Tag the service with blade.extension
  4. The BladeExtensionServiceProvider automatically wires up the directives in the blade compiler during boot().

Creating a new Extension Class

It would be annoying to create a new extension class from scratch each time, so this package provides an artisan command to create your extensions under the App\Blade namespace:

# Creates App\Blade\CartExtension
php artisan make:blade Cart

Defining the Extension Directives and Conditionals

Once you create a blade extension class, you can define supported directives, conditionals, or both. Custom Blade directives and conditionals are simply PHP callables:

<?php

namespace App\Blade;

use BitPress\BladeExtension\Contracts\BladeExtension;

class CartExtension implements BladeExtension
{
    public function getDirectives()
    {
        return [
            'cartcount' => [$this, 'getCartCount']
        ];
    }

    public function getConditionals()
    {
        return [
            'cartempty' => [$this, 'isCartEmpty']
        ];
    }

    public function getCartCount()
    {
        // logic to return cart count
    }

    public function isCartEmpty()
    {
        // logic for empty cart
    }
}

Note that Blade extension classes implement the BladeExtension contract, which includes getDirectives() and getConditionals(). Even if you don't plan on registering any conditionals, for example, you must implement the getConditionals() method and return an empty array.

Your custom blade extension will be registered in the service container, so you can define a __construct() method and inject services from the container. The fact that Blade extensions are services allows you to group common code around your blade extensions, including those directives that depend on outside services that are registered in the container.

Registering a New Blade Service

After you define a blade extension, you still need to register it in the service container and tag it properly so the BladeExtensionServiceProvier can define the PHP callables in the Blade compiler during boot().

This package provides a BladeRegistrar class to define the extension in the container and tagging it properly, for example, in App\Providers\AppServiceProvider:

use Illuminate\Support\ServiceProvider;
use BitPress\BladeExtension\Container\BladeRegistrar;

class AppServiceProvider extends ServiceProvider
{
    public function register()
    {
        BladeRegistrar::register(\App\Blade\CartExtension::class);
    }
}

If you need to, you can create the service in a Closure:

use \App\Blade\CartExtension::class;

BladeRegistrar::register(CartExtension::class, function () {
    // Do stuff...

    return new CartExtension($stuff);
});

You can also use the blade_extension() helper function to register the service if you prefer:

public function register()
{
    blade_extension(\App\Blade\CartExtension::class);
}

Without the Blade extension registrar, this is how you'd define an extension manually:

$this->app->singleton(\App\Blade\CartExtension::class);
$this->app->tag(\App\Blade\CartExtension::class, 'blade.extension');

The benefit of using the BladeRegistrar class is that it takes care of defining a consistent tag across any number of service providers and removes the boilerplate.

Registering Extensions with the Blade Compiler

The way this package works is quite simple, here's how the boot() method actually gets all registered extensions and defines them with the Blade compiler:

foreach ($this->app->tagged('blade.extension') as $extension) {
    if (! $extension instanceof BladeExtension) {
        throw new InvalidBladeExtension($extension);
    }

    foreach ($extension->getDirectives() as $name => $callable) {
        $this->app['blade.compiler']->directive($name, $callable);
    }

    foreach ($extension->getConditionals() as $name => $callable) {
        $this->app['blade.compiler']->if($name, $callable);
    }
}

License

The MIT License (MIT). Please see License File for more information.

blade-extensions's People

Contributors

paulredmond avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

blade-extensions's Issues

Constant if expression?

I'd like to use this to alter the template output when it's being compiled based on a .env setting that's fixed at deployment. We have two news sites running on the same codebase, and a few pages are drastically altered by which site is being served. We compile the templates during deployment, and I'd like to fix those alterations in the compiled output so that the if condition is not checked during runtime. Do you know if this is possible?

In other words, I'd like to tell the Blade compiler to evaluate the if condition during compilation instead of injecting <php if ($constant_condition): ?> into the compiled template. I suspect I'll have to extend the compiler itself, but I'm hoping you've already thought of that. :)

how to pass params

  1 @php
  2 $array = array_fill(0, 10, 'hello');
  3 \Log::info($array);
  4 @endphp
  5 @wct ({{ $array }})
  6 
17     public function getDirectives()
 18     {
 19       \Log::info(__FUNCTION__);
 20       return [
 21         'wct' => [$this, 'getWechatContentTemplate']
 22       ];
 23     }
 24 

 33     public function getConditionals()
 34     {
 35         return [];
 36     }
 37 
 38     public function getWechatContentTemplate($values) {
 39       \Log::info($values);
 40       if(isset($values) && is_array($values) && array_key_exists('code', $values)) {
 41         $wct = Esl\WechatContentTemplate::where('code', $values['code'])->first();
 42         if(isset($wct)) {
 43           return $wct->content;
 44         } else {
 45           return '';
 46         }
 47       } else {
 48         return '';
 49       }
 50     }

the log is

[2020-03-21 17:28:36] local.INFO: {{ $array }}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.