Jump to content
Wanze

Module: TemplateEngineFactory

Recommended Posts

TemplateEngineFactory

The main idea of this module is to support the developer separating logic from markup.

This is achieved by turning ProcessWire templates into controllers which interact over a new API variable to template engines like Smarty or Twig. The TemplateEngineFactory ships with a default engine "ProcessWire" that uses the internal TemplateFile class to render the templates (some of you may already be familiar with this concept). However, the module is constructed in a way that any template engine can be used, implemented as separate modules. :)

Please check out the readme on GitHub for more details how it works: https://github.com/wanze/TemplateEngineFactory

... or in the modules directory: http://modules.processwire.com/modules/template-engine-factory/

post-582-0-15633700-1404419674_thumb.png

How does it work?

A controller (aka ProcessWire template) can have an associated template file which contains the markup to render. The folder where those templates are stored is configurable for each installed engine. If the Factory finds a template file with the same name as the controller, an instance to access the template is provided with a new API variable (called "view" by default). Over this API variable, you can set the dynamic variables that should be rendered. Hopefully the following example makes things clearer:

// In controller file: /site/templates/home.php

if ($input->post->form) {
  // Do some processing, send mail, save data...
  $session->redirect('./');
}
// Pass variable to the template
$view->set('foo', 'bar');
$view->set('show_nav', true);
$view->set('nav_pages', $pages->get('/')->children());

As you can see, there is no markup echoed out. The corresponding template file is responsible for this task:

// In template file: /site/templates/view/home.php

<h1><?= $page->title ?></h1>
<p>Foo: <?= $foo ?></p>

<?php if ($show_nav): ?>
  <ul>
  <?php foreach ($nav_pages as $p): ?>
    <li><a href="<?= $p->url ?>"><?= $p->title ?></a></li>
  <?php endforeach; ?>
  </ul>
<?php endif; ?>

In the example above, "ProcessWire" is used as engine. If Smarty is the active template engine, the corresponding template file could look like this:

// In template file: /site/templates/smarty/home.tpl

<h1>{$page->title}</h1>
<p>Foo: {$foo}</p>

{if $show_nav}
  <ul>
  {foreach $nav_pages as $p}
    <li><a href="{$p->url}">{$p->title}</a></li>
  {/foreach}
  </ul>
{/if}

Note that the API variable acts as a gateway which connects you to the activated template engine. We can switch the engine behind without changing the controller logic! (I know that this is probably not a very common need, but it's a cool thing anyway :P)

For further information, please check out the readmes on GitHub. Please ask questions if anything makes no sense - sometimes it's hard to get my explanations ;)

Cheers

  • Like 19

Share this post


Link to post
Share on other sites

Oh, this is perfect timing! Taking this for a test drive as soon as possible. Lately, I was aiming at the exact same thing. But this looks perfectly done with the possibility to plug in your favorite template engine! Thanks, Wanze!

  • Like 1

Share this post


Link to post
Share on other sites

Used templateFile class before to build a site. You module should make it even easier... :)

Is it planned to add a template cache (to cache the "views") in the future? 

Don't know how much time caching would be save at a small / medium site...

I'll try your module soon to build a pocketGrid base layout also with sub templates  :)

Share this post


Link to post
Share on other sites

Hi Wanze,

after a short test...

1) My setup seems not supported

// init html basic template / layout
$tpl = new TemplateFile();
$tpl->filename = $config->paths->templates.'views/html.tpl.php';

// here handle page controller / view stuff
[...]
$pagePart = $pageTpl->render();

$tpl->set('subtpl', $pagePart);

echo $tpl->render();

Because you render and output $pagePart module controlled/ inside I can't use it as sub template :(

Could you make this use possible with TemplateEngineFactory module?

2) Get a 500 error if use chunks / sub templates (for example my html layout view...)

$factory = $modules->get('TemplateEngineFactory');

$chunk = $factory->load('views/html.php');
$chunk->set('test', 'TEST');
echo $chunk->render();
 

At the moment html.php is simple:

<h1><?php echo $page->title; ?></h1>
<p><?php echo $test; ?></p>

Any idea?

