Violet

Is this template file structure an OK practice in terms of variable-passing?

Recommended Posts

I originally created my template files thinking I'd only ever need 3 and not worrying about if I repeated bunches of common code there (yes, bad practice, I know). I figured I'd just manually/copy-paste to change any common code in all 3 as needed. So of course, fast-forward awhile, and I'm now up to 6 template files with possibly a few more to come, and decided it was high time I made the switch to keep the common parts in their own unique files for ease of editing. So I therefore went back and read Ryan Cramer's tutorial "How to Structure Your Template Files".

OK. I tried out the "includes" command mentioned in the tutorial on a test template. The resultant web page physically functions as expected, but my question here is, "Is the practice I'm showing below OK in terms of variable usage?" If not, what approach should I be using? 

I've tested it out and the variables do populate as expected in the final result, but is it OK for me to do it like this or is there the chance that some of the variables won't be passed properly?

Here is what I  mean (only the relevant portions of code shown to illustrate):

...
<aside> 
  <h3>Three Random Posts</h3>
<!-- get the list, then display it -->
<?php
$itempages = $pages->find("template=my-post");
$shortlist = $itempages->getRandom(3);
$shortlist->shuffle();
$itempagezero = $shortlist->eq(0);
$itempage1 = $shortlist->eq(1);
$itempage2 = $shortlist->eq(2);
?>
<?php include("./INC_displaylist.php"); ?>
</aside>
<?php include("./INC_footer.php"); ?>
</body>
</html>


The possible issue here is that the INC_displaylist.php file outputs field data from $itempagezero, $itempage1, and $itempage2. Is that OK? I wanted to split the variable assignments and the output separately. This is because, based on the exact template I'm using, I will sometimes choose to populate $itempages via different selectors in the $pages->find command in different template files, although all templates will display an identically-formatted list of 3.

By contrast, I wouldn't expect any variable issues with including the INC_footer.php file as shown above, since I'm not using any variables in the footer that aren't first referenced in that same footer.

So am I doing it OK here or should I be populating these variables somewhere else to ensure they're recognized properly by INC_displaylist.php? If I need to do it somewhere else, where should I populate these?

Share this post


Link to post
Share on other sites

Hi @Violet

This should work fine. What I'd do is make the path:

/site/templates/includes/displaylist.php

and link to it with:

<?php include(".includes/displaylist.php"); ?>

Do you need an include file though? I mean, is it that big or complex? If the list is just the linked titles, you could (not tested):

<aside> 
  <h3>Three Random Posts</h3>
<!-- get the list, then display it -->

