Jump to content

Recommended Posts

Hey folks,

I have a question regarding rendering of template files that are in a subfolder of the template folder.
How would I for example render these PageTable items, when their template files are inside templates/blocks/:

 <div class="grid">
    <?php foreach($page->grid_ext as $item): ?>
    <div id="pteg_<?= $item->id ?>">
      <?php echo $item->render(); ?>
    </div>
    <?php endforeach; ?>
  </div>

I tried this, but get an error:

<?php echo $item->render(wire('config')->paths->templates . '/blocks/'); ?>

 

Share this post


Link to post
Share on other sites

this is working:

<?php echo $item->render($config->paths->templates . "blocks/" .$item->template->name. ".php"); ?>

It would be better if I could get the folder of the PageTable settings (the settings where you can specify an alternative folder for your templates) programmatically

Share this post


Link to post
Share on other sites

@jploch Does this help? On the Template -> Edit -> Files tab, you could nominate an alternative template/path for your PageTable template.

1752310061_Screenshot2020-07-1022_22_58.thumb.png.f4fb49a80602a579b2a2661d4aa213c0.png

  • Like 1

Share this post


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

It would be better if I could get the folder of the PageTable settings (the settings where you can specify an alternative folder for your templates) programmatically

I mean, you could do something like this:

//in site/ready.php
$this->addHook("Page::renderBlock", function($event)
{
    $page = $event->object;

    if ($page->template->altFilename)
        $blockPath = $page->template->altFilename;
    else
        $blockPath = $page->template->name;

    $blockPath = "blocks/{$blockPath}.{$this->wire('config')->templateExtension}";

    $event->return = $page->render($blockPath, $event->arguments(0));
});

Now you can call $page->renderBlock() or $page->renderBlock(['this' => 'that']) and the block’s template path will be determined automatically according to the template settings.

Or this, maybe:

$this->addHook("Page::renderBlock", function($event)
{
    $page = $event->object;

    $templatePath = $this->wire('config')->paths->templates;
    $templatePath = substr_replace($page->template->filename, 'blocks/', strlen($templatePath), 0);

    $event->return = $page->render($templatePath, $event->arguments(0));
});

 

  • Like 1

Share this post


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

@jploch Does this help? On the Template -> Edit -> Files tab, you could nominate an alternative template/path for your PageTable template.

1752310061_Screenshot2020-07-1022_22_58.thumb.png.f4fb49a80602a579b2a2661d4aa213c0.png

I can't set a path this way. I think this defines only the name of the template, if I input the path it gets removed after page save.

Share this post


Link to post
Share on other sites
36 minutes ago, Jan Romero said:

Or this, maybe:


$this->addHook("Page::renderBlock", function($event)
{
    $page = $event->object;

    $templatePath = $this->wire('config')->paths->templates;
    $templatePath = substr_replace($page->template->filename, 'blocks/', strlen($templatePath), 0);

    $event->return = $page->render($templatePath, $event->arguments(0));
});