Maybe you can make my setup working with your module?

Share this post


Link to post
Share on other sites

Hi pwFoo,

Thanks for your interest :)

Now you're mixing things bit up that's why it does not work. I assume that you've chosen "ProcessWire" as TemplateEngine?

Then the TemplateFile class is also used to render your templates.

1) My setup seems not supported
Because you render and output $pagePart module controlled/ inside I can't use it as sub template  :(
Could you make this use possible with TemplateEngineFactory module?

 

If you are in your /templates/basic_page.php controller, then the factory has loaded for you already the corresponding template file ine /templates/views/basic_page.php.

Your code loading the html.tpl.php file and echo out it's markup will not have any effect, because the factory will use the /templates/views/basic_page.php file for the output. You'd want to pass the variables to that template file with $view->set();

 

2) Get a 500 error if use chunks / sub templates (for example my html layout view...)

 

In the module's setting of TemplateEngineProcesswire you define where your template files are stored.

When loading a file with the factory, it looks inside that folder. So I guess maybe it wil work so:

// Template files are in /site/templates/views/

$chunk = $factory->load('html.php'); // File is in /site/templates/views/html.php
$chunk2 = $factory->load('chunks/html.php'); // File is in /site/templates/views/chunks/html.php

Now again, if you are in a controller where a corresponding template file exists, echo out will have no effect. You'd need to pass 

the markup to your template:

// In /site/templates/basic_page.php

$view->set('chunk', $chunk->render());

// In /site/templates/views/basic_page.php

<p><?= $chunk ?></p>

Hope I could make things clearer? :)

Cheers

Share this post


Link to post
Share on other sites

Hi wanze, 

I don't think I'll use the wrong path to the template / chunk, but double check ;)

Don't know my planned setup is clear so far...

I would NOT output html.php inside basic_page view..., but try to output basic_page view inside html.php view!  :P

Won't work, I found your hook into render at source code... ;)

html.php

<html>
  <head>
[...]
  </head>
  <body>
    <p><?php echo $basic_page; ?></p>
  </body>
</html>

Hope the simplified example should show what I need ;)

$basic_page is the part of current page done by your module.

Maybe I could cutting my html.php to something like html_start.php and html_end.php to get it around basic_page...

Maybe views should be not .php because it's confusing to have TWO identical files open at editor / IDE.

I'll like to use .tpl or .tpl.php to differ controller and view / template.

Share this post


Link to post
Share on other sites

I think I understand, this is a little different need. You'd have to tell the factory that your main template file is now html.php.

Could you try something like this (not tested!):

// In basic_page.php controller

$factory = $modules->get('TemplateEngineFactory');
$basic_page = $view; // Save basic_page template which is currently behind the $view API variable
$main = $factory->load('html.php'); // Load the main markup
wire()->set('view', $main); // Set the context of wire view variable to be the main template
$view = wire('view'); // Reassign to locally scoped $view variable - not sure if this is necessary, but I think so...
$view->set('basic_page', $basic_page->render()); // Pass output of basic_page to main template

If this should work, you could enable $config->prependTemplateFile an put the code in your prepended controller file, e.g. _init.php.

Maybe views should be not .php because it's confusing to have TWO identical files open at editor / IDE.

I'll like to use .tpl or .tpl.php to differ controller and view / template.

I'll add support for that so that you can define the suffix. Actually this is supported by the Smarty and Twig additions, don't know why I did not add this for the ProcessWire engine ;)

Share this post


Link to post
Share on other sites

So I'll test it soon. Thanks for help :)

Maybe a option for module configuration?

Define a global view to be used as main view?

I'll add support for that so that you can define the suffix. Actually this is supported by the Smarty and Twig additions, don't know why I did not add this for the ProcessWire engine  ;)

Great!  :biggrin:

Share this post


Link to post
Share on other sites

Maybe a option for module configuration?

Define a global view to be used as main view?

I updated the module to version 1.0.1.

All engines now have a setting Global template file where you can enter the filename of a template file that is used as "main template" behind the API variable.

This is useful if you have a main template that contains all the markup and you need to fill certain variables per controller.