<?php
  // can chain the methods, first part returns an array with all pages
  // created with 'my-post'. Second part, gets random x 3 from first array
  // and returns a new array, which is then shuffled and saved to $itempages
  $itempages = $pages->find("template=my-post")->getRandom(3)->shuffle();
  
  // if items are actually returned
  if (count($itempages)):
  ?>

  <ul>

  <?php
  // loop over them
  foreach ($itempages as $itempage): ?>

  <h4><?= $itempage->title; ?></h4>
  
  <?php endforeach; ?>
  
  </ul>

  <?php else: ?>

    <p>No posts found :(</p>

  <?php endif; ?>
</aside>

...or you could do it with an include:

<aside> 
  <h3>Three Random Posts</h3>
<!-- get the list, then display it -->

<?php
  // can chain the methods, first part returns an array with all pages
  // created with 'my-post'. Second part, gets random x 3 from first array
  // and returns a new array, which is then shuffled and saved to $itempages
  $itempages = $pages->find("template=my-post")->getRandom(3)->shuffle();
  
  // if items are actually returned
  if (count($itempages)):
  ?>

  <ul>

  <?php
  // loop over them
  foreach ($itempages as $itempage): ?>

   <?php include("./includes/displaylist") ;?>
  
  <?php endforeach; ?>
  
  </ul>

  <?php else: ?>

    <p>No posts found :(</p>

  <?php endif; ?>
</aside>

and displaylist.php like:

<?php namespace ProcessWire;
// caveat being that the variable MUST be called '$itempage' here
?>

<h4><?= $itempage->title; ?></h4>

<?= $itempage->summary; ?>

<?= $itempage->whatever; ?>

It's up to you really :)

==EDIT==

I am unsure by your example if you need different fields from each page $itempagezero, $itempage1 and $itempage2. Would need to see the contents of INC_displaylist.php. You did mention 'all templates will display an identically-formatted list of 3.'.

==EDIT 2==

Can I just clarify something. You can also use wireIncludeFile() function which is awesomer (is that a word?) than the standard include because you can pass variables INTO the template. The standard include above is simply used 'as if it were typed directly into the containing template'. This is just another approach.

<aside> 
  <h3>Three Random Posts</h3>

  <?php
    $itempages = $pages->find("template=my-post")->getRandom(3)->shuffle();

    if (count($itempages)) {
      // include the file and pass the pages into it
      wireIncludeFile("./includes/displayist.php", array('mypages' => $itempages));
    }
  ?>

  <h3>Newest 5 Posts</h3>

  <?php
    $itempages = $pages->find("template=my-post, limit=5, sort=created");

    if (count($itempages)) {
      // include the file and pass the pages into it
      wireIncludeFile("./includes/displayist.php", array('mypages' => $itempages));
    }
  ?>

</aside>

and displaylist.php

<?php namespace ProcessWire; ?>

<ul>

  <?php
  // loop over the value/s of the 'mypages' array key
  foreach ($mypages as $itempage): ?>

   <li><a href="<?= $itempage->url; ?>"><?= $itempage->title; ?></a></li>
  
  <?php endforeach; ?>
  
</ul>

There's just so many ways. I haven't tested this one either but you get the idea.

You can see why people here (and myself) love the flexibility processwire provides! :) you can arrange your templates any way you want, whatever makes sense to you.

  • Thanks 1

Share this post


Link to post
Share on other sites

Hi @SamC thanks so much for your very helpful and thorough reply. I went through your code for your two different examples. Thanks, I think I see what you're saying here. Upon reflection, I think I have something more like your second method in mind, mainly because I have a fair amount of fields to output from the post list and a fair amount of styling going on in there. Therefore if I decide I want to later add in and display an extra field for each item in the list of 3 in the <aside> section (this is in fact exactly what happened yesterday), I just want to edit ONE file (the one called by "include") and not every single one of my template files.

Also, sorry if I inadvertently made my wording confusing in the original post. Oops :blush:. When I said "all templates will display an identically-formatted list of 3", I did not mean that all 3 items will be displayed identically to EACH OTHER. This is why I did not loop. I just meant that the layout of the 3 will not change between templates. So, for example the first post title might be displayed with full-width photo, publication date, and with an excerpt. Posts 2 and 3 might be displayed below that but next to each other (one on left other on right), with title and just thumbnail pic, no excerpt. Still tinkering with my design layout, but ultimately I want the final layout and final fields of the <aside> section to be the same on all my different templates (e.g. post 1 details always shown full-width; posts 2 and 3 always displayed below next to each other). So that's why I was wanting to use include.

My displaylist.php basically looks a lot like your example, but with lots of styling and with separate display of each of the 3 post fields.

IMPORTANT QUESTION: Your example showed I was supposed to begin the file displaylist.php with: 

<?php namespace ProcessWire;
?>

 

The file calling it i.e. the code from my template file I gave at the start (currently called _temptest.php ) ALSO starts with that:

<?php namespace ProcessWire; ?>
<!DOCTYPE html>
<html lang="en">
<head>
  ....

So to clarify, do I still need to specify "namespace ProcessWire" in file displaylist.php even though file _temptest.php (which calls displaylist.php) starts with the same thing? And thanks again for all the help you've given me above. I really appreciate it.

Share this post


Link to post
Share on other sites

Haven't thoroughly read everything written above. Quick suggestions:

$config is your friend

For paths, (and other stuff), $config is your friend. Rather than entering paths yourself, let it to the donkey work. For instance, if you have an includes folder in /site/templates/includes/  you can get to that easily using:

$path = $config->paths->templates . 'includes/';

Delayed Output

If you are not already, I recommend you use this approach. Makes it easy to pass and change variables if needed. See the Automatic Inclusions section (the $config->prependTemplateFile). Your files do not have to be named .inc. They could be .php or even .tpl.

 

  • Like 2

Share this post


Link to post
Share on other sites
Just now, Violet said:

So to clarify, do I still need to specify "namespace ProcessWire" in file displaylist.php even though file _temptest.php (which calls displaylist.php) starts with the same thing?

Not 100% sure, let me test... when I remove the namespace from one of my includes I get...

Fatal error: Uncaught Error: Call to undefined function renderTags()

What I do (maybe unnecessarily) is just paste that line at the top of every template. it fixes my errors anyway.

I believe it's to do with the compiling of the files Admin > Setup > Templates > Files (tab) and using 3rd party PHP libraries so variables don't collide. I'm no PHP expert so don't quote me on this!

Just now, kongondo said:

Delayed Output

If you are not already, I recommend you use this approach.

I'm thinking of going this way myself, or at least the new template strategy. Things are getting a little weird with includes, especially my header which changes depending on what template is loaded. Got some funky logic in an include file right now that just doesn't feel right.

What puts me off is all the HTML in strings in terms of syntax autocomplete/highlighting in ST3.

  • Like 1

Share this post


Link to post
Share on other sites

Thanks to both of you for the updates. 

@kongondo , the $config is a good idea,I will replace my paths on the "include" with that. Valuable info.

You also mentioned I should consider delayed output. When reading up about it, I came to the conclusion that I'd have to sit around and do a lot of concatenating of strings every time I create a new template file. I'm new to ProcessWire, so maybe I've gotten it wrong, but I just don't like the general idea that I have to pre-define every output I want to make as a string first, instead of just using variables here there and everywhere on the fly as I update/change my templates (the latter is what I love about ProcessWire).

I will think about all this. In the meantime, will change my paths to $config ones.

@SamC , thank you SO MUCH for going to all the trouble to actually test out the namespace on the "include" files. While my setup was working fine without the namespace, I'm DEFINITELY heeding your warning that depending what you have going on in your files, omitting the namespace may lead to errors. As you say, it can't hurt to put it in. I'll change my files around to add those in. Thanks so much!

14 hours ago, SamC said:

Things are getting a little weird with includes, especially my header which changes depending on what template is loaded.

What you said above about the limitations of the "includes" method was very valuable too. Hmm.

Thanks also for the link to the new template strategy; this was extremely helpful as it was not mentioned in the tutorial that I had read in my first post (why??). I'm not certain if the new template strategy is ultimately what I'm looking for; I'll have to think about that carefully. The reason is my template is heavily CSS-based, and I'm not a big fan of using classes like pw-append and pw-prepend. I can see how on the one hand the new system would allow flexibility when using different templates on a site; on the other I don't like the notion of using classes that aren't defined in my stylesheet. I realize ProcessWire handles those tags itself; I just don't like it from an ideological point of view more so than a practical point of view. Plus, I don't want the pw classes to be at war with either my classes or my screen reader strategy. Perhaps it wouldn't clash, but it still doesn't seem like the most readable templating method to me.

I read your second edit, and I was beyond thrilled!

16 hours ago, SamC said:

You can also use wireIncludeFile() function which is awesomer (is that a word?) than the standard include because you can pass variables INTO the template.

I think this is what I might go with! It sounds like exactly what I need. I will try it out. This is hugely valuable info thanks.

 

Share this post


Link to post
Share on other sites
21 minutes ago, Violet said:

When reading up about it, I came to the conclusion that I'd have to sit around and do a lot of concatenating of strings every time I create a new template file.

I think you must have misunderstood the tutorial.

 

22 minutes ago, Violet said:

I don't want the pw classes to be at war with either my classes or my screen reader strategy.

The pw-* classes are just placeholder tags that ProcessWire parses at render. They are removed in the final markup. There's a very tiny note about it on that page (I'm not sure why it had to be a note and not just in the text proper :)) just above Benefits and drawbacks section.

