Jump to content
louisstephens

Using $page Functions in Templates

Recommended Posts

After getting a lot more confident with my php skills, I thought I would try condensing my file structure by using the _func.php in my templates. I thought this would be a great way to cut down on my includes (Currently at around 12). However, I ran into a bit of a snag. From my reading, I understand that $page is not a global variable, and that I could use something like:

$pages = wire('pages');

to get the desired result. However, I must not be using this right :).  Here Is what I have:

function basicPage(){
$pages = wire('pages');
$output = "";
$output .="<div class=\"container\">";
$output .="<div class=\"row\">";
$output .="<div class=\"col-md-12\">";
$output .="<h1><?php echo $page->title; ?></h1>";
$output .="</div>";
$output .="</div>";

$output .="<div class=\"row\" id=\"tinyInfo\">";
$output .="<div class=\"col-md-12\">";
$output .="<ul class=\"about\">";
$output .="<li>{$pages->about}</li>";
$output .="</ul>";
$output .="</div>";
$output .="</div>";

$output .="<div class=\"row\">";
$output .="<div class=\"col-md-12\" id=\"maincopy\">";
$output .="{$pages->maincopy}";
$output .="</div>";
$output .="</div>";
$output .="<div class=\"row\">";
$output .="<div class=\"col-md-12\">";
	include './includes/slider.php';
$output .="</div>";
$output .="</div>";
echo $output;
}

This doesn't seem to be outputing anything into my template. Have I missed a crucial step here, or is the "output" method I have chosen not even a great way to set this up? I understand includes wont work this way, but if anyone has suggestions on this I would gladly like to hear them. Sorry for a post with so many questions, but I am just stumped.

Share this post


Link to post
Share on other sites

Instead of echo $output, you must return the variable and in your template, you echo your function.

in _func.php you have your function :

function basicPage(){
	// ...
	return $output;
}

and in your template file you call the function :

<?php

$out = basicPage();
echo $out; 

 

Share this post


Link to post
Share on other sites

flydev is right for the basic usage of the function with echo but additionally you define $pages but you did'nt that with $page:

//you have this in your code...
echo $page->title;

so what is $page in this function?

I think the whole idea is to build a function for the output of the basic page template...so i think this is the wrong way...

I use in my templates the delayed output with a _main.php file (and _init.php and _func.php) and the interesting part different layouts on the equal templates...this idea is from @horst and the basic concept could read there:

 

 

so you can split the template logic from the HTML output without to build a custom function for every template....since PW rendering the templates this is just unnecessary.

You could build functions for special rendering that is needed in different templates or all over the place for example:

/**
 * Show last Posts in several templates
 * @var $limit (Int) set the limit of displayed posts
 * @var $headline (string)set the headline of the postlist
 */

function renderArticles($limit = 3, $headline = 'New Articles') {
	//get articles
	$articles = wire('pages')->find("template=article,limit=$limit,sort=-publish_from");
	if (count($articles)) {
	//get the rootpage of the articles
	$article_root = wire('pages')->get(1068);
	//open article list
	$out = '<h4 class="subtitle">'.$headline.' - <a href="'.$article_root->url.'">Overview</a><h4><div class="side-list"><ul>';
	//get list items
	foreach ($articles as $a) {
		// get the image instance of the cropped version 70px x 70px
		$thumb = $a->artikel_bild->size(70);
			$out .= '<li>';
			$out .= '<a href="'.$a->url.'"><img alt="'.$a->headline.'" src="'.$thumb->url.'"></a>';
			$out .= '<h5><a href="'.$a->url.'">'.$a->title.'</a></h5>';
			$out .= '<p>'.$a->article_cat->title.'</p>';
			$out .= '</li>';
	}
	//close list
	$out .= '</ul></div>';
	return $out;
	}
}

Best regards mr-fan

  • Like 2

Share this post


Link to post
Share on other sites

If you are using Processwire 3.x

you could import PW namespace

<?php
namespace Processwire;

and use the functions without the need for wire() method.

:)

  • Like 2

Share this post


Link to post
Share on other sites

A couple of errors in your function...

$output .="<h1><?php echo $page->title; ?></h1>";

The PHP tags shouldn't be here and you cannot echo inside a variable declaration.

 

{$pages->about}
...
{$pages->maincopy}

These don't make sense - maybe you meant $page ?

 

And totally a matter of preference, but I find...

$output = "
<div class='container'>
    <div class='row'>
        <div class='col-md-12'>
            <h1>{$page->title}</h1>
        </div>
    </div>
</div>
";

...more readable than...

$output = "";
$output .="<div class=\"container\">";
$output .="<div class=\"row\">";
$output .="<div class=\"col-md-12\">";
$output .="<h1>{$page->title}</h1>";
$output .="</div>";
$output .="</div>";

 

13 hours ago, louisstephens said:

I thought this would be a great way to cut down on my includes (Currently at around 12)

If you're considering switching to functions instead of includes because of performance concerns I wouldn't bother. It's true that you would avoid some file loads but you'd have to have a lot more includes before this would make a difference worth caring about.

