Wanze Posted March 16, 2017 Author Share Posted March 16, 2017 I mostly try to use FormBuilder which does all the work However, if I need special forms in terms of styling or functionality, I'm using the ProcessWire form API to render and validate/process the input. You also get free CSRF protection. Here's an example how roughly works (written in browser, not copy paste ready): // Controller contact.php // ------------------------ $form = $modules->get('InputfieldForm'); $select = $modules->get('InputfieldSelect'); $select->required = 1; $select->setOptions(['blub', 'blub2']); $form->append($select); $csrf = $session->CSRF->renderInput(); $view->set('inputs', ['select' => $select', 'csrf' => $csrf]); // Validate and process the input if submitted if ($isSubmitted) { $form->processInput($input->post); // Handle errors and success } // View contact.twig // ------------------------------ <form action="{{ page.url}} " method="POST"> <label>Select</label> {{ form.select.render() }} {{ csrf }} <button type="submit">Submit me</button> </form> Cheers 3 Link to comment Share on other sites More sharing options...
gmclelland Posted June 13, 2017 Share Posted June 13, 2017 (edited) Hi @Wanze, I'm interested in somehow adding twig namespaces. I'm not sure if it would be best to do this in a custom module via hooking initTwig, adding to this module, or the adding to the TwigExtensions module? The reason I'm interested in this is because I would like to use PatternLab(http://patternlab.io/) with Twig and Processwire. Basically I would like to use my PatternLab components created with Twig and include them within my Processwire Twig templates. The benefit is that you can have a styleguide that is always in sync with the website's templates. I would like to add something like @molecules, @organisms, and @atoms namespaces to specify what directory my Frontend twig components are located in. The components usually live under the PatternLab's directory in your site/templates/Patternlab/source/_patterns folder. This @styleguide namespace would allow me to easily change the paths to my components folders if they ever change. The new symfony.com also uses a @icons namespace to easily include svg icons. http://symfony.com/blog/refactoring-symfony-com-front-end {# Twig namespaces create concise and beautiful templates #} <i class="icon">{{ source('@icons/arrow.svg') }}</i> For background reading of why to do this: https://www.fourkitchens.com/blog/article/component-based-theming-drupal-8-video-series/ http://www.evanlovely.com/notes/pattern-lab/integrating-pattern-lab-into-drupal-workshop.pdf - good presentation that shows how your CMS needs to use the same twig namespaces as PatternLab and why https://www.drupal.org/project/components - similar Drupal module that allows creating Twig namespames https://www.mediacurrent.com/blog/component-based-theming-drupal-8 https://www.mediacurrent.com/blog/integrating-components-drupal-8-part-1 http://jordanpagewhite.github.io/drupal-8-front-end-architecture/ Implementation I'm thinking I just need to add a textarea field that allows the user to enter a namespace and the path to the twig templates on a new line separated by a delimiter of some kind. The markupSEO module doesn't this in it's config settings. To add the namespaces to Twig: According to https://twig.sensiolabs.org/doc/1.x/api.html, I think you can do the following: $loader->addPath($templateDir, 'admin'); //adds an @admin namespace I would love to hear anyone's thoughts on this. I really like working with Processwire and Twig, it really makes code so much cleaner and easier to read. Edited June 13, 2017 by gmclelland Link to comment Share on other sites More sharing options...
onjegolders Posted July 22, 2017 Share Posted July 22, 2017 Hi Wanze, Thanks again for this module, have been really enjoying using it. Have run into a slight issue on a new site where my layout file is getting read but the views files themselves (set in `templates/views` ) aren't outputting anything. I have made sure that the factory module is using Twig and have tried deleting the cache but nothing is outputting from the views folder. I'm pretty sure my paths are correct. Do you have any good ways to debug? Thanks! Link to comment Share on other sites More sharing options...
Wanze Posted July 23, 2017 Author Share Posted July 23, 2017 @onjegolders What do you mean with layout file, can you give an example of your setup? Do you have a corresponding controller file (aka ProcessWire template in /site/templates) for the template of the current $page? Cheers Link to comment Share on other sites More sharing options...
gmclelland Posted July 23, 2017 Share Posted July 23, 2017 @onjegolders Maybe you can try templates/views/ with the trailing slash? Also like Wanze is saying you need a php controller file in /site/templates/ and you need a .twig file to go with it. Ex. calendar-list.php and calendar-list.twig. In my .twig file I extend a base template with {% extends "./partials/one-column-layout.twig" %}. I like to keep my php controller files in the same directory as my .twig files so that I don't have switch between directories so much. @Wanze Did you happen to see my post above? Link to comment Share on other sites More sharing options...
onjegolders Posted July 24, 2017 Share Posted July 24, 2017 Hi @Wanze, @gmclelland thanks for your replies. I had my layout file and my twig files in /site/templates/views and for each page I had an equivalent .php file but these were in /site/templates. I should say that my layout.twig file was getting loaded fine but not the individual view files. Seems a strange one. I will try again and play around with the paths.. Thanks Link to comment Share on other sites More sharing options...
Wanze Posted July 24, 2017 Author Share Posted July 24, 2017 17 hours ago, gmclelland said: Did you happen to see my post above? @gmclelland I would suggest to create a new module which uses the TemplateEngineTwig::initTwig hook. Having your own module also allows to enter/store some config data to map the namespaces to a path etc. Cheers Link to comment Share on other sites More sharing options...
qtguru Posted December 1, 2017 Share Posted December 1, 2017 This is strange I can't find myself to hooking TemplateEngineTwig:init no matter what i do nothing happens and in Symfony this is not a problem for me, am I missing anything wire()->addHookAfter("TemplateEngineTwig::initTwig", function($event) { $twig = $event->arguments('twig'); $instanceOfFunction = new Twig_Function('instanceof', function ($object,$evaluatedClass) { return ($object instanceof $evaluatedClass); }); $twig->addFunction($instanceOfFunction); }); Link to comment Share on other sites More sharing options...
qtguru Posted December 1, 2017 Share Posted December 1, 2017 I think this is limiting if I can't extend modules from templates and only from modules. Link to comment Share on other sites More sharing options...
qtguru Posted December 2, 2017 Share Posted December 2, 2017 Had no choice than to settle for modifying the TemplateEngineTwig, feels so hackish. If anyone can guide me on how you can hook to the TemplateEngine::initTwig from a template i'd be appreciative, a feature in the future could be a user-defined folder where extensions can be placed and used easily. Link to comment Share on other sites More sharing options...
dotnetic Posted December 2, 2017 Share Posted December 2, 2017 <?php /** * * TwigExtensions * * See README.md for usage instructions. * * @author Jens Martsch <jmartsch@gmail.com> * @version 1.0.0 * @see http://www.processwire.com */ /** * Class TwigExtensions */ class FriendChipFunctionsForTwig extends WireData implements Module { /** * Retrieves module meta data * Implementation of the Module interface * * @return array * @see http://processwire.com/apigen/class-Module.html */ public static function getModuleInfo() { return array( 'title' => 'Functions for Twig', 'summary' => 'Allows customizing twig, e.g. add extensions', 'version' => 100, 'singular' => true, 'autoload' => true, 'icon' => 'puzzle-piece', 'requires' => array( 'TemplateEngineFactory', 'TemplateEngineTwig' ) ); } public function init() { if ($this->modules->get('TemplateEngineTwig')) { $this->addHookBefore('TemplateEngineTwig::initTwig', $this, 'addExtensions'); } } /** * Hook add twig extensions * * @param HookEvent $event */ public function addExtensions(HookEvent $event) { $this->twig = $event->arguments('twig'); $this->addRelativeTimeStr(); $this->asset_path(''); } private function addRelativeTimeStr() { $twigWireRelativeTimeStr = new Twig_SimpleFunction('wireRelativeTimeStr', function ($date) { return wireRelativeTimeStr($date); }); $this->twig->addFunction($twigWireRelativeTimeStr); } /** * Returns the revved filename if a rev-manifest exists * else it returns the $filename * @param string $filename relative to the template/assets directory * @return string */ private function asset_path($filename) { $assetPathFunction = new Twig_SimpleFunction('asset_path', function ($filename) { $manifest_path = $this->config->paths->templates . 'assets/rev-manifest.json'; if (file_exists($manifest_path)) { $manifest = json_decode(file_get_contents($manifest_path), TRUE); } else { return $this->config->urls->templates . "assets/" . $filename; } if (array_key_exists($filename, $manifest)) { $manifest_filename = \ProcessWire\wire()->config->urls->templates . "assets/public/" . $manifest[$filename]; return $manifest_filename; } }); $this->twig->addFunction($assetPathFunction); } } or take a look at https://github.com/justb3a/processwire-twigextensions 2 Link to comment Share on other sites More sharing options...
gmclelland Posted December 8, 2017 Share Posted December 8, 2017 Has anybody had any trouble triggering a 404 page not found when accessing a non-valid paginated page with TemplateEngineTwig? In my template calendar-listing.php I do the following: throw new Wire404Exception(); but nothing happens. The page is still displayed instead of being redirect and displaying the 404 page. If I go to /calendar/page200 it shows the same page as /calendar instead of throwing the 404 page. However, if you look at Chrome's console the document shows a 404. What's else is strange is that I can go to /some-fake-page and it will then redirect me and display the 404 error page just fine. Note: allow page numbers is checked on this calendar-listing.php template. I also use $config->prependTemplateFile = '_init.php'; calendar-listing.twig is used to output the html. It sort of seems like something similar is happening on the processwire.com blog. If I visit https://processwire.com/blog/page200 which doesn't exist, I would expect it to give me a 404 page not found error and redirect me to the 404 not found page, but instead it shows a 500 error and still displays the blog page. The main reason I'm doing this is to try what is suggested here to improve my site's SEO: https://processwire.com/blog/posts/processwire-2.6.18-updates-pagination-and-seo/ // Don't let search engines index non-existing pages // see https://processwire.com/blog/posts/processwire-2.6.18-updates-pagination-and-seo/ if(!count($paginated_calendar_postings) && $input->pageNum > 1) { throw new Wire404Exception(); } Link to comment Share on other sites More sharing options...
gmclelland Posted December 8, 2017 Share Posted December 8, 2017 I think I found my answer: Basically with Processwire it is up to you on how you handle the 404. So in my case I just need to do a $session->redirect to my 404 page. Link to comment Share on other sites More sharing options...
ak1001 Posted March 22, 2018 Share Posted March 22, 2018 Big thanks for the module! I think it is very useful for processwire. I think it will be very practical for newcomers ( like me ) to include some basic examples to start with. Suppose i have a blank profile installed and created only home page with home template consist of title and body After installing TemplateEngineFactory module first, and TemplateEngineTwig second, and then setting engine to twig, one need to 1 delete file site/templates/home.php 2 create file site/templates/home.twig 3 create file site/templates/views/home.html please correct me if i wrong //home.html <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>{{ page.title }}</title> </head> <body> <h1>{{ page.title }}</h1> {{page.body}} <hr> <p>myvar:{{myvar}}</p> </body> </html> //home.twig <?php $view->set("myvar", "my test var"); Link to comment Share on other sites More sharing options...
Wanze Posted March 22, 2018 Author Share Posted March 22, 2018 Hi @ak1001 Thanks! 1. Do not delete /site/templates/home.php. This file now acts as a "controller" and you will pass variables to your twig templates via $view. 2. You don't need this file, the corresponding twig file would be in /site/templates/views/home.html. Note that this path and the file extension depend on your module configuration. 3. Yes, this is actually your twig template. The below code belongs to /site/templates/home.php <?php $view->set("myvar", "my test var"); Think of this file as layer between ProcessWire and your twig template. So instead of echo stuff there, pass it to the twig template which takes care of the rendering. Hope that helps! Cheers 2 Link to comment Share on other sites More sharing options...
gmclelland Posted March 22, 2018 Share Posted March 22, 2018 Hi @ak1001, Welcome, I personally like to use home.php as my controller and home.twig as the view. Using the .twig can provide Twig syntax highlighting in some text editors. Make sure you set the .twig extension in the Template Engine Twig module settings > Template File Suffix I prefer to keep those file in the same directory. It's less context switching when your looking for files. Template Engine Twig module settings > Path to templates = templates/ In your case, I would use the following: site/templates/home.twig <!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> <title>{{ page.title }}</title> </head> <body> <h1>{{ page.title }}</h1> {{page.body}} <hr> <p>myvar:{{myvar}}</p> </body> </html> site/templates/home.php <?php $view->set("myvar", "my test var"); Hope that helps 3 Link to comment Share on other sites More sharing options...
gmclelland Posted March 22, 2018 Share Posted March 22, 2018 Oops... We posted at the same time. 1 Link to comment Share on other sites More sharing options...
Wanze Posted March 22, 2018 Author Share Posted March 22, 2018 On 8.12.2017 at 10:50 PM, gmclelland said: Has anybody had any trouble triggering a 404 page not found when accessing a non-valid paginated page with TemplateEngineTwig? In my template calendar-listing.php I do the following: throw new Wire404Exception(); but nothing happens. The page is still displayed instead of being redirect and displaying the 404 page. @gmclelland I noticed the same problem on a project of mine. I tried to fix this with the latest release of the TemplateEngineFactory module (1.1.2). If you throw a Wire404Exception() the module now should set the correct 404 page for twig. So the redirect should not be necessary now. 1 Link to comment Share on other sites More sharing options...
ak1001 Posted March 23, 2018 Share Posted March 23, 2018 Thanks @Wanze I tried to do next 1 site/templates/home.php ( with myvar variable) 2 site/templates/views/home.html (twig template) and get error Notice: Undefined index: TemplateEngineNull in /home/WWW/pw/processwire/wire/core/Modules.php on line 3023 then i added empty home.twig : 1 site/templates/home.php (with myvar variable) 2 site/templates/views/home.html (twig template) 3 site/templates/home.twig (empty) and it works but not output myvar value! Only page.title and page.body So working combination in my case only php code in home.twig and template in home.html. home.php is not working/needed So i'm little confused what i do wrong. Link to comment Share on other sites More sharing options...
gmclelland Posted March 23, 2018 Share Posted March 23, 2018 @ak1001, Forget about home.html. You only need to use home.php and home.twig. All of your PHP stuff goes into home.php and your html stuff goes into home.twig. Example: in home.php <?php namespace ProcessWire; $view->set('mytitle', $page->title); In home.twig <h1>{{ mytitle }}</h1> <div class="body-content">{{ page.body }}</div> This code assumes your Processwire home template has a title and body field. 2 Link to comment Share on other sites More sharing options...
ak1001 Posted March 23, 2018 Share Posted March 23, 2018 2 hours ago, gmclelland said: You only need to use home.php and home.twig Thanks a lot, i found my mistake. I had tried to install Template Twig Replace module it have a $config->templateExtension = 'twig'; in site/config.php after i deleted this string your example works! And thanks for suggesting to keep twig and php in one folder. Link to comment Share on other sites More sharing options...
ocr_b Posted June 25, 2018 Share Posted June 25, 2018 SOLVED: For every newbie like me: Read the docs more carefully and use "{{ page.title }}" instead of "{{ page->title }}" within a twig-template I am new to Twig and want to implement into my default PW installation and get the following error: What did I do wrong? PW Verson is 3.0.98 Error: Exception: Unexpected token "operator" of value ">". (in /Applications/MAMP/htdocs/_PROCESSWIRE-BOILERPLATE/site/modules/TemplateEngineTwig/TemplateEngineTwig.module line 94) #0 /Applications/MAMP/htdocs/_PROCESSWIRE-BOILERPLATE/site/modules/TemplateEngineFactory/TemplateEngineFactory.module.php(121): TemplateEngineTwig->render() #1 /Applications/MAMP/htdocs/_PROCESSWIRE-BOILERPLATE/wire/core/WireHooks.php(822): TemplateEngineFactory->hookRender(Object(ProcessWire\HookEvent)) #2 /Applications/MAMP/htdocs/_PROCESSWIRE-BOILERPLATE/wire/core/Wire.php(442): ProcessWire\WireHooks->runHooks(Object(ProcessWire\Page), 'render', Array) #3 /Applications/MAMP/htdocs/_PROCESSWIRE-BOILERPLATE/wire/modules/Process/ProcessPageView.module(205): ProcessWire\Wire->__call('render', Array) #4 /Applications/MAMP/htdocs/_PROCESSWIRE-BOILERPLATE/wire/modules/Process/ProcessPageView.module(205): ProcessWire\Page->render() #5 /Applications/MAMP/htdocs/_PROCESSWIRE-BOILERP This error message was shown because: you are logged in as a Superuser. Error has been logged. Thanks Link to comment Share on other sites More sharing options...
dotnetic Posted June 25, 2018 Share Posted June 25, 2018 8 hours ago, ocr_b said: Read the docs more carefully and use "{{ page.title }}" instead of "{{ page->title }}" within a twig-template Because of that, I use Smarty as my template engine now, because it is closer to the ProcessWire syntax. But in one project I still have to use twig ? Also twig often throws errors, when you try to access a property/variable that isn't defined, but then you can use page["myvar"] instead without getting an error. Link to comment Share on other sites More sharing options...
Sten Posted September 15, 2018 Share Posted September 15, 2018 Hello, I have some difficulties to understand extends. How send variables through extends ? like here, may i send {{ page.title }} or {{langue_str}} to base.twig ? Base.twig is my main template with headers, footers... that extends each page. {% extends 'base.twig' %} {% block content %} <div id="titres"> <div id="titre">{{ page.title }} {{ lang }}</div> </div> <div class="hr"></div> <br> {{ include('engagement.twig') }} {{ include('lettre.twig') }} {{ intro_derniers_textes }}<br /><ul> {% for texte in derniers_textes %} <li><a href="{{ texte.url }}{{langue_str}}/">{{ texte.title }}</a></li> {% endfor %} </ul> {% endblock %} Thank you Link to comment Share on other sites More sharing options...
arjen Posted September 15, 2018 Share Posted September 15, 2018 You can't send variables through extends. I don't use this module, but you can include variables like this: {% include('engagement.twig') with: {'title': 'your title here'} %} In your engagement.twig you have access to "title". When you want variables on a higher level you can create another block in your base.twig. Read more here. Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now