Quote

Note: after being processed, the “pw-” classes above are removed from the HTML tags automatically by ProcessWire.

 

  • Like 2

Share this post


Link to post
Share on other sites
21 minutes ago, Violet said:

You also mentioned I should consider delayed output. When reading up about it, I came to the conclusion that I'd have to sit around and do a lot of concatenating of strings every time I create a new template file. I'm new to ProcessWire, so maybe I've gotten it wrong, but I just don't like the general idea that I have to pre-define every output I want to make as a string first, instead of just using variables here there and everywhere on the fly as I update/change my templates (the latter is what I love about ProcessWire).

Hi,

I have not read the whole thread but I think Ryan's delayed output with all those concatenating stuff is not for everyone, normally I do not use it either. I have a hybrid approach of using all sorts of possibilities which is rather long to explain but maybe one day I have the time to do a write up on it in my own blog.

The most important thing is that most of the time I use <?php include __DIR__ . '/../path/to/file.php'; ?> but there is something to keep in mind: http://yagudaev.com/posts/resolving-php-relative-path-problem/

Using PHP's own include() and its variants has the advantage of being able to access all the variables you need during the rendering process without doing much extra "work". It works well for not too "convoluted" frontends. Yet, more sophisticated approaches might be required in other cases but for just starting with ProcessWire you will probably not need more than this for quite a while.