Note that Smarty and Twig already support this feature with template inheritance.

Also the TemplateEngineProcesswire module now supports custom suffixes for the template files. Change this setting if you'd like to name the templates different than the controller, e.g "home.tpl.php".

Cheers

  • Like 1

Share this post


Link to post
Share on other sites

Hi Wanze,

global template works with following example.

$factory = $modules->get('TemplateEngineFactory');

$subtpl = $factory->load('basic-page'); // current page template / view basic-page.tpl
$subtpl->set('subtplvar', $page->body); 

// global template / view
$view->set('title', $page->title);
$view->set('subtpl', $subtpl->render()); // render sub template to global template variable

I think that's how it should be used?

How did it work with smarty / twig? Was it a include inside a template to load a sub template?

If I'm right template engine can't simply switched between Processwire and Smarty/Twig because template variables seems to be handled different?

PW -> load sub template & fill it like your chunk example

Twig/ Smarty -> include sub templates and fill all the template and sub template variables via api variable?

Don't know I'm right or if it's possible. But would be nice to get it filled the same way  :cool:

At the moment I'm only working with pw template class, but maybe I'll could be switch it later... So it would be a great feature have template parser independent code ;)

Share this post


Link to post
Share on other sites

I think that's how it should be used?

Yep, looks fine to me!

Another approach could be to use ProcessWire's prepend template file option. This way, you can populate the variables in your global template and overwrite them in the controllers, if needed.

Let's assume that we have a variable 'content' and 'sidebar' in our global template.

// Populate default values in prepended template file, e.g. _init.php
$view->set('content', $page->body);
$sidebar = $factory->load('chunks/sidebar');
$sidebar->set('a_variable', 'a_value');
$view->set('sidebar', $sidebar->render());

Now in the home controller, the content variable is more complex, we overwrite it:

// In home.php the content variable is pouplatet differently
$home = $factory->load('home');
$home->set('images', $pages->find('template=gallery,sort=-created,limit=3');
$view->set('content', $home->render());

How did it work with smarty / twig? Was it a include inside a template to load a sub template?

If I'm right template engine can't simply switched between Processwire and Smarty/Twig because template variables seems to be handled different?

It works the same, switching the template engine is possible as long as you use the same template filenames (the ending/suffix can be different) and identical variable names. This is possible because behind the API variable is not directly the engine like Smarty or Twig but sort of a 'gateway class' that talks to those engines. Notice that in my examples above I loaded the template files without the suffix, just the filename. Depending on the active filename, the correct template is loaded.

As an example, you could (though this is probably a very rare need) store your templates like this:

  • For the ProcessWire engine: In folder /site/templates/views/
  • For the Smarty engine: In folder /site/templates/smarty/

Now if ProcessWire is the active engine and you load the template 'home', a file in /site/templates/views/home.tpl.php gets loaded (whatever you've configured as template file suffix). If Smarty is active, the file /site/templates/smarty/home.tpl is loaded.

Don't know I'm right or if it's possible. But would be nice to get it filled the same way   :cool:

At the moment I'm only working with pw template class, but maybe I'll could be switch it later... So it would be a great feature have template parser independent code

It works as long as you have your template filenames and variable names consistent :)

However, when switching to a template engine like Smarty or Twig you should check out template inheritance. In my opinion, this is the most powerful feature and one of the main reasons to use a template engine. For smarty, I've written a little section how this could work: 

https://github.com/wanze/TemplateEngineSmarty#best-practices

Cheers

Share this post


Link to post
Share on other sites

Really awesome module, great work!

I just have one question, 

If in one controller I need to render two different templates

how can it be done?

Example home controller

and two themes, one for night other for day.

So the controller check the time and load the corresponding view.

Share this post


Link to post
Share on other sites

Really awesome module, great work!

I just have one question, 

If in one controller I need to render two different templates

how can it be done?

Example home controller

and two themes, one for night other for day.

So the controller check the time and load the corresponding view.

Thanks!

If the HTML markup is the same, maybe you could solve it with loading different CSS files. If markup is different, you'd need to dynamically set the template that is behind the API variable ($view or your custom name).

Something like this, not tested:

$theme_template = isDay() ? 'day' : 'night';
$theme = $factory->load($theme_template); // Load the correct theme
wire()->set('view', $theme); // Set the context of view variable to be the correct theme template
$view = wire('view'); // Reassign to locally scoped $view variable - not sure if this is necessary, but could be

This must happen before you pass any variables to $view. If you need this check on the whole site, you could also use ProcessWire's prependTemplateFile option and put this code in your prepended template file (controller).

Share this post


Link to post
Share on other sites

Wanze, this is a very nice module :) I am playing around with it now

