tpr

Module: Template Latte Replace

Recommended Posts

On 4/19/2017 at 11:14 AM, tpr said:

Just upgraded the module to v0.4.3. There's a new option to disable the "noescape" filter, and a workaround for translations on a non-multilanguage site.

The latter is a simple solution for a situation when you copy over a latte file from another project full with translations but the current project is single-language only. This is perhaps not an issue if you're using full strings for translation keys, e.g "_t('Read more')" instead "_t('read_more_text')" because the original key is returned. But even so you may start a non-English project and there you'll be in trouble :) I was there several times and ended up rewriting strings/translations all over the project, now they can remain in place and I have to add translations at one file (which you can copy over).

 

Great additions, @tpr !! The translation workaround can be also useful when you're creating a site that initially isn't multilanguage, but will be in the future, so you can add the translations strings even if the backend doesn't have the multilanguage modules setup yet.

  • Like 1

Share this post


Link to post
Share on other sites

Hey @tpr,

Thanks for the module. Switched over from Twig and really enjoying the custom filters, makes things much easier.

Just wondering about embedding a Form Builder form. As Form Builder creates a form-builder.php template which gets called via Ajax when embedded in another template, I am running into issues for obvious reasons (no .latte view file etc.).

I know there are workarounds and different form builder options, but for this use case I feel like am missing something, like the ability to bypass the view or turn latte off on a template basis. 

Thanks again.

  • Like 1

Share this post


Link to post
Share on other sites

Glad to hear that, thanks for sharing :)

Unfortunately I don't have From Builder so I'm afraid I can't tell you anything smart. Does this php file render the form html? How about using something like this? (in basic-page.php or other 'controller file', or in /site/ready.php if you have checked 'Use latte extension ... ' in module config):

$view->form = wireRenderFile('path_to/form-builder.php');

Then in .latte file use '{$form|noescape}'.

Perhaps if you could send me the contents of the php file in PM I could tell something smarter :)

  • Like 1

Share this post


Link to post
Share on other sites

How can I test template cache? I occasionally enable it and google pagespeed gives slighty better results. It works fine with ProCache though.

Share this post


Link to post
Share on other sites

v046 is just uploaded and contains a new setting for ignored templates (thanks to @mke).

Make sure to save the module after the update to apply the defaults.

  • Like 2

Share this post


Link to post
Share on other sites

My problem from above, which was that Form Builder's form-builder.php template needed to be ignored by latte is now resolved.

Tested the update and all working fine. Thanks @tpr!

  • Like 2

Share this post


Link to post
Share on other sites

In v048 there's a new filter called group. This allows creating groups from a PageArray based on a page field value. I will probably further polish it later when I will use it in more projects but I think it's a nice time saver.

{foreach ($page->children()->sort('sort')|group:'section') as $group}
...

The filter just saved my *** from re-writing a thing to use Repeaters instead using child pages. It was much easier and fun to create the filter :) 

  • Like 1

Share this post


Link to post
Share on other sites

Some new filters in v049 (eg. srcset) and an easy way to clear Latte cache by appending ?clearcache to the URL.

I've added a sidebar to the GitHub wiki so filters and macros are more easier to find.

 

  • Like 1

Share this post


Link to post
Share on other sites

Latest version is 0.5.1, which contiains Latte 3.0.0-dev, which means the module requires PHP 7 from now on.

A new savetemp filter was added in v0.5 that allows saving temporary data. This can be handy eg. when creating an image variation in a src attribute, and would like to add a width/height attribute with the resized image data.

Before savetemp you had to save the resized image to a variable first and use this variable in src/width/height attributes, now you can do it much simpler. You could use the "iff" or "setvar" macros too but savetemp is only a matter of adding "|savetemp" where you need it (even inside a filter chain).

  • Like 1

Share this post


Link to post
Share on other sites

In the latest v0.5.5 there's a new optionchecked filter. I usually have a tough time when I have to check whether a Select options field has a given option checked/selected, so this filter is about simplify this. I've decided to use a "dot notation" because it makes things easier to read imo.

The filter accepts the id, value and title too:

// 3=show_header|Show header

{if ($page|optionchecked:'page_options.3')} ... {/if}