Note that PHP is a native template engine, at least Rasmus Lerdorf says so:

I do something similar. Early in the rendering process I implement the "business logic" and store stuff in variables which can be outputted and/or tested later in the native Rasmus's style code part generating the actual output. This way most code editors can auto format, syntax highlight, intellisense, etc... your HTML code.

Concatenated code is hard to read to say the least. Some IDEs deal with it well – e.g. PHPStorm (which is not free) – but still...

  • Like 1

Share this post


Link to post
Share on other sites

The following topic is old and some of the stuff is probably out of date but well worth reading.

 

  • Like 3

Share this post


Link to post
Share on other sites

Thanks for all of the additional info, @kongondo. And the delegate approach sounds interesting. It could be a good way to do it when there are some similar-ish templates, which is the case for 2 of my current 6 templates. So it could be a strategy to incorporate into those. However I'm not sure that I would want to do it for everything I'm using, because (correct me if I'm wrong), in that case I'd wind up using 1 template file with a bunch of conditional statements referring to 6 different templates. This, while elegant coding-wise, would surely have a little drawback in readability, at least to me. I might have misunderstood as I am still a newbie, sorry. I'm still very much trying to get to grips with everything and get my head around everything. In any case, I might incorporate this delegate approach for the more similar of my templates where there wouldn't be too many conditional statements. I'm glad that everyone has given me so many different templating strategies to choose from here. 

@szabesz - thanks, so glad for the warning and for the link to the info about relative paths! Actually I had wondered about that, which was one of the reasons I'd kept my inc files in the same directory as my template files. My own naming convention for my inc files is INC_filenamehere.php , since my editor handles the .php files well, but won't recognize a .inc the same way, and I don't like editing plain text. I like the markup and things to be in different colors like they are on .php files. (Yes I know I can probably change the editor settings to recognize .inc files but I'd prefer to instead go for a filename convention that works for me personally). Plus having inc files start with INC_ means they are all grouped together alphabetically in my template directory anyway. I will update my paths using $config, just as kongondo recommended, so that this way I can ensure that the path is specified explicitly to sidestep the whole problem altogether. Thanks, I read the other 2 articles you linked to also, very helpful info when thinking about templating strategies.

2 hours ago, szabesz said:

Early in the rendering process I implement the "business logic" and store stuff in variables which can be outputted and/or tested later in the native Rasmus's style code part generating the actual output.

Thanks, it's helpful to get ideas of how people are doing it for their own sites.

