GithubHelp home page GithubHelp logo

mauricius / wireframerendererblade Goto Github PK

View Code? Open in Web Editor NEW
4.0 5.0 1.0 31 KB

Laravel Blade renderer for the Wireframe output framework

License: Mozilla Public License 2.0

PHP 100.00%
laravel processwire processwire-modules

wireframerendererblade's Introduction

WireframeRendererBlade

Blade renderer for the ProcessWire Wireframe output framework.


This module is an optional renderer add-on for the Wireframe output framework, adding support for the Laravel Blade templating engine.

Basic usage

First of all, you need to install both Wireframe and WireframeRenderBlade.

Then you have to install the dependencies of WireframeRenderBlade by running

composer install

in the module folder.

Finally you can set up Wireframe (as instructed at https://wireframe-framework.com/getting-started/). Once that's done, you can open the bootstrap file (wireframe.php) and instruct Wireframe to use the Blade renderer:

// during Wireframe init (this is the preferred way):
$wireframe->init([
    'renderer' => ['WireframeRendererBlade', [
        // optional settings array
    ]],
]);

// ... or after init (this incurs a slight overhead):
$wireframe->setRenderer('WireframeRendererBlade', [
    // optional settings array
]);

Settings

You can provide your values for the views and cache paths. Default values are outlined below:

[
    'views' => '/site/templates/views',
    'cache' => '/site/assets/cache/WireframeRendererBlade'
]

Blade templates

Once you've told Wireframe to use the Blade renderer, by default it will attempt to render all your views, layouts, partials and components using Blade. File extension for Blade files is .blade.php.

Note that if a Blade file can't be found, Wireframe will automatically fall back to native (.php) file. This is intended to ease migrating from PHP to Blade, and also makes it possible for Blade and PHP view files to co-exist.

Layouts

Blade allows you to extend a parent layout using the Blade @extends directive, to specify which layout the child view should "inherit". By default all layouts are referenced from the views folder

@extends('layout')
.
|-- views
|   |-- layout.blade.php
|   └-- child.blade.php

Otherwise you can keep the Wireframe concept of layout and use a Blade file from the layouts folder, by prefixing the layout with the layout:: namespace

@extends('layout::layout')
.
|-- layout
|   └-- layout.blade.php
|-- views
|   └-- child.blade.php

Includes (partials)

The same concept is valid for sub-views. You can include a Blade file from another view using the @include directive. By defaut it will pick up partials from the views folder. If you prefer to use a file from the Wireframe partials directory you can prefix the partial name with the partial:: namespace.

Extending Blade

If you want to extend Blade (e.g. add a new directive), you can access the Blade Environment by hooking into WireframeRendererBlade::initBlade:

Adding a Custom Directive

// site/ready.php
$wire->addHookAfter('WireframeRendererBlade::initBlade', function(HookEvent $event) {
    $event->return->directive('hello', function ($expression) {
        return "<?php echo 'Hello ' . {$expression}; ?>";
    });
});
@hello('World')

Adding a Custom If Directive

// site/ready.php
$wire->addHookAfter('WireframeRendererBlade::initBlade', function(HookEvent $event) use ($user) {
    $event->return->if('superuser', function () use ($user) {
        return $user->isLoggedIn() and $user->isSuperuser();
    });
});
@superuser
    <h2>Hello</h2>
@else
    <p>You don't have access here</p>
@endsuperuser

Adding a directive to cache partial HTML with Markup Cache Module

// site/ready.php
$wire->addHookAfter('WireframeRendererBlade::initBlade', function(HookEvent $event) use ($wire) {
     $event->return->directive('cache', function ($expression) use ($wire) {
        $args = array_map(function ($item) {
            return trim($item);
        }, explode(',', $expression));

        $key = substr($args[0], 1, -1);
        $duration = $args[1] ?? (24 * 60 * 60); // 24 hours

        return implode('', [
            "<?php ob_start(); ?>",
            '<?php if (! $__partial = $modules->get("MarkupCache")->get("' . $key . '",' . $duration . ')) : ?>',
        ]);
    });

    $event->return->directive('endcache', function () {
        return implode('', [
            '<?php endif; ?>',
            '<?php if (! $__partial): ?>',
            '<?php $__partial = ob_get_clean(); ?>',
            '<?php $modules->get("MarkupCache")->save($__partial); ?>',
            '<?php else : ?>',
            '<?php ob_end_clean(); ?>',
            '<?php endif; ?>',
            '<?php echo $__partial; ?>',
        ]);
    });
});
@cache('my-cache-key', 3600)
    {{-- heavy stuff here --}}
@endcache

Adding a directive to cache an included file with Markup Cache Module

// site/ready.php
$wire->addHookAfter('WireframeRendererBlade::initBlade', function(HookEvent $event) use ($wire) {
     $event->return->directive('cacheInclude', function ($expression) use ($wire) {
        $args = array_map(function ($item) {
            return trim($item);
        }, explode(',', $expression));

        $key = substr($args[0], 1, -1);
        $duration = $args[1] ?? (24 * 60 * 60); // 24 hours

        return implode('', [
            '<?php if (! $__partial = $modules->get("MarkupCache")->get("' . $key . '",' . $duration . ')) : ?>',
            '<?php $__partial = $__env->make("' . $key . '", \Illuminate\Support\Arr::except(get_defined_vars(), ["__data", "__path"]))->render(); ?>',
            '<?php $modules->get("MarkupCache")->save($__partial); ?>',
            '<?php endif; ?>',
            '<?php echo $__partial; ?>'
        ]);
    });
});
@cacheInclude('my-partial', 3600)

You can also access the underlying Blade class from the wireframe.php file:

$blade = $wireframe->view->getRenderer()->getBladeInstance();

Localization

ProcessWire translation functions are provided as helpers so you can use __() and _n() directly in the templates, keeping ProcessWire ability to detect strings that need translation. However you will have to manually override the textdomain to use the path of the uncompile Blade file, otherwise ProcessWire will not be able to match your translations.

However this is easier as it sounds. Just add this code to your wireframe.php file

/**
 * Convert template path into valid textdomain
 * e.g. from /site/templates/views/mypage.blade.php
 * into site--templates--views--mypage-blade-php
 * @param  string $path
 * @return string
 */
function getViewTextDomain($path) {
    $config = wire('config');

    $input = str_replace('.', '-', str_replace($config->paths->root, '', $path));

    $re = '/\/+/m';

    return preg_replace($re, '--', $input);
}

$wireframe->view->getRenderer()->getBladeInstance()->composer('*', function($view)
{
    $view->with('textdomain', Utils::getViewTextDomain($view->getPath()));
});

Finally you can use the $textdomain variable wherever you need to translate strings

{{ __("Translate me", $textdomain) }}

Laravel Mix

In case you're using Laravel Mix, WireframeRendererBlade provides a mix function to reference frontend assets.

Gotchas

Some Blade directives don't work in the ProcessWire context. A few examples are @inject, @can and @cannot.

License

MPL

wireframerendererblade's People

Contributors

mauricius avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

porl

wireframerendererblade's Issues

Having some trouble with component views (and layouts)

Hey @mauricius!

I'm posting this issue following a question at the support forum (https://processwire.com/talk/topic/21893-wireframe-wip/?do=findComment&comment=205955). It seems that currently using Blade based component views is a bit tricky, unless I'm missing something:

  • In order to make Wireframe detect a Blade based component view, I need to place the [view name].blade.php file to the component's directory (in this case /site/templates/components/Hero/default.blade.php).
  • While rendering said view, WireframeRendererBlade modifies the path to point to /site/templates/views/Hero/default.blade.php.
  • This means that the original file is never used, and I actually have to a) put a dummy file to /site/templates/components/Hero/default.blade.php (for Wireframe to detect this view) and then put the actual view at /site/templates/views/Hero/default.blade.php (for WireframeRendererBlade).

Ideas? :)

Note that the same thing happens with layouts: normally I would place a layout file at /site/templates/layouts/default.php, but if I add a Blade layout (/site/templates/layouts/default.blade.php), this results in a fatal error since the render method changes the path to /site/templates/views/default.blade.php.

Obviously this won't affect "extends" calls, so if you're extending the layout from the view then you won't run into this issue. That's not how Wireframe layout/view relations work by default, though; normally view doesn't have to know anything about layout, which also makes it possible to switch the layout without modifying any existing views, etc. :)

Please let me know if I misunderstood something! This is the first time I'm using this module, and it's entirely possible that I made a mistake somewhere.

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.