{if ($page|optionchecked:'page_options.show_header')} ... {/if}

{if ($page|optionchecked:'page_options.Show header')} ... {/if}

 

  • Like 1

Share this post


Link to post
Share on other sites

Is there no easy way to change the delimiters? Having a hard time with Vue in my template where it’s conflicting inside class bindings. Turning the syntax off is obviously not a good solution...

i’ve tried using getParser()->setDelimiters(left, right), but it must be too late in the lifecycle for it to be effective, because it still says the macro is unknown.

Edit: Got it working…

$view->latte->getParser()->syntaxes['latte'] = ["\{\@(?![\s'\"{}])", '\}'];

 

Edited by Mike Rockett
working :-)

Share this post


Link to post
Share on other sites
On 1/8/2018 at 2:38 PM, Mike Rockett said:

Is there no easy way to change the delimiters?

Sorry @Mike Rockett I completely missed your post. Was your goal to use another syntax instead of "{}"? If so, latte supports syntax switching but I guess you already know that:

https://latte.nette.org/en/macros#toc-syntax-switching

So you can simply add this:

<script n:syntax="double">
    var obj = {var: 123};
</script>

Their docs says there are "asp", "python" syntaxes but those were removed long ago (just found out myself too though I've noticed it earlier that didn't work).

However there's a trick: leave spaces between the delimiters and you're good to go. So in Vue use "{{ myVar|myFilter }}".

  • Like 1

Share this post


Link to post
Share on other sites

There are two new macros in v058: ifstatus and ifloggedin.

The former allows checking page status easily and it's quite powerful:

{ifstatus $servicesPage, array('!hidden', '!locked')}
    <p>The services page is not hidden nor locked.</p>
{else}
    <p>The services page is locked or hidden.</p>
{/ifstatus}

($servicesPage is a Page object but it would work with only supplying its ID)

Sometimes I need such checks but it was inconvenient to do such checks in the view file, eg like this:

{if !$servicesPage->is(\ProcessWire\Page::statusUnpublished)}

Macro ifloggedin doesn't need too much explanation I guess :) 

Share this post


Link to post
Share on other sites
On 05/04/2018 at 9:47 PM, tpr said:

Sorry @Mike Rockett I completely missed your post. Was your goal to use another syntax instead of "{}"? If so, latte supports syntax switching but I guess you already know that:

https://latte.nette.org/en/macros#toc-syntax-switching

So you can simply add this:


<script n:syntax="double">
    var obj = {var: 123};
</script>

Their docs says there are "asp", "python" syntaxes but those were removed long ago (just found out myself too though I've noticed it earlier that didn't work).

However there's a trick: leave spaces between the delimiters and you're good to go. So in Vue use "{{ myVar|myFilter }}".

No problem, and thanks. I'm going to stick with my original solution as I need it to only be set once... This also gives a level of customisation, which I like.

🙂

Share this post


Link to post
Share on other sites

I've added a new filter called replacesubs that allows adding placeholders in format ((name)) to fields, and then use an array or a textarea content to fill them with values.

You can apply it to a field content and all available placeholders will be replaced. Unlike getlines you can add new placeholders and data sources at any time, no need to touch the code. Plus you / your client can add HTML and formatting to them in the CKEditor.

  • Like 1

Share this post


Link to post
Share on other sites

I've created a new documentation page with docsify. I was about to ship standalone markdown files with the module so they could be versioned and read through GitHub (or somehow else). Then I looked at @adrian's docs for Tracy and I liked it, especially the search feature, so I decided to go that route.

The next release will contain a major rewrite for filters and macros. They contribute largely to the module's robustness (imo) and I wanted these functions to be available separately too. So there's a new "PWHelpers" class (name is not final) that contains methods that filters and macros are using. This means you can include this class in your non-latte PW projects too and use them if you wish.

Another motivation was to make these functions testable which was not possible without this change. I wrote tests for almost every filter and macro. I spent significant time to it (testing is fun :)) and have fixed many bugs. Of course this doesn't mean they are bug-free but they are much safer to use and when a new feature is added I can easily check if everything works as expected (using ProcessNetteTester btw). 