All of this discussion has forced me to think about what's most important to me when templating. It's probably readability and layout.  In other words, I need to be able to come back to my templates 6 months from now, and if there's a change I want to make on the page (whether it's displaying a new field or changing some of the styling), I want to be able to do it as quickly as possible without needing to track stuff down much. Parts of my templates can be busy, especially when I have a bunch of nested divs etc with different classes, but it seems to be the main way that makes sense to me while still functioning responsively. Anyway this has given me lots to think about and it's helped highlight to me that there are lots of different possible templating approaches due to the flexibility of ProcessWire. It's not even restricted to only the methods mentioned in the tutorial I had first read. I really appreciate all the help I've received here from everyone.

  • Like 3

Share this post


Link to post
Share on other sites
2 hours ago, kongondo said:

The following topic is old and some of the stuff is probably out of date but well worth reading.

 

I have used this approach for the past 4 sites.

Now I'm considering other options though. Things like this though...

<?php
$headline = $page->get("headline|title");

// bodycopy is body text plus comments
$bodycopy = $page->body . $page->comments->render();
$sidebar = $page->sidebar;

// check if this page has any children
if(count($page->children)) {
  // render sub-navigation in sidebar
  $sidebar .= "<ul class='nav'>";
  foreach($page->children as $child) {
    $sidebar .= "<li><a href='$child->url'>$child->title</a></li>";
  }
  $sidebar .= "</ul>";
}

include("./main.inc"); 

...makes me think a few things:

1) Having to make strings out of all my HTML is a royal pita.

2) No autocomplete for HTML tags in ST3 when pretty much everything is chucked into strings.

3) However, this is easier to read than some of the the alternate syntax I'm using i.e. when there's a bunch of if/else, inside a loop, maybe a second loop, then the alternate syntax I also find a pita.

4) I like the idea of being able to pre-populate things, then just render them out later depending on which template is loaded. Makes a fair bit of sense.

So, it seems I'm unpleasable :P good news is, whatever approach you take @Violet you've got a forum full of incredible help here.

  • Like 1

Share this post


Link to post
Share on other sites

wow, did'nt read all the answers, but it seems nobody mentioned markup regions anywhere? soma's post is a must-read of course, but it's also from 2011 and we now have the same functionality a lot easier and cleaner imho: https://processwire.com/blog/posts/processwire-3.0.62-and-more-on-markup-regions/

a simple setup could be:

_main.php

<html>
  <head>
    <!-- scripts&co -->
  </head>
  <body>
    <section id="header">your header, menu or the like...</section>
    
    <region id="main"></region>
    
    <section id="footer">your footer</section>
  </body>
</html>

home.php (really no other markup than this in this file!)

<section id="main">
  <h1>Welcome to my website!</h1>
  <p>This is the awesome text of my awesome website</p>
</section>

blogitem.php (for example)