Thank you! This looks promising, as I could make the folder name dynamic (it's for a module based on pagetable).
However this throws me an error (Method Page::renderBlock does not exist or is not callable in this context) on the frontend and also the page tree in the backend stops working after I insert that hook inside my module inside public function ready() 

Share this post


Link to post
Share on other sites

Mh, it works for me. I believe 'autoload' => true must be set for it to call ready(). Have you tried reinstalling the module?

Share this post


Link to post
Share on other sites
Posted (edited)
On 7/10/2020 at 12:29 PM, jploch said:

Hey folks,

I have a question regarding rendering of template files that are in a subfolder of the template folder.
How would I for example render these PageTable items, when their template files are inside templates/blocks/:


 <div class="grid">
    <?php foreach($page->grid_ext as $item): ?>
    <div id="pteg_<?= $item->id ?>">
      <?php echo $item->render(); ?>
    </div>
    <?php endforeach; ?>
  </div>

 

I would go this way, without invoking ready.php or other resources:

 <div class="grid">
    <?php foreach($page->grid_ext as $item): ?>
    <div id="pteg_<?= $item->id ?>">
      <?php 
		// specify the template viewfilename like this, if it is a single viewfile:
        $viewFilename = $wire('config')->paths->templates . 'blocks/myblockviewfile.php';
         
		// or if you have different files get them from template properties:
  		$viewFilename = $item->template->altFilename ? $item->template->altFilename : $item->template->name;
        $viewFilename = $wire('config')->paths->templates . 'blocks/' . $viewFilename . '.' . $wire('config')->templateExtension;
        
        // check if viewfile is available
        if(!is_readable($viewFilename)) {
            echo logSectionError('Missing Template-View-File!', '<strong>' . basename($viewFilename) . '</strong>');
            continue;
        }
         
        // now pack a bag with all needed variables for the block render template file:
        $viewBag = [];
        $viewBag['item'] = $item;
        $viewBag['page'] = $item;     // if you use the $page var in your template file, pass here the current item-page to it !
        $viewBag['pages'] = $pages;   // optionally if you need other vars, add them here
        $viewBag['config'] = $config; //  "
        
        // and render the block
		echo "\n      "  . wireRenderFile($viewFilename, $viewBag);

      ?>
    </div>
    <?php endforeach; ?>
  </div>

https://processwire.com/api/ref/functions/wire-render-file/

 

Edited by horst
added a check for viewfile existence
  • Like 1

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 christophengelmayer
      Hi everyone,
      I'm working on a CLI script that renders paginated pages.
      Therefore I iterate trough paginated pages and set the page number and render the result.
      My problem is, after calling the render function for the first time, the output doesn't change even if I change the page number.
       
      DEMO:
      I'm using a template that renders a pagination of its children:
      <?php echo $page->children("limit=3")->render(); ?> I can view the paginated results in the Browser:
      /page-rendering-pagination/ /page-rendering-pagination/page2 /page-rendering-pagination/page3 ... When trying to render the different pages using the API I always get the first result, even if I change the page Number.
      <?php namespace ProcessWire; include('./index.php'); wire('input')->setPageNum(1); $p = wire('pages')->get('/page-rendering-pagination'); var_dump($p->render()); // renders first three items wire('input')->setPageNum(2); var_dump($p->render()); // also renders the first three items Am I missing something? Is there some kind of caching mechanism that I'm not aware of?
      Thanks for your help.
    • By tron1000
      Hello! I use PW 3.0.98 and I have frontend editing enabled for a PageTable Field. Somehow, when I double click the field in the frontend, the iframe in wich the content is displayed is very small (see screenshot). I couldn't find out if thats some CSS conflict or another problem. Any suggestions? Thanks, Andrej
       

    • By Noel Boss
      I use a PageTable field to make edits to children of pages more intuitive…
      To register the hooks, insert the following Snippet inside your init function in your module (or add it to your init.php file):
      /** * Initialize the module. * * ProcessWire calls this when the module is loaded. For 'autoload' modules, this will be called * when ProcessWire's API is ready. As a result, this is a good place to attach hooks. */ public function init() { // Prefill pageTable field $this->wire()->addHookBefore('InputfieldPageTable::render', $this, 'addChildrenToPageTableFieldsHook'); $this->wire()->addHookBefore('InputfieldPageTableAjax::checkAjax', $this, 'addChildrenToPageTableFieldsHook'); } Then, add this hook method:
      /** * Fill pagetable fields with children before editing…. * * @param HookEvent $event */ public function addChildrenToPageTableFieldsHook(HookEvent $event) { $field = $event->object; // on ajax, the first hook has no fieldname if (!$field->name) { return; } // get the edited backend page $editID = $this->wire('input')->get->int('id'); if (!$editID && $this->wire('process') instanceof WirePageEditor) { $editID = $this->wire('process')->getPage()->id; } $page = wire('pages')->get($editID); // disable output formating – without this, the ajax request will not populate the field $page->of(false); // you could also insert a check to only do this with sepcific field names… // $page->set($field->name, $page->children('template=DesiredTemplate')); // just specific templates $page->set($field->name, $page->children); } Now whenever there is a page-table field on your page, it gets populated with the children
    • By rareyush
      <?php namespace ProcessWire; $form = $modules->get('FormTemplateProcessor');$form->template = $templates->get('book-now'); // required $form->requiredFields = array('title', 'email', 'number','body'); //$form->email = 'your@email.com'; // optional, sends form as email $form->parent = $page('template=book-now'); // optional, saves form as page //$form->render(); // draw form or process submitted form ?> <?php echo $form->render(); ?>  
       
      using this to for a contact on new processwire version 3  and I am receiving this error
       
      Error: Uncaught Error: Call to undefined method stdClass::render() in C:\wamp64\www\mbs\site\templates\book-now.php:9  
      tried following but none of them works
       
      render(array('name','email','body',))
      wireRender()
       
      Render()
      wire()
       
      anyone ?  
    • By Lance O.
      I've built a site that uses parent pages as the "container" for child pages:
      Parent page [page.php] -- Child page [unit-child-a.php] -- Child page [unit-child-b.php] ---- Grandchild page [subunit-grandchild-a.php] ---- Grandchild page [subunit-grandchild-b.php] -- Child page [unit-child-c.php] The child pages are displayed as content on the corresponding parent page using the render method. Some child pages also include their own child pages. (Internally the child page template names start with "unit-" and the grandchild page template names start with "subunit-".)
      Example:
      foreach ($page->children("template=template-name,sort=sort") as $child) echo $child->render(); This approach allows content administrators to add and reorder child pages as necessary, but I've come across an issue that I'm not sure how to address.
      The site includes search functionality, but when a visitor searches for content and it is found in a child or grandchild page, the Parent page should be the one that is displayed in the search results, since the child and grandchild pages are not directly viewable. Since some searches could include more than one child or grandchild page of a parent page, this sometimes means that a parent page could be included more than once.
      How do I easily redirect the child and grandchild pages to the parent page, and only include the parent page once in the search results?
       
×
×
  • Create New...