Thanks :)

Today I pushed a little update (v.1.0.2) with some improvments. If you update to this version and already installed/used Smarty or Twig, make sure to update those modules as well.

What's new?

When loading a template file with the factory, you can optionally tell the module to use the given file behind the API variable:

$factory = $modules->get('TemplateEngineFactory');
$view = $factory->load('pw_rocks', true);

Setting the second parameter to true, the template file 'pw_rocks' is now used as active template behind the API variable.

In the example above, the template file is also assigned to '$view' which reflects this change also to the $view variable which is locally scoped in controllers. Whatever template is set behind the $view variable is used by the module when rendering the output of a page.

  • Like 1

Share this post


Link to post
Share on other sites

Hi Wanze,

Any direction how to configure this with $config->ajax?

<?php
//we use the page title as template
$template = $sanitizer->name($page->title);

/* render load body */
$body = $factory->load('custom-templates/' . $template. '.php');

if ($config->ajax) {

$view = $factory->load('custom-templates/_Ajax.php', true);
return;
}

/* render custom-templates */
$view->set('Body', $body->render());

I tried the code above but I dont get the desired result. I am setting the global template with my setup. Need a bit of help :) Thanks :D

Share this post


Link to post
Share on other sites

Hi peterfoeng,

What is the content of your _Ajax.php file?

Does it work if you do echo ou the template and the exit if you do not have to process any additional logic?

if ($config->ajax) {
  $view = $factory->load('custom-templates/_Ajax.php', true);
  echo $view->render();
  exit;
}

Cheers

Share this post


Link to post
Share on other sites

Hi Wanze,

I figured it out, this is a silly mistake of not supplying the correct path LOL!

<?php
//we use the page title as template
$template = $sanitizer->name($page->title);

/* render load body */
$body = $factory->load('custom-templates/' . $template. '.php');

if ($config->ajax) {
  $view = $factory->load('_Ajax.php', true);
}

/* render custom-templates */
$view->set('Body', $body->render());

So, I am rendering the body with the global template option and if there is an ajax request, the global template is overridden with ajax.php or empty template using $factory->load() :D

Silly mistakes!

  • Like 1

Share this post


Link to post
Share on other sites

hi Wanze, this system is awesome but I'm getting some issues working with the "Global template file" option, probably i didn't get the right purpose of this.

my setup is:
"templates/views/" for the path
"tpl" for the extensions
this works good as long as i use files like home.php + home.tpl
but when i set
"main" for the Global template file (or should write main.php??)
i get just blank pages.
Can you please provide an example of the correct use of this option and file structure ?
 

Share this post


Link to post
Share on other sites

Hi Sevarf2,

Sorry for my late response...!

"main" for the Global template file (or should write main.php??)

Just "main" or "main.tpl" if you've set "tpl" as the extension.

i get just blank pages.
Can you please provide an example of the correct use of this option and file structure ?

What is the content of your main.tpl? You should see this content rendered by the selected engine.

This option is useful if your controllers (aka Pw-Templates) all render the same markup. With this option, you'd define this markup in your "main.tpl" file, and home.php would render it. If you don't use the global template file, home.php would render "home.tpl".

Does it make sense?

Cheers

Share this post


Link to post
Share on other sites

This looks very nice module Wanze, thanks.

One thing i don't understand.

Why people hook into Page::render instead of TemplateFile::render, which is actual ultimate output buffer for templates.

Forked your module and trying to figure out this and that, i like it mostly, just few things i wanted to test out.

Sorry if this post is on wrong forum section, feel free to move it to proper place.