<section id="main">
  <h1>Blog Item <?= $page->title ?></h1>
  
  <?= $page->body ?>
  
  <ul>
  <?php
  $page->siblings("id!=$page")->each(function($p) {
	echo "<li><a href='{$p->url}'>{$p->title}</a></li>";
  }
  ?>
  </ul>
</section>

This will render your website with header and footer, inject scripts on all sites and just change the content of the main section on your pages.

  • Like 3
  • Thanks 1

Share this post


Link to post
Share on other sites

I just made a copy of my templates folder, renamed the copy 'templates.delegate' and now in the process of trying out the new markup regions to see how it suits me. Thanks for the newer link @bernhard

Having:

<region id="main"></region>

replaced by:

<section id="main">
  <h1>Welcome to my website!</h1>
  <p>This is the awesome text of my awesome website</p>
</section>

(EDIT - the section tags are not printed)

reminds me a bit of extending in twig, where you could:

// master template
<div id="content">{% block content %}{% endblock %}</div>

and then in the child template:

{% extends "base.html" %}

{% block content %}
    <h1>Index</h1>
    <p class="important">
        Welcome on my awesome homepage.
    </p>
{% endblock %}

Not paid a great deal of attention to this approach but I like the look of it.

  • Like 2

Share this post


Link to post
Share on other sites

i haven't used markup regions on larger projects. ryan said its a little more overhead. but for smaller projects imho it is the cleanest and easiest solution. i think its much easier to understand for newcomers than the regular delayed output. it was also great to work together with my designer :) 

  • Like 2

Share this post


Link to post
Share on other sites

I wonder how much overhead? What is considered 'large amounts of markup' as quoted from your link?

Your second point is interesting. If this approach is easy for web designers (or developers) to understand, this may help in the convincing of clients that anyone would be able to take over the site in the future because the template structure is so intuitive/straight forward.

 

  • Like 1

Share this post


Link to post
Share on other sites

@bernhard - Thank you for your awesome example! Yes, Sam had posted a link to the 3.0.49 post, but it was good to also see the updated 3.0.62 version of markup regions. The thing that made a huge difference to me was your code example. Your sample code here was MUCH easier for me to understand as a newcomer than the examples given in both of the official markup regions posts. If there are any other newcomers who are thinking of using markup regions, I strongly recommend bernhard's earlier reply above. It allowed me to see more easily how this would indeed help solve the general problem of having common bits of code.

The advantage over the "includes" method is that the main layout code is in one place. In other words, I could therefore edit header and footer for all pages from the same file ( _main.php in your example), and I can see layout at a glance. High readability and ease of editing. I see I could add to _main.php all possible region ID's used in all templates; only the ones used by the specific template in use will get populated. So, it's pretty tidy, and you can get a feel straight away for what sorts of things all of your templates are likely to be doing, just by looking at _main.php. The main disadvantage I see is that I'm not sure what I would do if I ever created a page template that (for example) I did not want to include a footer on. Sure, that's unlikely to happen, but I'm not sure how I'd handle that using markup regions if it occurred. I expect there must be a way to do that, it's just not obvious to me.

@SamC thanks for updating and also for mentioning the methods you are using. It is really great for me to have all of this info here from everyone all in one place. 

Share this post


Link to post
Share on other sites
26 minutes ago, Violet said:

The main disadvantage I see is that I'm not sure what I would do if I ever created a page template that (for example) I did not want to include a footer on.

You're in luck because I just tried this.

// _main.php
<region id="header">HEADER</region>

<region id="main"></region>

<region id="footer">THIS IS MY FOOTER</region>

...and a template:

// basic-page.php (used to make the /about/ page)
<?php namespace ProcessWire; ?>

<region id="header"></region>

<region id="main">
  <div class="container py-5">
  <div class="row justify-content-center">
    <div class="col-md-8">
      <?= $page->body; ?>
    </div>
  </div>
</div>
</region>

<region id="footer"></region>

Then on a page made with the basic-page template. The header and footer are hidden completely (from view and source).

  • Thanks 1

Share this post


Link to post
Share on other sites

Oooh awesome!! I can see how that would work but I would never have thought of it myself. Thanks @SamC! I really appreciate you trying that out. I'm leaning toward using markup regions now.

One question, if anyone is willing to comment: using "markup regions" vs using "includes" - which of those two would you expect to be faster to render? And are there any conditions / caveats which favor one better than the other as far as speed alone is concerned? 

I know it said that markup regions can take a bit longer if you're outputting a lot of markup, but how do I know if I have a lot of markup? Also, wouldn't "includes" be considered an extra step just like "markup regions", so how do we know which one of these two would be faster for PW to render? I know there's most likely no hard-and-fast rule here, but I'm seeking some general thoughts about which conditions might favor one vs the other speed-wise. 

Share this post


Link to post
Share on other sites

I think includes() would be faster because it is a function built into php. It's like whatever's in the include file is simply written right into the page. The markup regions have to be processed by PW first to see what goes where, then put it all together for final output.

I'm not convinced on markup regions tbh. I'm just not getting how you dynamically change just parts of the regions instead of having to define what goes in the entire region in every template. Maybe just tired! I'll carry on tomorrow.

  • Like 1

Share this post


Link to post
Share on other sites

@SamC what are you trying to do exactly? 

Like always in PW it's up to you. Just wanted to mention markup regions because I didn't see anybody mentioned them. If others are happier with using includes that's totally fine :)

Ps: if performance is a factor for you the best you can do is to invest some euros and 3 minutes to download and install procache. No matter what technique you are using for generating the output, procache will make it lightning fast even on slow servers ;)

  • Like 1