I was thinking about making this class a separate module but I kept it inside TemplateLatteReplace for now, but I can change this later if there's a need.

  • Like 4

Share this post


Link to post
Share on other sites

Thanks for this and all your other work on the module. I'm in the process of converting sites from Clipper (MODX Evolution fork), and find that Latte has just the right level of intelligent templating for me. Together with the Processwire API, it means I've been able to replicate pages without constant hopping in and out of PHP and, so far, without having to write a single database query.

KP

  • Like 2

Share this post


Link to post
Share on other sites

Nice to hear that, thanks. As I wrote the additional filters will be modified a lot in the next release so if you use them a lot then updating will be harder. I try to release it in about two weeks but as always, time is not on my side 🙂

  • Like 1

Share this post


Link to post
Share on other sites

Hey @tpr, I think I've found a bug.

One of my pages was returning a black page and no error on debug/tracy. Data was passing fine.

After 10 min trying several things here, like removing the template php file to test the error etc and nothing happened. The file was named pdf_report_pdf.latte and it was loaded by another template via viewFile method. 

I then went back to the module config and remove a "pdf" (just "pdf) from the list of templates to ignore as I have another template called pdf.php and voilà, the error was gone. So, I'm guessing you do a regex on the ignore list entries? Was that the problem?

Share this post


Link to post
Share on other sites
4 hours ago, tpr said:

I think the problem is the strpos function. It will return true for "pdf" in "report_pdf" for instance. But we need to return true only if it's an exact match. So, what about this:

foreach ($ignoredTemplates as $t) {
  if (preg_match('/\b'.trim($t).'\b/',$templateFile->filename)) {              
  	return;
  }
}

I tested it here and it works.

Share this post


Link to post
Share on other sites

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 Sebi
      I've created a small module which lets you define a timestamp after which a page should be accessible. In addition you can define a timestamp when the release should end and the page should not be accessable any more.
      Github: https://github.com/Sebiworld/PageAccessReleasetime
      Usage
      PageAccessReleasetime can be installed like every other module in ProcessWire. Check the following guide for detailed information: How-To Install or Uninstall Modules
      After that, you will find checkboxes for activating the releasetime-fields at the settings-tab of each page. You don't need to add the fields to your templates manually.
      Check e.g. the checkbox "Activate Releasetime from?" and fill in a date in the future. The page will not be accessable for your users until the given date is reached.
      If you have $config->pagefileSecure = true, the module will protect files of unreleased pages as well.
      How it works
      This module hooks into Page::viewable to prevent users to access unreleased pages:
      public function hookPageViewable($event) { $page = $event->object; $viewable = $event->return; if($viewable){ // If the page would be viewable, additionally check Releasetime and User-Permission $viewable = $this->canUserSee($page); } $event->return = $viewable; } To prevent access to the files of unreleased pages, we hook into Page::isPublic and ProcessPageView::sendFile.
      public function hookPageIsPublic($e) { $page = $e->object; if($e->return && $this->isReleaseTimeSet($page)) { $e->return = false; } } The site/assets/files/ directory of pages, which isPublic() returns false, will get a '-' as prefix. This indicates ProcessWire (with activated $config->pagefileSecure) to check the file's permissions via PHP before delivering it to the client.
      The check wether a not-public file should be accessable happens in ProcessPageView::sendFile. We throw an 404 Exception if the current user must not see the file.
      public function hookProcessPageViewSendFile($e) { $page = $e->arguments[0]; if(!$this->canUserSee($page)) { throw new Wire404Exception('File not found'); } } Additionally we hook into ProcessPageEdit::buildForm to add the PageAccessReleasetime fields to each page and move them to the settings tab.
      Limitations
      In the current version, releasetime-protected pages will appear in wire('pages')->find() queries. If you want to display a list of pages, where pages could be releasetime-protected, you should double-check with $page->viewable() wether the page can be accessed. $page->viewable() returns false, if the page is not released yet.
      If you have an idea how unreleased pages can be filtered out of ProcessWire selector queries, feel free to write an issue, comment or make a pull request!
    • By David Karich
      Thanks to the great Pro module "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 this module on a different page (e.g. in the same design), you have to rebuild each item manually every time.
      With this proof of concept I have created a module which adds the feature to copy a repeater item to the clipboard so that you can paste this item to another page with the same repeater field. The module has been developed very rudimentarily so far. It is currently not possible to copy nested items. There is also no check of Min/Max. You can also only copy items that have the same field on different pages. And surely you can solve all this more elegantly with AJAX. But personally I lack the deeper understanding of the repeaters. Also missing on the Javascript side are event triggers for the repeaters, which would make it easier. Like e.g. RepeaterItemInitReady or similar.
      it would be great if @ryan would implement this functionality in the core of RepeaterMatrix. I think he has better ways to implement this. Or what do you think, Ryan?
      Everybody is welcome to work on this module and improve it, if it should not be integrated into the matrix core. Therefore I put it for testing and as download on GitHub: https://github.com/FlipZoomMedia/InputfieldRepeaterMatrixDublicate
      You can best see the functionality in the screencast: 
       
    • By anderson
      Hi,
      Please take a look at this:
      https://templatemag.com/demo/Good/
      The upper nav bar, including dropdowns like "pages" and "portfolios", what do you call this whole thing? At first I guess it's called "dropdown nav bar", but seems not.
      AND of course, what's the simplest way/module to achieve this in PW?
      Thanks in advance.
    • By Sebi2020
      Hey, I'm new and I created a simple module for tagging pages because I didn't found a module for it (sadly this is not a core feature). This module is licensed under the GPL3 and cames with absolutly no warranty at all. You should test the module before using it in production environments. Currently it's an alpha release. if you like the module or have ideas for improvements feel free to post a comment. Currently this fieldtype is only compatible with the Inputfield I've created to because I haven't found  an Inputfield yet, that returns arrays from a single html input.
      Greetings Sebi2020
      FieldtypeTags.zip.asc
      InputfieldTagify.zip
      InputfieldTagify.zip.asc
      FieldtypeTags.zip
    • By psy
      Background
      I'm creating a module to integrate https://pushalert.co/ into ProcessWire. You actually don't even need a module. You could just use the "Other Websites" javascript provided by PushAlert for basic functionality, ie send a broadcast notification to all subscribers. This is essentially what all the other integrations, including WordPress, do. The WP integration installs a widget with a form enabling the admin to enter details such as title, message, etc from a blog post. It does not:
      collect any statistics within the CMS about the notification enable audience fine tuning to eg a particular subscriber or subscriber segment within WP. The admin needs to use the PA dashboard for that functionality PushAlert has a javascript and REST API. It's intended that this module will use both. https://pushalert.co/documentation 
      What my module does so far:
      associate a subscription with a user. FE user clicks a button on the website front end to subscribe and/or agrees to the browser popup to accept notifications from this site send broadcast push alerts from a page within admin It doesn't have a 'widget' but easy enough to create a fieldsetpage with the relevant fields and add that fs page to any appropriate templates, then with a hook, send the notification. Need to be careful that once published/sent, the notification is not automatically re-sent on subsequent page edits.
      Looking for help/collaboration on how best:
      to send a notification, eg from a blog post, then track the statistics. Dilemma is that the push notification must come from the admin page. Responses go to the sending page which, as it's an admin page, is restricted and will not accept the https response. This is where the other CMS integrations stop. The only json response from PushAlert is the status, eg 'success', and the notification id. There is no opportunity at this point to capture the sending page id. handle, 'once sent on page publish', do not automatically resend on future page edits Am thinking along the lines that FS Page will have a @kongondo runtime markup field https://modules.processwire.com/modules/fieldtype-runtime-markup/ to pull the stats from PushAlert. Every time an admin visits the page, the stats will update.
      Once an admin checks the 'Send notification on page publish' checkbox, a hook creates new front end page that records the 'sender page', sends the notification request to PA, which then uses that newly created frontend page, as the response endpoint. Another rook re-associates the front end page with the admin page (eg blog post), to update the stats.
      Potential use cases:
      Notify individual and/or users with a particular role of an event, eg "New work opportunity" for job seekers; new blog post published; entries now open, etc...
      Looking for help/ideas/collaboration on this module. Please let me know if you're interested and as I do, believe this would be a great addition to ProcessWire