One thing to think about when considering a switch from includes to functions is variable scope. Basically, includes have access to variables defined outside of them but functions do not unless you pass the variable to the function as a parameter. This can be a help or a hindrance depending on your needs.

Lastly, you could consider using $files->render() (aka wireRenderFile). A file rendered this way has access to all API variables and you can pass in an array of your own variables for use inside the file. I'm not 100% clear on the benefits of this over a normal include but I guess it has to do with the isolation of variable scope (to avoid the risk of overwriting variables of the same name in your template).

  • Like 5

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Mithlesh
      Hi there,
      My form is not getting submitted, it is showing:
      Unable to verify successful email delivery of this form submission.
      Attaching for your reference as well: 

      In the Backend, it is showing Connection timed out with smtp.gmail.com
      Pl guide me how to resolve that
    • By CareerTeam GmbH
      Hi there,
      We are an executive search agency based in Germany looking for a freelancer (2-5 days per week) supporting us with the development and design of our websites. The position will be located in Hamburg, Germany and it would be great if you are on short call. German language knowledge is mandatory. 
      You can reach me via email jobs@careerteam.de.
      Thank you!
      Regards
      Annemie
    • By louisstephens
      I was really unsure of how to actually title this post, so I do apologize (if someone has a better idea, I will gladly edit it). I am using the profields: pagetable field to allow people to create their own "content" (copy, image, button, etc etc) and rearrange it. I also included a field called "column_size" using the RangeSlider set to (1-12).
      I guess I'll clarify a bit more on this. I am using flexbox where the "row" is <section></section> and the columns are <div class="column"></div> have given the "columns"  flex: 1 1 0; so no matter how many columns you have, the columns will automatically adjust for new content. Where my confusion is coming in: If a user has set up 3 copy items (with 12, 5, 7 respectfully for the column_size), how do I actually output this in my template? I was going to use a switch statement to handle the various items which I thought made it quite easy, but with closing sections and columns I have confused myself as I assume I need an if statement to check if the column size is > 12, or = 12 to determine the actual closing/opening of sections. I apologize if I have not made this very clear. I am a bit unsure how to word this let alone to go about this. 
      Im very appreciative of for any insight into this.
       
       
    • By Robin S
      Another little admin helper module...
      Template Field Widths
      Adds a "Field widths" field to Edit Template that allows you to quickly set the widths of inputfields in the template.

      Why?
      When setting up a new template or trying out different field layouts I find it a bit slow and tedious to have to open each field individually in a modal just to set the width. This module speeds up the process.
      Installation
      Install the Template Field Widths module.
      Config options
      You can set the default presentation of the "Field widths" field to collapsed or open. Field widths entered into the Template Field Widths inputfield are only applied if the Edit Template form is submitted with the Template Field Widths inputfield in an opened state. "Collapsed" is the recommended setting if you think you might also use core inputs for setting field widths in a template context. You can choose Name or Label as the primary identifier shown for the field. The unchosen alternative will become the title attribute shown on hover. You can choose to show the original field width next to the template context field width.  
      https://github.com/Toutouwai/TemplateFieldWidths
      https://modules.processwire.com/modules/template-field-widths/
    • By louisstephens
      So I have been hard at work creating url segments for a template (api) and everything is working swimmingly in creating a simple end point for svelte.js. I have however, run into a few questions that I can wrap my head around.
      In my api template I have:
      if($input->urlSegment1 === 'clients') { header('Content-Type: application/json'); $clients = $pages->find("template=clients"); $client_array = array(); foreach ($clients as $client) { $id = $client->id; $title = $client->title; $url = $client->url; $clientName = $client->client_name; $clientColor = $client->client_color->value; $assigned = $client->assigned_to->user_full_name; $client_array[] = array( 'id' => $id, 'code' => $title, 'name' => $clientName, 'associated_users' => $assigned, 'url' => $url ); } $client_json = json_encode($client_array, true); echo $client_json; } The output json from this is:
      [ { "id":1644, "code":"abc", "name":"Test Name", "associated_users":null, "url":"\/pw\/clients\/abc\/" }, { "id": 1645, "code": "xyz", "name": "Test Name", "associated_users": null, "url": "\/pw\/clients\/xyz\/" }, ] I was curious is it possible to add in "clients" before this output json so it would appear as 
      clients: [ { "id":1644, "code":"abc", "name":"Test Name", "associated_users":null, "url":"\/pw\/clients\/abc\/" }, { "id": 1645, "code": "xyz", "name": "Test Name", "associated_users": null, "url": "\/pw\/clients\/xyz\/" }, ] I was not really sure of how to tackle this in my php code, and have spent more time than I care to admit trying to figure it out. Another question I have is that "associated_users" is returning null, which in this instance is correct. It is a multi page field that is set to pull a custom name field from the users template, ie "Louis Stephens" would be associated with the first page. I understand that I need to use a foreach to get the correct data, but I was really unsure of how to place this inside an array, or update the array with the new data. Any help with any of this would greatly be appreciated.
×
×
  • Create New...