Share this post


Link to post
Share on other sites
1 hour ago, bernhard said:

@SamC what are you trying to do exactly? 

At present, all templates are rendered via '_main.php' but each template that needs to be a rendered page (basic-page, blog-index, blog-entry etc.) uses the alternate template filename instead of '_main.php' being appended. Hence:

// _main.php
<?php include("./includes/header" . ".php"); ?>
<?php include("./views/{$page->template->name}" . ".php"); ?>
<?php include("./includes/footer" . ".php"); ?>

and the header which is included on every page:

<?php namespace ProcessWire; ?>

<header>
  <div class="container">
   LOGO, MENU ETC...
  </div>

<?php
  if ($page->template == "tag-entry") {
    $title = "Processwire " . strtolower($page->title) . " tutorials";
  }
  elseif ($page->parent->template == "blog-entry") {
    $title = $page->parent->title;
  }
  else {
    $title = $page->get("altTitle|title");
  }
?>

  <div class="container pt-5 pb-6">
      
      <h1 class="display-3"><?= $title; ?></h1>

      <?php if ($page->subtitle): ?>
        <p class="subtitle"><?= $page->subtitle; ?><p>
      <?php endif; ?>

      <?php if ($page->template == "blog-entry" && $page->parent->template == "blog-entry"): ?>

        <p class="date-and-cat"><span>Posted on</span> <strong><?= renderPostDate($page->parent) ;?></strong> <strong><?= renderTags($page->parent); ?></strong></p>

      <?php elseif ($page->template == "blog-entry" && $page->parent->template == "blog-index"): ?>

        <p class="date-and-cat"><span>Posted on</span> <strong><?= renderPostDate($page) ;?></strong> <strong><?= renderTags($page); ?></strong></p>

      <?php endif; ?>

  </div>

</header>

So, using another method such as markup regions, not sure how to render this. Maybe something like:

// _main.php
  <?php
    if ($page->template == "tag-entry") {
      $title = "Processwire " . strtolower($page->title) . " tutorials";
    }
    elseif ($page->parent->template == "blog-entry") {
      $title = $page->parent->title;
    }
    else {
      $title = $page->get("altTitle|title");
    }
  ?>

  <region id="header">
    <div class="container pt-5 pb-6">

    <h1 class="display-3"><?= $title; ?></h1>

    <?php if ($page->subtitle): ?>
      <p class="subtitle"><?= $page->subtitle; ?><p>
    <?php endif; ?>

    <region id="date-and-cat"></region>

    </div>

  </region>

and a blog page for example:

// blog-entry.php
<region id="date-and-cat">
  <?php if ($page->parent->template == "blog-entry"): ?>

    <p class="date-and-cat"><span>Posted on</span> <strong><?= renderPostDate($page->parent) ;?></strong> <strong><?= renderTags($page->parent); ?></strong></p>

  <?php elseif ($page->parent->template == "blog-index"): ?>

    <p class="date-and-cat"><span>Posted on</span> <strong><?= renderPostDate($page) ;?></strong> <strong><?= renderTags($page); ?></strong></p>

  <?php endif; ?>
</region>

Not really sure here. I also have include files inside loops and stuff like that. I think my best bet is to start with empty templates and build it up rather than modifying my existing ones which is just confusing me no end.

Don't really want to divert this thread too much though.

  • Like 1

Share this post


Link to post
Share on other sites
12 hours ago, SamC said:

Not really sure here. I also have include files inside loops and stuff like that. I think my best bet is to start with empty templates and build it up rather than modifying my existing ones which is just confusing me no end.

agree ;) but of course you can combine markup regions and includes...

12 hours ago, SamC said:

Don't really want to divert this thread too much though.

agree :)

  • Like 1

