Jump to content

A page with output formatting ON does not pass the output formatting down to values of the page reference field?


artfulrobot
 Share

Recommended Posts

I have a template with a Page Reference field on it called resources.

In my template file, I'm noting this:

$page->of(); // **true**
foreach($page->resources as $resourcePage) {
  $resourcePage->of(); // **false**
}

i.e. the output formatting is not passed down from the main $page. This surprised me, as it means - I think - that something like

<?php echo $page->resources[0]->title; ?>

would be unescaped data. Is this the designed behaviour?

Also, is there any way of setting the output formatting on the collection? e.g. so I could call

$page->resources->of(true); // ← This bit is made up/pseudocode I'm asking about
foreach ($page->resources as $resource) {
  echo $resource->title;
}

 

Link to comment
Share on other sites

First of all there is $page->of(false) and $pages->of(false). First is singular and sets OF for the single page object, second is plural and sets it globally.

Second, even if you have OF=false on a page and you echo a field's content, then you request the string value, which will automatically request the formatted value of your field:

sqydvns.png

Also if you are on the frontend and not in module development there should be OF=true by default.

  • Like 1
Link to comment
Share on other sites

Thanks @bernhard for your reply.

Front/back end: it's complex! In this situation, the front end template is being called in a back end context, by PageTableNext (PTN), to render a slice of a page in the shadow DOM.

For this reason, I don't want to interfere with the global OF setting as that could risk messing up the operation of the admin forms.

As I said, I'm experiencing OF=true for the value being rendered, but OF=false for $page->somePageRefField so I think what's happening is that the global setting will be false, but PTN is presumably setting OF=true on the page it renders, but this does not propagate down.

(string) doesn't help me - I think - because the field I'm having trouble with is an image field. But it's useful to know that PW will output-format on toString(). The image field is configured to return a single image (when OF=true) as it will only ever hold one image. However if the template receives the owner of the field with OF=false, then image fields always return an PageImages object, which breaks the template.

I think my options are:

  1. As I'm doing now: inside the render loop, do $old=$item->of(false); then do $item->of($old); at the end of my code. This means I definitely know that I'm dealing with an output formatted object.
  2. In my code set $pages->of(true). And reset that at the end. I feel uncomfortable about this somehow. I suppose I don't know what else it might affect, though it would be nice to do this outside of the field loop.
  3. Alternatively, for this specific case, I could reconfigure my image field to always return a PageImages. This impacts quite a few templates though.

I think I'll stick with the solution (1) and accept it as a quirk of PTN.

  • Like 1
Link to comment
Share on other sites

I'd go with option 4 and use $page->getFormatted('your_image_field') ? That ensures you get the formatted value no matter which state the global OF is in. And you can use the new syntax like $page->getFormatted('your_image_field.first') if you want to ensure that you get a single page image object no matter what the field settings say about the formatted value.

That means even if your field settings are changed some time by some person your script will still work.

Link to comment
Share on other sites

20 minutes ago, bernhard said:

I'd go with option 4 and use $page->getFormatted('your_image_field')

I like the idea but this means every reference to the field needs to be done this way, which is quite a lot to (a) change and (b) remember for future templates. At least with (1) I can do it once per page object. Also (1) fixes potential problems with other fields as well.

I don't think it's relevant, but I'm using Latte, too. So my loop is like this:

<li n:foreach="$downloads as $downloadPage">                  
  {var $dummy = $downloadPage->of(true)} <!-- This is the bit I wanted to avoid -->
  {include 'download-list--teaser.latte', page: $downloadPage}
</li>                                                         

Then in `download-list--teaser.latte` (wish this editor supported semantic inline code samples!) I can just use `$page->image` like normal:

{if $page->image && $page->image->width * $page->image->height < 24000000}  
  {var $thumb=$page->image->size(400, 220) }                                
{/if}
<a target=_blank href="{$page->url}" >                                      
  <article >                                                                
    <div class="meta body-text">                                            
      <h1>{$page->title|noescape}</h1>                                      
      {$page->text|noescape}                                                
    </div>                                                                  
    {ifset $thumb}                                                          
    <div class='image'><img src="{$thumb->url}" alt="{$thumb->alt}" /></div>
    {else}                                                                  
    <div class='image bg-stripey'></div>                                    
    {/ifset}                                                                
  </article>                                                                
</a>                                                                        

(I may not have all those escaping rules right yet.)

Link to comment
Share on other sites

13 minutes ago, artfulrobot said:

I like the idea but this means every reference to the field needs to be done this way, which is quite a lot to (a) change and (b) remember for future templates. At least with (1) I can do it once per page object. Also (1) fixes potential problems with other fields as well.

Sure, there are always many ways ? 

13 minutes ago, artfulrobot said:
<li n:foreach="$downloads as $downloadPage">                  
  {var $dummy = $downloadPage->of(true)} <!-- This is the bit I wanted to avoid -->
  {include 'download-list--teaser.latte', page: $downloadPage}
</li>   

If I understand correctly you could also do this:

<li n:foreach="$downloads as $downloadPage">                  
  {do $downloadPage->of(true)}
  {include 'download-list--teaser.latte', page: $downloadPage}
</li>   

 

15 minutes ago, artfulrobot said:

Then in `download-list--teaser.latte` (wish this editor supported semantic inline code samples!) I can just use `$page->image` like normal:

{if $page->image && $page->image->width * $page->image->height < 24000000}  
  {var $thumb=$page->image->size(400, 220) }                                
{/if}
<a target=_blank href="{$page->url}" >                                      
  <article >                                                                
    <div class="meta body-text">                                            
      <h1>{$page->title|noescape}</h1>                                      
      {$page->text|noescape}                                                
    </div>                                                                  
    {ifset $thumb}                                                          
    <div class='image'><img src="{$thumb->url}" alt="{$thumb->alt}" /></div>
    {else}                                                                  
    <div class='image bg-stripey'></div>                                    
    {/ifset}                                                                
  </article>                                                                
</a>

What about adding a {do $page->of(true)} at the top of this file?

  • Like 1
Link to comment
Share on other sites

Thanks again @bernhard !

I started my project without latte, then started to despise what templates looked like with raw php, and liked the look of Latte, so I added it as an aside; I have it as an api variable $latte and use it in some places but not everywhere. I'm aware there are two projects that offer to integrate Latte everywhere, but that looked a bit daunting!

I'm currently edging in the opposite direction now! Using Latte's escaping instead of PW's. So now my code is like

{do $page->of(false)} <!-- but see comment below -->
{var $i = $page->image->first}
<h2>{$page->title}</h2>
{$page->someLongBodyHTML|noescape}
<img url={$i->url} alt={$i->alt} />
...

Which means cleaner templates as I only need to use `|noescape` on HTML fields (so text formatters run).

33 minutes ago, bernhard said:

What about adding a {do $page->of(true)} at the top of this file?

I prefer to do it outside because I like the principle that a template should not have side effects. If some thing that relied on OF being either true or false but called my template to render it, and in doing so the OF got swapped, that could lead to trouble. So I prefer to pass in an object with OF correct; e.g. in my n:foreach loop I know I've got my own page that I can change OF on.

The {do ...} syntax is good though, hadn't spotted that.

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...