Share this post


Link to post
Share on other sites

Hi Stikki,

Thanks!

Please report any issues or new features you'd like to see here!

Why people hook into Page::render instead of TemplateFile::render, which is actual ultimate output buffer for templates.

Never thought about that, have you tried it? :)

Share this post


Link to post
Share on other sites

This option is useful if your controllers (aka Pw-Templates) all render the same markup. With this option, you'd define this markup in your "main.tpl" file, and home.php would render it. If you don't use the global template file, home.php would render "home.tpl".

Hi Wanze!

I'm having trouble understanding the file structure yet.  

What happens with PW's _main.php and _init.php?

Where the views get the project's css/js/etc.?

What am I missing? :)

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By horst
      Wire Mail SMTP

      An extension to the (new) WireMail base class that uses SMTP-transport

      This module integrates EmailMessage, SMTP and SASL php-libraries from Manuel Lemos into ProcessWire. I use this continously evolved libraries for about 10 years now and there was never a reason or occasion not to do so. I use it nearly every day in my office for automated composing and sending personalized messages with attachments, requests for Disposition Notifications, etc. Also I have used it for sending personalized Bulkmails many times.

      The WireMailSmtp module extends the new email-related WireMail base class introduced in ProcessWire 2.4.1 (while this writing, the dev-branch only).
       
      Here are Ryans announcement.



      Current Version 0.4.1
      Changelog: https://github.com/horst-n/WireMailSmtp/blob/master/CHANGELOG.md
      get it from the Modules Directory Install and Configure

      Download the module into your site/modules/ directory and install it.

      In the config page you fill in settings for the SMTP server and optionaly the (default) sender, like email address, name and signature.
      You can test the smtp settings directly there. If it says "SUCCESS! SMTP settings appear to work correctly." you are ready to start using it in templates, modules or bootstrap scripts.


      Usage Examples
      The simplest way to use it:
      $numSent = wireMail($to, $from, $subject, $textBody); $numSent = wireMail($to, '', $subject, $textBody); // or with a default sender emailaddress on config page This will send a plain text message to each recipient.
       
      You may also use the object oriented style:
      $mail = wireMail(); // calling an empty wireMail() returns a wireMail object $mail->to($toEmail, $toName); $mail->from = $yourEmailaddress; // if you don't have set a default sender in config // or if you want to override that $mail->subject($subject); $mail->body($textBody); $numSent = $mail->send(); Or chained, like everywhere in ProcessWire:
      $mail = wireMail(); $numSent = $mail->to($toEmail)->subject($subject)->body($textBody)->send(); Additionaly to the basics there are more options available with WireMailSmtp. The main difference compared to the WireMail BaseClass is the sendSingle option. With it you can set only one To-Recipient but additional CC-Recipients.
      $mail = wireMail(); $mail->sendSingle(true)->to($toEmail, $toName)->cc(array('person1@example.com', 'person2@example.com', 'person3@example.com')); $numSent = $mail->subject($subject)->body($textBody)->send(); The same as function call with options array:
      $options = array( 'sendSingle' => true, 'cc' => array('person1@example.com', 'person2@example.com', 'person3@example.com') ); $numSent = wireMail($to, '', $subject, $textBody, $options); There are methods to your disposal to check if you have the right WireMail-Class and if the SMTP-settings are working:
      $mail = wireMail(); if($mail->className != 'WireMailSmtp') { // Uups, wrong WireMail-Class: do something to inform the user and quit echo "<p>Couldn't get the right WireMail-Module (WireMailSmtp). found: {$mail->className}</p>"; return; } if(!$mail->testConnection()) { // Connection not working: echo "<p>Couldn't connect to the SMTP server. Please check the {$mail->className} modules config settings!</p>"; return; } Following are a ...


      List of all options and features


      testConnection () - returns true on success, false on failures


      sendSingle ( true | false ) - default is false

      sendBulk ( true | false ) - default is false, Set this to true if you have lots of recipients (50+)


      to ($recipients) - one emailaddress or array with multiple emailaddresses

      cc ($recipients) - only available with mode sendSingle, one emailaddress or array with multiple emailaddresses

      bcc ($recipients) - one emailaddress or array with multiple emailaddresses

       
      from = 'person@example.com' - emailaddress, can be set in module config (called Sender Emailaddress) but it can be overwritten here

      fromName = 'Name Surname' - optional, can be set in module config (called Sender Name) but it can be overwritten here


      priority (3) - 1 = Highest | 2 = High | 3 = Normal | 4 = Low | 5 = Lowest

      dispositionNotification () or notification () - request a Disposition Notification


      subject ($subject) - subject of the message

      body ($textBody) - use this one alone to create and send plainText emailmessages

      bodyHTML ($htmlBody) - use this to create a Multipart Alternative Emailmessage (containing a HTML-Part and a Plaintext-Part as fallback)

      addSignature ( true | false ) - the default-behave is selectable in config screen, this can be overridden here
      (only available if a signature is defined in the config screen)

      attachment ($filename, $alternativeBasename = "") - add attachment file, optionally alternative basename


      send () - send the message(s) and return number of successful sent messages


      getResult () - returns a dump (array) with all recipients (to, cc, bcc) and settings you have selected with the message, the message subject and body, and lists of successfull addresses and failed addresses,


      logActivity ($logmessage) - you may log success if you want

      logError ($logmessage) - you may log warnings, too. - Errors are logged automaticaly
       
       
      useSentLog (true | false) - intended for usage with e.g. third party newsletter modules - tells the send() method to make usage of the sentLog-methods - the following three sentLog methods are hookable, e.g. if you don't want log into files you may provide your own storage, or add additional functionality here

      sentLogReset ()  - starts a new LogSession - Best usage would be interactively once when setting up a new Newsletter

      sentLogGet ()  - is called automaticly within the send() method - returns an array containing all previously used emailaddresses

      sentLogAdd ($emailaddress)  - is called automaticly within the send() method
       
      Changelog: https://github.com/horst-n/WireMailSmtp/blob/master/CHANGELOG.md
       
      LATEST UPDATE:
       
    • By ukyo
      Mystique Module for ProcessWire CMS/CMF
      Github repo : https://github.com/trk/Mystique
      Mystique module allow you to create dynamic fields and store dynamic fields data on database by using a config file.
      Requirements
      ProcessWire 3.0 or newer PHP 7.0 or newer FieldtypeMystique InputfieldMystique Installation
      Install the module from the modules directory:
      Via Composer:
      composer require trk/mystique Via git clone:
      cd your-processwire-project-folder/ cd site/modules/ git clone https://github.com/trk/Mystique.git Module in live reaction with your Mystique config file
      This mean if you remove a field from your config file, field will be removed from edit screen. As you see on youtube video.
      Using Mystique with your module or use different configs path, autoload need to be true for modules
      Default configs path is site/templates/configs/, and your config file name need to start with Mystique. and need to end with .php extension.
      // Add your custom path inside ready or init function, didn't tested outside Mystique::add('your-configs-path'); All config files need to return a php array like examples.
      Same as ProcessWire Inputfield Api, only difference is set and showIf usage
      <?php namespace ProcessWire; /** * Resource : testing-mystique */ return [ 'title' => __('Testing Mystique'), 'fields' => [ 'text_field' => [ 'label' => __('You can use short named types'), 'description' => __('In file showIf working like example'), 'notes' => __('Also you can use $input->set() method'), 'type' => 'text', 'showIf' => [ 'another_text' => "=''" ], 'set' => [ 'showCount' => InputfieldText::showCountChars, 'maxlength' => 255 ], 'attr' => [ 'attr-foo' => 'bar', 'attr-bar' => 'foo' ] ], 'another_text' => [ 'label' => __('Another text field (default type is text)') ] ] ]; Example:
      site/templates/configs/Mystique.seo-fields.php <?php namespace ProcessWire; /** * Resource : seo-fields */ return [ 'title' => __('Seo fields'), 'fields' => [ 'window_title' => [ 'label' => __('Window title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'attr' => [ 'placeholder' => __('Enter a window title') ] ], 'navigation_title' => [ 'label' => __('Navigation title'), 'type' => Mystique::TEXT, // or InputfieldText 'useLanguages' => true, 'showIf' => [ 'window_title' => "!=''" ], 'attr' => [ 'placeholder' => __('Enter a navigation title') ] ], 'description' => [ 'label' => __('Description for search engines'), 'type' => Mystique::TEXTAREA, 'useLanguages' => true ], 'page_tpye' => [ 'label' => __('Type'), 'type' => Mystique::SELECT, 'options' => [ 'basic' => __('Basic page'), 'gallery' => __('Gallery'), 'blog' => __('Blog') ] ], 'show_on_nav' => [ 'label' => __('Display this page on navigation'), 'type' => Mystique::CHECKBOX ] ] ]; Searching data on Mystique field is limited. Because, Mystique saving data to database in json format. When you make search for Mystique field, operator not important. Operator will be changed with %= operator.
      Search example
      $navigationPages = pages()->find('my_mystique_field.show_on_nav=1'); $navigationPages = pages()->find('my_mystique_field.page_tpye=gallery');
    • By Robin S
      File Info
      A textformatter module for ProcessWire. The module can add information to local Pagefile links in two ways:
      As extra markup before, within or after the link As data attributes on the link (handy if you want to use a Javascript tooltip library, for instance) Screenshots
      Module config

      Example of output

      Installation
      Install the File Info module.
      Add the textformatter to one or more CKEditor fields.
      Configuration
      Add markup action (and general)
      Select "Add markup to links" Select the Pagefile attributes that will be retrieved. The attribute "filesizeStrCustom" is similar to the core "filesizeStr" attribute but allows for setting a custom number of decimal places. If you select the "modified" or "created" attributes then you can define a date format for the value. Enter a class string to add to the links if needed. Define the markup that will be added to the links. Surround Pagefile attribute names in {brackets}. Attributes must be selected in the "Pagefile attributes" section in order to be available in the added markup. If you want include a space character at the start or end of the markup then you'll need >= PW 3.0.128. Select where the markup should be added: prepended or appended within the link, before the link, or after the link. Add data attributes action
      Select "Add data attributes to links" Select the Pagefile attributes that will be retrieved. These attributes will be added to the file links as data attributes. Attributes with camelcase names will be converted to data attribute names that are all lowercase, i.e. filesizeStrCustom becomes data-filesizestrcustom. Hook
      If you want to customise or add to the attributes that are retrieved from the Pagefile you can hook TextformatterFileInfo::getFileAttributes(). For example:
      $wire->addHookAfter('TextformatterFileInfo::getFileAttributes', function(HookEvent $event) { $pagefile = $event->arguments(0); $page = $event->arguments(1); $field = $event->arguments(2); $attributes = $event->return; // Add a new attribute $attributes['sizeNote'] = $pagefile->filesize > 10000000 ? 'This file is pretty big' : 'This file is not so big'; $event->return = $attributes; });  
      https://github.com/Toutouwai/TextformatterFileInfo
      https://modules.processwire.com/modules/textformatter-file-info/
    • By Robin S
      Access By Query String
      Grant/deny access to pages according to query string.
      Allows visitors to view protected pages by accessing the page via a special URL containing an "access" GET variable. This allows you to provide a link to selected individuals while keeping the page(s) non-viewable to the public and search engines. The recipients of the link do not need to log in so it's very convenient for them.
      The view protection does not provide a high level of security so should only be used for non-critical scenarios. The purpose of the module was to prevent new websites being publicly accessible before they are officially launched, hence the default message in the module config. But it could be used for selected pages on existing websites also.
      Once a visitor has successfully accessed a protected page via the GET variable then they can view any other page protected by the same access rule without needing the GET variable for that browsing session.
      Superusers are not affected by the module.
      Usage
      Install the Access By Query String module.
      Define access rules in the format [GET variable]??[selector], one per line.
      As an example the rule...
      rumpelstiltskin??template=skills, title~=gold ...means that any pages using the "skills" template with the word "gold" in the title will not be viewable unless it is accessed with ?access=rumpelstiltskin in the URL. So you could provide a view link like https://domain.com/skills/spin-straw-into-gold/?access=rumpelstiltskin to selected individuals.
      Or you could limit view access to the whole frontend with a rule like...
      4fU4ns7ZWXar??template!=admin You can choose what happens when a protected page is visited without the required GET variable:
      Replace the rendered markup Throw a 404 exception If replacing the rendered markup you can define a meta title and message to be shown. Or if you want to use more advanced markup you can hook AccessByQueryString::replacementMarkup().
      $wire->addHookAfter('AccessByQueryString::replacementMarkup', function(HookEvent $event) { // Some info in hook arguments if needed... // The page that the visitor is trying to access $page = $event->arguments(0); // An array of access keys that apply to the page $access_keys = $event->arguments(1); // The title $title = $event->arguments(2); // The message $message = $event->arguments(3); // Return some markup $event->return = 'Your markup'; }); Screenshot

       
      https://github.com/Toutouwai/AccessByQueryString
      https://modules.processwire.com/modules/access-by-query-string/
    • By David Karich
      ProcessWire InputfieldRepeaterMatrixDuplicate
      Thanks to the great ProModule "RepeaterMatrix" I have the possibility to create complex repeater items. With it I have created a quite powerful page builder. Many different content modules, with many more possible design options. The RepeaterMatrix module supports the cloning of items, but only within the same page. Now I often have the case that very design-intensive pages and items are created. If you want to use a content module on a different page (e.g. in the same design), you have to rebuild each item manually every time.
      This module extends the commercial ProModule "RepeaterMatrix" by the function to duplicate repeater items from one page to another page. The condition is that the target field is the same matrix field from which the item is duplicated. This module is currently understood as proof of concept. There are a few limitations that need to be considered. The intention of the module is that this functionality is integrated into the core of RepeaterMatrix and does not require an extra module.
      Check out the screencast
      What the module can do
      Duplicate a repeater item from one page to another No matter how complex the item is Full support for file and image fields Multilingual support Support of Min and Max settings Live synchronization of clipboard between multiple browser tabs. Copy an item and simply switch the browser tab to the target page and you will immediately see the past button Support of multiple RepeaterMatrix fields on one page Configurable which roles and fields are excluded Duplicated items are automatically pasted to the end of the target field and set to hidden status so that changes are not directly published Automatic clipboard update when other items are picked Automatically removes old clipboard data if it is not pasted within 6 hours Delete clipboard itself by clicking the selected item again Benefit: unbelievably fast workflow and content replication What the module can't do
      Before an item can be duplicated in its current version, the source page must be saved. This means that if you make changes to an item and copy this, the old saved state will be duplicated Dynamic loading is currently not possible. Means no AJAX. When pasting, the target page is saved completely No support for nested repeater items. Currently only first level items can be duplicated. Means a repeater field in a repeater field cannot be duplicated. Workaround: simply duplicate the parent item Dynamic reloading and adding of repeater items cannot be registered. Several interfaces and events from the core are missing. The initialization occurs only once after the page load event Changelog
      1.0.4
      Bug fix: Various bug fixes and improvements in live synchronization Bug fix: Items are no longer inserted when the normal save button is clicked. Only when the past button is explicitly clicked Feature: Support of multiple repeater fields in one page Feature: Support of repeater Min/Max settings Feature: Configurable roles and fields Enhancement: Improved clipboard management Enhancement: Documentation improvement Enhancement: Corrected few typos #1 1.0.3
      Feature: Live synchronization Enhancement: Load the module only in the backend Enhancement: Documentation improvement 1.0.2
      Bug fix: Various bug fixes and improvements in JS functions Enhancement: Documentation improvement Enhancement: Corrected few typos 1.0.1
      Bug fix: Various bug fixes and improvements in the duplication process 1.0.0
      Initial release Support this module
      If this module is useful for you, I am very thankful for your small donation: Donate 5,- Euro (via PayPal – or an amount of your choice. Thank you!)
      Download this module
      > Github: https://github.com/FlipZoomMedia/InputfieldRepeaterMatrixDuplicate
      > PW module directory: – soon –
×
×
  • Create New...