Share this post


Link to post
Share on other sites
47 minutes ago, bernhard said:

agree ;) but of course you can combine markup regions and includes...

Starting to see the point of regions now after playing around with it this morning. Need to keep reminding myself that '_main.php' is the LAST file that is output.

This does seem to have (at least) one advantage over my last approach. Namely, I don't have to set '_main' as the alternate template filename anymore for each template.

=EDIT=

Another thing I've noticed, if you include a file from '_main.php' (which is not a known system template), the include must have...

<?php namespace ProcessWire; ?>

...at the top or it doesn't output.

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 androbey
      Hello again! 

      Unfortunately I came across another problem. 

      I have a "regular" ProcessWire setup and want to create a separate php script. That script should be executed by a cron job and is bootstrapped with my PW setup. Main goal is to send mails which are stored in a email field. 
      My problem: I want to access a specific field from a template where only specific users have access to. Right now, the cron job is executed as "guest", of course. 

      How can I bypass this restriction, so that I have access to that specific field (it's only one email field)? 

      Does it make sense to set current user via api? 

      Hope you can help me out there.

      Cheers,
      Andreas
    • By mike62
      I'm trying to echo a field from another page, in my footer. I have a Website Settings page (id 1006) with several fields for general site settings, like store hours (field is named store_hours). In the footer, I have this:
      <?php $settingsPage = $pages->get(1006); echo $settingsPage->store_hours; ?> Shouldn't that output the contents of that field? Right now it's printing a "0" (zero) on the page.
      Elsewhere in the same footer template file, I have this code and it works fine:
      <?php $homepage = $pages->get(1); echo $homepage->body; ?> Does it have anything to do with the fact that the field is organized into one of these tabs, at the top of the page editor?
      (disclaimer: I'm new to PW, and have inherited this site from another developer; that's why I don't know how or why some of this stuff is set up the way it is).
      Thanks!

    • By jtborger
      Hi,
      Yesterday I found out about the relatively new markup regions functionality and I love it. The ease of use and simplicity is just what I think is typically ProcessWire and is why Im still happy I chose for PW four years ago when changing CMS/CMF. So thanks Ryan for your vision and all you put into it.
      That said, Im running into an issue I'm not sure what to think of it.
       
      I have enabled markup regions in config.php and it does what I suppose it should: it replaced and all. Very neatly. 
      The only thing I discovered is that while Im debugging some issues and I use var_dump to echo some stuff, it does that two times in a row. And this only happens when useMarkupRegions is enabled.
      I dont get this, does it mean the template file gets called twice (and thus the script is run twice?) or is it only displayed twice, where the first time most output is erased and /or replaced by the substituted output?
      I don't really get whats going on there. Is this behavior normal when using markup regions?
      Thanks!
       
    • By mike62
      I'm working on a page and it's showing up differently when I'm logged in. It's not that a field is set to private or anything, because it's still pulling data from that field. It looks like the "public" view is simply using an old version of the template (home.php), and the logged-in view is using the current version of home.php. See attached screenshots.
      Is there something that caches template files? Is there a way to force it to use the most recent version of the template?
      EDIT: I found the Pro Cache module and cleared it. That seemed to help. 
      Thanks,
      -Mike


    • By mike62
      I am new to PW, and am trying to get an image to display, from a field in my template. Here's the code I'm using:
      <?php $image = $page->home_header_image; echo "<img src='{$image->url}' alt='{$image->description}' />"; ?> I'm following the tutorial on this here.
      When I save the template and reload the page, the path to the image is incomplete. If just echoes:
      <img src="/site/assets/files/1/" alt=""> It omits the name of the image, at the end of the path.
      Here's the site I'm working on:
      http://dev.delucaswpg.webfactional.com
      A couple caveats:
      I'm using ProcessWire 2.3.0 (tried updating the site and everything went berserk because of some plugin dependencies; point being: I can't update to the latest PW). I tried using the ->size thing and it gave me an error, saying it couldn't use 'size' in this context. Which I also thought was weird. Any ideas? Thanks!