Jump to content

WIP: TemplateFileHelper & AjaxIntercoolerJS


Recommended Posts

I pushed an initial (testing) version of TemplateFileHelper to bitbucket.


The autoload module extends TemplateFile instances with 

API vars $layout and $view

  • $layout -> global layout instance of TemplateFile to set layout placeholders ($layout->set(...) or global scripts / styles.
  • $view -> current page instance of TemplateFile to set the current page placeholders and current page scripts / styles.


load() method

Load a template / view with additional controller (php) file as subTemplate. Returns a TemplateFile object to render / output
Each sub-template controller have access to API Vars and $subTemplate (current TemplateFile instance, $subTemplate->set('placeholder', 'My value...')).

Load site/templates/chunks/test1.php controller and site/templates/chunks/test1.tpl view:

$part = $view->load('chunks/test1');
echo $part->render();

chunks/test1 example

// chunks/test1.php - controller
$subTemplate->set('var1', "Subtemplate variable output...");
<!-- chunks/test1.tpl - view -->


scripts / styles properties

FilenameArray like $config->styles | scripts. It should help to organize scripts / styles with ajax in mind (global / current page only).

// current page script

// global / layout script

You have to handle the output yourself by two foreach loops inside your _layout.php / _layout.tpl files (non ajax calls scripts and styles should be in layout head section).

foreach ($layout->scripts as $globalScript) { ... }
foreach ($view->scripts as $currentPageScript) { ... }

IntercoolerJS module will take care about async / ajax handling of (custom page) scripts and styles.


hook Page::render

hook after page render to load and add the global layout. The current page template (PW template file == controller) just handle the currents page code / view. Global layout / controller / view is moved to separate files (default: _layout.php controller and _layout.tpl view). 

Just use $layout->set(...) to fill the _layout.tpl placeholder variables inside the _layout.php controller file.


configurable module

Some settings are available...

  • Global layout (view + controller) file name (default: "_layout")
  • Current page content variable (used inside of the _layout.tpl view to output current page content, default: "currentPageContent")
  • View file extension (default: ".tpl")
  • Controller file extension (default: ".php")



It will be a dependency of the planned IntercoolerJS module which adds ajax page calls, async scripts / styles handling (current page scripts and styles...) and need a defined template handling to work...

Edited by pwFoo
Title modified
  • Like 6
Link to comment
Share on other sites

After some changes (removed "echo $view->render()" output from PW template file) it works like TemplateEngineFactory module from @Wanze.
I think about abandon my TemplateFileHelper draft and switch to the existing (and maintained?) module. 

But I have to think about the script / style handling to be compatible to the planned IntercoolerJS module (global and custom page scripts / styles). TemplateFileHelper module would handle styles / scripts by TemplateFile instance ($layout ==> global, $view ==> current page ). So IntercooolerJS module is able to remove / replace "current page" scripts and styles to prevent side effects between ajax loaded pages.


So I have to decide if TemplateFile calls like setFilename() and render() should be written to the PW template file (with my module draft) or handled by the module (hook Page::render, maybe switch to TemplateÉngineFactory).

If pw template output is replaced by the rendered view maybe debugging could be difficult because output won't visible!

It feels like more "control" if debugging output is visible and the controller includes the "echo $view->render()" call :rolleyes:

Edited by pwFoo
Link to comment
Share on other sites

And it could be difficult to attach styles and scripts loaded by PW modules (like "JqueryCore") to global or current page scripts / styles...

$config->scripts / $config->styles isn't hookable (FienameArray helper class) and I don't know how to detect the automatic loaded styles and scripts.


Any suggestions how to detect automatic loaded styles and scripts?


I think I have a simple solution... Move $config->scripts to the right context...

// Define as current page
$config->scripts = $view->scripts;

// Change to global before take care about the global layout
$config->scripts = $layout->scripts;

All Scripts / styles manually and automatically (PW modules like Inputfields, JqueryCore, ...) loaded are assigned to the needed context.

Link to comment
Share on other sites

Added IntercoolerJS response header methods... Maybe I reduce the number of methods (for example combine setPollingInterval, cancelPolling, resumePolling with a param to switch case).

     * Set x-ic-trigger response header
     * @param array $array One or more events with related data arrays
    public function trigger($array) {
        $json = json_encode($array);
        header('x-ic-trigger: ' . $json);

     * Set x-ic-script response header
     * @param string $js Valid javaScript code
    public function script($js) {
        header('X-IC-Script: ' . $js);

     * Stop current / parent element Intercooler polling
    public function cancelPolling() {
        header ('x-ic-cancelPolling: true');

     * Resume current / parent element Intercooler polling
    public function resumePolling() {
        header ('x-ic-resumePolling: true');

     * Set current / parent element Intercooler polling interval
     * @param string $interval
    public function setPollingInterval($interval) {
        header ('x-ic-setPollInterval: ' . $interval);

     * Set x-ic-refresh response header
     * @param string $pathCsv Comma separated paths to refresh.
    public function refresh($pathCsv) {
        header('x-ic-refresh: ' . $pathCsv);

     * Set x-ic-open response header
     * @param string $url New window / tab address
    public function open($url) {
        header('x-ic-open: ' . $url);

     * Set x-ic-redirect response header
     * @param string $url Redirect destination address
    public function redirect($url) {
        header('x-ic-redirect: ' .$url);

     * Add ajax redirect handler to Session::redirect
    public function hookSessionRedirect($event) {
        $event->replace = true;


Also successfully tested AjaxIntercoolerJS with Frontenduser :) 
I'll do some more tests with PW inputfields (via FormHelper) soon.

  • Like 1
Link to comment
Share on other sites

  • 1 month later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By franciccio-ITALIANO
      Hi everyone.
      I've created 12 templates that are the same but each with an extra bit of html code. 
      The piece of code is as follows:
      <div> <div class="box-pf"> <i class="fa fa-map-pin fa-2x fa-red faa-pulse animated"></i> <a href=""> <span class="uk-text-middle"><i>Sonchus oleraceus</i> 'Grespino degli Orti'</span></b> </a> </div> </div> On the third line we read "fa-red."
      I created 12 similar templates.
      The first template has only one box with fa-red, the last template has 12 boxes with icons of 12 different colors.
      So. is there any way to have only 1 template and add, if I want and when I want, a small or big, same or different piece of html code?
    • By Rezvitskyq
      Hello! There was a need to rewrite the code written with jquery into vanilla js. I have little js code on my site and I see no reason to include a library such as jquery 🙂
      $('.progress-wrap .dot').on('click', function () { let $this = $(this) let stepValue = $this.attr('data-step') $this.closest('.progress-wrap').find('.bar').css('width', stepValue + '%') $this.siblings('.dot').removeClass('is-current') $this.addClass('is-active is-current') $this.prevAll('.dot').addClass('is-active') $this.nextAll('.dot').removeClass('is-active') $('.process-panel-wrap').removeClass('is-active') $('.step-title').removeClass('is-active') if (stepValue === '0') { $('#signup-panel-1, #step-title-1').addClass('is-active') } else if (stepValue === '25') { $('#signup-panel-2, #step-title-2').addClass('is-active') } else if (stepValue === '50') { $('#signup-panel-3, #step-title-3').addClass('is-active') } else if (stepValue === '75') { $('#signup-panel-4, #step-title-4').addClass('is-active') } else if (stepValue === '100') { $('#signup-panel-5, #step-title-5').addClass('is-active') } })  
    • By Brian Peat
      Hello! I've got a single client on Processwire and it's completely foreign to me. I've been able to find most things, but they've asked for a custom designed page with a full width header image/section, and then a body block and a right side bar below the header. They're using a landing page template, so I duplicated that, figured out how to add it in the admin, and assigned it to the page. Nothing. It doesn't change a thing.
      I feel like I'm missing something obvious. I've made sure all the fields are the same, I tried to set up the parent/child stuff though this page doesn't have a parent that I can tell (though it's under Landing Pages). If I can get the template to actually kick in, I think I can use a bit of code to check for the hero section and load it at the top. I also made a copy of the widget template and set that to load instead of the original. But again, since my main page template isn't kicking in, neither is the new widget template.
      I'd just love some tips on what to check or change to get a landing page to actually render what's in the assigned page template.
      Hopefully I've used the correct terminology here to make sense.
    • By rookie
      hi there,
      Is there a module or other solution to select a template with a preview image? Sometimes it is not that easy to describe a template.
      e.g. Template with 3 columns (image, title, content, button) or template for a slider with max. 4 pictures.
      Even if it is nice to have a description field for a template, a picture says more than thousand words could describe.
      And no, I don't think I could develop something like that. I don't even know where to start.🙄
    • By muzzer
      I have just upgraded a site from 2.7 to latest v3.
      I have run into a weird issue where a page template setting for slashUrls changes from No to Yes immediately after an ajax call, causing the second ajax call on the page to use the wrong setting.
      There is no reference to the $template->slashUrls() in any of my code.
      This happens every time I load the page, it's 100% consistent.
      I have this running on a second machine under v2.7 and no such weirdness.
      I'm lost as to why this is happening, what would cause a PW setting change for slashUrls? Anyone have any ideas?
  • Create New...