Jump to content

Rendering page manually without losing context?


abdus
 Share

Recommended Posts

Hi,

I'm working on a homepage template where I loop over some pages, check if they have children, and print their children; if not, print the page itself where I employ page->render function. Inside template files of these parent pages, I use $config->scripts->[foot|head]->add() to enqueue scripts and and when creating markup I print the contents of these FilenameArrays using simple foreach loops.

With parents that have children, which don't require rendering a part of page (as opposed to rendering whole html document), there's no problem using $config->scripts, using PHPStorm's debugger I can track the scripts up until where the execution comes to parents with no children. When used with $parentPage->render(array('renderPartial' => true)) these pages get rendered from beginning using their own context, completely ignoring the previous one, and resulting in flushing $config->scripts->[foot|head].After many hours of fiddling with here and there, I'm lost and I don't know how else I can tackle with this problem. 

The question I have is if there's a way to manually render a page without losing the context?
Or, in which variable I can store FilenameArrays?

// The code I have can be paraphrased as

// Homepage sections
foreach $section as $parent 
    if $parent->hasChildren
        foreach $children as $child
            renderChild()
    else
        $parent->render(partial=true)

// In each parent's template
$config->scripts->head->add("head.js")
$config->scripts->foot->add("foot.js") 
// both foot and head initialized at _init.php

// After using
$parent->render(partial=true)

// $config->scripts gets flushed 
loop_over_and_write_scripts('foot') // returns nothing, $config->scripts->foot is empty

Thanks in advance.

Link to comment
Share on other sites

how are you getting that partial=true,  i can't see how the render method takes any arguments, at least not here:

http://cheatsheet.processwire.com/page/built-in-methods-reference/page-render/

perhaps you could use wireRenderFile, or wireIncludeFile

Huh, that's weird. I couldnt find it either http://apigen.juzna.cz/doc/ryancramerdesign/ProcessWire/class-Page.html

I think that parameter is left from when I was playing with wireIncludeFile/wireRenderFile What's more weird is that it works. I can access the given parameter perfectly fine on its template file.

DVh708m.png

// contact.php, one of the sections in homepage

// If partial render is not requested render the whole page
if (isset($options['renderPartial']) == false) {
    // Append contact form to the end of content
    $content .= $page->render("partials/_contact_form.php");
    // Call main template
    include("_main.php");
} // If only the contact form is requested, return it alone
elseif (isset($options['renderPartial']) == true && isset($options['renderPartial']) == true) {
    include("partials/_contact_form.php");
}

I employed wireIncludeFile/wireRenderFile somewhere else for creating email markup, but let me try using it here too.

Link to comment
Share on other sites

I solved it.

Thanks to Macrura's recommendation, I was able to render the page without losing context.

The code is simplified into this:

// home.php, check if parent has children: if true, render partial, full page otherwise

if(! hasChildren)
    // render partially
    $template_file = $parent->template->filename;
    wireIncludeFile($template_file, array('renderPartial' => true));

...
...

// Using renderPartial, which you can access by itself 
// as $renderPartial in the template file associated with the page

// contact.php

// Render partial
if (isset($renderPartial) && $renderPartial) {
    wireIncludeFile("partials/_contact_form.php");
} else { // render the whole page
    ...
    ...
    // Append contact form to the end of content
    $content .= wireRenderFile("partials/_contact_form.php");
    // Call main template
    include("_main.php");
}

// Everything renders fine, can access $config->scripts->foot|head just fine.

For reference:

Link to comment
Share on other sites

I sometimes use the code below so that include doesn't loose context.

<?php

// Allow to cache to a variable
function getPartial($path_to_file) {
    ob_start();
    include($path_to_file);
    return ob_get_clean();
}

$partial = getPartial($config->urls->templates . 'partials/myfile.php'); 

That's a nice one. I'm learning the API, so I want to utilize its core functions more, as they have certain advantages like

  • It receives all API variables and optionally your custom variables
  • If your filename is not absolute, it doesn't look in PHP's include path, only in the current dir.
  • It only allows including files that are part of the PW installation: templates, core modules or site modules 

I don't know the internals of output buffering though, I'm new to PHP.

Thanks a lot.

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

×
×
  • Create New...