Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 01/10/2025 in all areas

  1. I’m happy to report that today the dev branch has been merged to the main/master branch with our latest version: 3.0.244. This is after about a year on the dev branch. Relative to the previous main/master version (3.0.229) there’s a lot to cover. That’s what I’ll be working on this coming week, writing a new blog post outlining all that’s new and all that’s changed. Like with most ProcessWire versions, it should be an easy upgrade, swapping out the old /wire/ directory for the new one. Thanks for reading and stay tuned for more details next week!
    18 points
  2. Plates for ProcessWire is a module to make using Plates with your ProcessWire templates plug-and-play. Plates is an extremely lightweight pure PHP templating system that provides features that developers have come to expect when building applications and sites in ProcessWire and beyond. From the Plates website: Highlights from the documentation: Native PHP templates, no new syntax to learn Plates is a template system, not a template language Plates encourages the use of existing PHP functions Increased code reuse with template layouts and inheritance Template folders for grouping templates into namespaces Data sharing across templates Pre-assign data to specific templates Built-in escaping helpers Easy to extend using functions and extensions Plates is an extremely stable application that has been in development and use in production since 2014. This module is also a simple adapter so I am confident in it's stability as I've already used it myself. However, the custom extensions included should be considered early releases and bug reports are welcome, pull requests are very welcome as well! If you're familiar with Plates or just want to get started now, you can download the module from the Github repository. Batteries are included, documentation provided. Previously this module requires that you install Plates manually via Composer. To make the module more accessible and a true "drop-in and code" solution, Plates is now included. If you prefer to manage your packages separately via Composer, or have already installed this module and Plates, Plates for ProcessWire will use the version you have installed then fall back to the version shipped with the module if it is not present. So, FireWire, why another templating engine? There are many stellar templating engines available. I've used several of them and they have truly great features. I also appreciate the simplicity of working with PHP. While templating engines do sometimes offer more terse syntax, it's not a killer feature for everyone like code reuse, nesting, and layouts may be. Code editors will always offer first-class support for PHP and syntax highlighting makes some of the arguments about readability less of a feature benefit for alternatives. Plates takes care of the limitations that come with writing pure PHP templates. Plates feels very at home with the ProcessWire API. Like ProcessWire, it also scales infinitely and its focus on core features over the large library approach makes for a great developer experience. If you've worked with templating engines in the past, the features are familiar. If you haven't, you'll be up to speed remarkably fast. I wrote this module with the intention of making it a "drop-in and code" experience, and I've worked on using the extensibility of Plates to add some extra superpowers to boot. Plates is another great option that may be useful to you whether because it's more your style, it fits your use case, or maybe your first time adding a little extra oomph to your ProcessWire templates. The first 10 minutes you spend with the Plates documentation might be the last 10 minutes. A Simple Example Start with files and folders. Things to know off the bat: Plates for ProcessWire comes pre-configured to look for Plates templates in your /site/templates folder By default it will look for files with the extension '.plates.php' to help differentiate from ProcessWire files, however this may be customized to any extension you prefer on the module config page The folder structure here is entirely up to you, this example can be used but is not required. /site /templates /components image_gallery.plates.php /layouts main.plates.php /views home.plates.php home.php ready.php Your ProcessWire templates will contain one line that hands off rendering to Plates <!-- /site/templates/home.php --> <?=$plates->templates->render('views/home')?> Start by creating your layout. We'll keep it simple. <?php namespace ProcessWire; // /site/templates/layouts/main.plates.php /** * @property string|null $title Page title * @property string|null $description Meta description */ ?> <!DOCTYPE html> <html> <head> <title><?= $title ?? $page->title; ?></title> <?php if ($description ?? null): ?> <meta name="description" content="<?=$description?>"> <?php endif ?> <link rel="stylesheet" href="<?=$config->paths->templates?>styles/app.css"> </head> <body> <header class> <img src="/path/to/logo.jpg"> <nav> <ul> <?php foreach ($navBase->children->prepend($pages->get('/')) as $navPage): ?> <li> <a href="<?=$navPage->url?>"><?=$navPage->title?></a> </li> <?php endforeach ?> </ul> </nav> </header> <section> <?= $this->section('hero'); ?> </section> <?= $this->section('content') ?> <footer> <?= $this->section('footer'); ?> </footer> <script src="/path/to/your/file.js"></script> </body> </html> I like to add docblocks at the top of my Plates templates because we can pass data to any template or layout wherever needed and this helps understand what is accepted or expected at a glance. This is optional and just a style preference. Some notes: The full ProcessWire API is available including language functions Your Plates templates are rendered inside a Plates Template object. To use any Plates function, custom function, or custom extension you use $this Jumping over to home.plates.php <?php namespace ProcessWire; // /site/templates/views/home.plates.php $this->layout('layouts/main', ['description' => $page->description]); ?> <?php $this->start('hero') ?> <h1><?=$page->headline?></h1> <img src="<?=$page->hero_image->url?>" alt="$page->hero_image->description"> <?php $this->end() ?> <section> some stuff here </section> <?php if ($page->gallery->count()): ?> <section> <?php $this->insert('components/image_gallery', [ 'images' => $page->gallery, 'title' => __('Image Gallery'), ]) ?> </section> <?php endif ?> <section> Some stuff there </section> <?php $this->start('footer') ?> <p>Thanks for visiting</p> <?php $this->end() ?> Things to note: Even though this file is located in the 'views' subdirectory, Plates is configured out of the box to use '/site/templates/' as the base directory, so you can write paths without '../' directory traversal We chose the main layout and passed the 'description' variable which is available in main.plates.php as $description $this->start('section name') and $this->stop() capture what is output to those sections in main.plates.php, there is no limit on sections and they can have any name aside from 'content' which is reserved. Any content that exists outside of a defined start/stop section is automatically output to the 'content' section in your layout And the image gallery: <?php namespace ProcessWire; // /site/templates/components/image_gallery.plates.php /** * @property string|null $title Optional gallery title * @property Pageimages $images Images field */ ?> <div> <?php if ($title ?? null): ?> <h3><?=$this->batch($title, 'strtolower|ucfirst')?></h3> <?php endif ?> <ul> <?php foreach ($images as $image): ?> <li> <img src="<?=$image->url?>" alt="<?=$image->description?>"> </li> <?php endforeach ?> </ul> </div> Additional notes: You can use $this->insert() in any Plates file, including layouts. You can also use $this->insert() to nest Plates templates in other Plates templates You can use batch() to execute multiple functions on a value. Any PHP function that accepts one argument (or one argument and the rest optional) can be chained in a batch. This also works with custom functions and Extension functions where you can do some really neat stuff. This is similar to functions and filters in other templating engines. The Syntax The syntax, like ProcessWire, is just PHP and has complementary style and a simple API. Plates only makes style recommendations. One of the key elements to making templates in any engine work is knowing where to put logic and where control structures should do the heavy lifting. With PageClasses and organized code, templates can be clean and concise with just PHP variables, loops, and control structures. At it's core, Plates primarily keeps focus on templates which where other engines that tend to include new syntax and tools because they already have to build a parser or interpreter. The batch() function covers a most use cases and is a welcome tool to use as is or as a complement to more custom functions and extensions. That's all you need to get started using Plates for ProcessWire. I highly recommend reviewing the short documentation to get the most out of templates in your projects. Layouts - A core templating feature for sharing page designs and base code between templates Nesting - Enhanced code reusability by inserting code blocks Inheritance - Use code sharing between templates to build more complex designs with simplicity Functions - Batching functions and writing your own Plates for ProcessWire comes with several custom build extensions for this module that may be useful. All extensions are optional and disabled by default. You can start building with the core Plates system. Extras: Plates for ProcessWire Extensions (optional) NOTE: All examples below are part of custom extensions written for this module. They can be enabled or disabled on the Plates for ProcessWire module config page, all are disabled by default. These custom extensions have full documentation that is accessible on the module config page or by reading the markdown documents directly in the module directory. This module comes with several extensions that add useful tools for building templates. Many also provide some parity with other templating solutions. Plates for ProcessWire extensions provide over 100 custom functions to use in your templates. Many of them are batchable, many of them are written to use with ProcessWire objects such as Page and WireArray/PageArray. Others are intended to make template code shorter and cleaner, others still are just nice to have. The Conditionals Extension brings some efficient output options. <!-- From our example above. Instead of this --> <?php if ($page->gallery->count()): ?> <?php $this->insert('components/image_gallery', [ 'images' => $page->gallery, 'title' => __('Image Gallery'), ]) ?> <?php endif ?> <!-- Consider this --> <?php $this->insertIf('components/image_gallery', $page->gallery->count(), [ 'images' => $page->gallery, 'title' => __('Image Gallery'), ]) ?> Tidy up single line outputs <!-- Instead of this --> <?php if ($page->text_field): ?> <h2><?=$page->text_field?></h2> <?php endif ?> <!-- Consider this. The if function accepts two argument and outputs the second if the first is truthy/falsey --> <?=$this->if($page->text_field, "<h2>{$page->text_field}</h2>")?> Conditionals also provide cleaner syntax for some control flow operations <!-- Instead of this --> <h2> <?php if ($weather === 'sunny'): ?> <?=__('Grab your sunglasses')?> <?php elseif ($weather === 'cold'): ?> <?=__('Wear a coat')?> <?php elseif ($weather === 'cold'): ?> <?=__('Bring an umbrella')?> <?php endif ?> </h2> <!-- Consider this --> <h2> <?=$this->match($weather, [ 'sunny' => __('Grab your sunglasses'), 'cold' => __('Wear a coat'), 'rainy' => __('Bring an umbrella'), ])?> </h2> <!-- When more complex evaluations are needed, consider matchTrue --> <h2> <?=$this->matchTrue([ __('Tickets are available') => $ticketCount > 10, __('Hurry, tickets are almost sold out') => $ticketCount > 1, __('Sold Out') => true, ])?> </h2> The Functions Extension provides a wide array of flexible and batchable functions <!-- Get the sum of all items in a WireArray/PageArray, associative array, or object by field/key/property, Also works on indexed arrays --> <p>Total: <?=$this->sum($page->cart_items, 'price')?></p> <!-- Group items in an associative array, array of objects, or WireArray/PageArray by property or field --> <?php foreach ($this->group($pages->get('template=players'), 'team_name')) as $teamName => $players): ?> <h2><?=$teamName?></h2> <ul> <?php foreach ($players as $player): ?> <li> <?=$player->title?><br> <?=$player->position?> </li> <?php endforeach ?> </ul> <?php endforeach ?> <!-- Get PageArrays inclusive of their parent using withChildren() Assign attributes/values if a page matches the current page using attrIfPage() --> <nav> <ul> <?php foreach ($this->withChildren('/') as $navItem): ?> <li<?=$this->attrIfPage($navItem, 'class', 'active')?>> <a href="<?=$navItem->url?>"> <?=$navItem->title?> </a> </li> <?php endforeach ?> </ul> </nav> <!-- A second argument is a selector for child pages --> <?php foreach ($this->withChildren('/', 'template=team_members') as $navItem): ?> <!-- Generate an unordered list of breadcrumbs --> <?=$this->breadcrumbs(['startPage' => '/', 'separator' => ' | ', 'ulClass' => 'breadcrumb-nav'])?> <!-- Create an indexed array with iterator from index 1 on any iterable object --> <?php foreach ($this->batch($page->images, 'toList|from1') as $i => $image): ?> <img src="<?=$image->url?>" alt="<?=$image->description?>" data-slide-index="<?=$i?>"> <?php endforeach ?> The configurable Asset Loader extension lets you link, inline, and preload assets with automatic cache busting version parameters. Directories and namespaces are customizable on the module config page and are yours to choose. <?=$this->preloadAssets([ 'fonts::ProximaNova.woff2', 'fonts::ProximaNovaLight.woff2', 'js::app.js', ])?> <?=$this->linkAsset('styles::app.css')?> <?=$this->inlineAsset('styles::critical.css')?> <?=$this->linkAsset('js::app.js')?> There are more extensions and powerful utilities. If you're a RockPageBuilder rockstar, check out the README file for details on how to use an included utility function to make Plates and RPB work together 👍 Try It Out! If you want to give it a try, download the module from the Github repository and take it for a spin. When it gets a little more testing I may submit it to the modules directory. I'm a consistent user of plain PHP, Latte, and Blade for templating and I think Plates is a great addition to the developer toolbox. Interested to hear your thoughts.
    7 points
  3. @joe_g It’s a bit of a late reply, but I pushed an update for the module which allows to extract the footnotes across all fields where the textformatter is applied to then output them wherever. Please have a look at the first post in the thread for an example.
    2 points
  4. View website: ID Studio Web Agency We have been working on the ID Studio website for quiet some time using ProcessWire extensively for ourseleves and 90% of all our clients. This post will highlight some features we have implmented and also show off some of the hidden functionality. A quick overview is as follows: Custom web design of course 🙂 Front-end uses Canvas and Three.JS The core objective for us is to get users engaged, reviewing the showcase and services, then getting in touch The showcase and blog have alot of content We hide the ID Lab and About section in the footer but there if folks want to dive in and have the time Development features include: We use the form builder system with some custom modifications 3D tools and management Linking 3D elements to HTML elements Repeater matrix for content panels and lots more, best way is to see it on the video overview below ID-Overview.mp4
    1 point
  5. I guess you meant @matjazp perhaps?
    1 point
  6. Hey @FireWire, thanks for the post! I hope you can shed some light on this for me. Personally, I’ve never used template engines. My lazy, Occam's Razor-inspired mindset has always questioned the need to add another layer of complexity—especially since it’s something else to learn. I feel similarly about CSS preprocessors. That said, regarding PHP template systems, could you elaborate a bit more on your experience with them? Also, forgive my ignorance, but do they “compete” with the markup regions in PW? Thanks!
    1 point
×
×
  • Create New...