Brettflan
Active member
What I'm trying to do is add a custom Page (which I've added a menu tab for) which shows a forum index with only specific categories listed. These categories will have "Display in the node list" disabled so they don't show up on the main forum index, only on the custom page.
I'm of course trying to set it up using a PHP Callback. Since I want to be able to specify which categories to show within the page's template HTML, rather than having to edit the PHP file to update which categories are shown, I opted to use callback references within the template HTML rather than in the PHP Callback field for the Page.
So, for example, within the template HTML to show 3 categories with the specified node IDs:
I looked around for someone having tried something similar, but the closest I could find was this for XF 1.5, to show a Forum within a Page:
Not quite what I'm after, and not working in XF 2.1 anyway, but it gave me some points of reference at least.
So after spending hours mostly digging around through XF's code and the online documentation, among other efforts, this is the mess I've currently reached trying to work out the proper method to get the properly templated (with nodes and other content potentially hidden based on the viewer's permissions) output, largely debug code which has been commented out:
The upper part was mostly trying to work out how to do it similar to that guide for showing a forum in a page for XF 1.5, and the bottom is mostly from my other efforts. The upper part stalled out.
The bottom part does partly work at this point, in that the category header is shown, but the main problem I'm then facing is that I can't find the right way to get the proper data for 'children' and 'childExtras'. As for 'children', it seems that should be an array of the child nodes (read as [$id] => $child), with each $child being in the form of an \XF\Tree. At the moment I can't figure out how I can get that info.
The template errors from the above code (again, it does at least show the templated category header, but not the forums or other info below that):
EDIT:
Also, CatShow definition for reference, used to get around assertCanonicalUrl() causing failure and being unnecessary for this:
Anyone have a better idea of how to do this in XF 2.1, or any other thoughts? I'm about at my wit's end here.
I'm of course trying to set it up using a PHP Callback. Since I want to be able to specify which categories to show within the page's template HTML, rather than having to edit the PHP file to update which categories are shown, I opted to use callback references within the template HTML rather than in the PHP Callback field for the Page.
So, for example, within the template HTML to show 3 categories with the specified node IDs:
HTML:
<xf:callback class="Brettflan\ShowContent" method="getCategoryHtml" params="[11]"></xf:callback>
<xf:callback class="Brettflan\ShowContent" method="getCategoryHtml" params="[17]"></xf:callback>
<xf:callback class="Brettflan\ShowContent" method="getCategoryHtml" params="[24]"></xf:callback>
I looked around for someone having tried something similar, but the closest I could find was this for XF 1.5, to show a Forum within a Page:
How to show a forum in a page
This tutorial will explain how to show a forum (thread list) inside a page. I'll not explain why this, or why that, but all the code necessary is commented. And this is the final result: I strongly recommend you to read my others tutorials to know better how XenForo works: How to...
xenforo.com
So after spending hours mostly digging around through XF's code and the online documentation, among other efforts, this is the mess I've currently reached trying to work out the proper method to get the properly templated (with nodes and other content potentially hidden based on the viewer's permissions) output, largely debug code which has been commented out:
PHP:
public static function getCategoryHtml($contents, $params)
{
// $req = new Request(new InputFilterer);
$req = \XF::app()->request();
$req->set('node_id', $params[0]);
// $controller = \XF::app()->controller('XF:Category', $req);
$controller = new CatShow(\XF::app(), \XF::app()->request());
$parBag = new ParameterBag(['node_id' => $params[0]]);
$controller->preDispatch('index', $parBag);
// echo '<pre>'; var_dump(get_class_methods($controller)); echo '</pre>'; return '';
$controllerResponse = $controller->actionIndex($parBag);
// $controllerResponse = $controller->{'actionIndex'}($parBag);
/* Set the param called 'visitor' in the controller response. This param is used in the thread_list template. */
$visitor = \XF::visitor();
$controllerResponse->setParam('visitor', $visitor->toArray());
// echo '<pre>'; var_dump($controllerResponse->getParams()); echo '</pre>';
// echo '<pre>'; print_r(get_class_methods($controllerResponse)); echo '</pre>'; return '';
// return '';
// ----------
// $theNode = \XF::finder('XF:Category')->where('node_id', $params[0])->fetchOne();
$theNode = \XF::finder('XF:Node')->where('node_id', $params[0])->fetchOne();
// $data = $this->getTemplateData($theNode);
$nodeRepo = \XF::repository('XF:Node');
$childNodes = $nodeRepo->findChildren($theNode, false)->fetch();
$nodeRepo->loadNodeTypeDataForNodes($childNodes);
// echo '<pre>'; var_dump($childNodes->toArray()[9]->getNodeListExtras()); echo '</pre>';
// echo '<pre>'; var_dump($childNodes->toArray()); echo '</pre>';
// return '';
$dat['node'] = $theNode;
$dat['extras'] = $theNode->getNodeListExtras();
$dat['children'] = $childNodes->toArray();
$dat['childExtras'] = [];
$dat['depth'] = 1;
// var_dump(\XF::app()->templater()->renderMacro('public:node_list_category', 'depth1', $dat));
return \XF::app()->templater()->renderMacro('public:node_list_category', 'depth1', $dat);
// return '';
}
The upper part was mostly trying to work out how to do it similar to that guide for showing a forum in a page for XF 1.5, and the bottom is mostly from my other efforts. The upper part stalled out.
The bottom part does partly work at this point, in that the category header is shown, but the main problem I'm then facing is that I can't find the right way to get the proper data for 'children' and 'childExtras'. As for 'children', it seems that should be an array of the child nodes (read as [$id] => $child), with each $child being in the form of an \XF\Tree. At the moment I can't figure out how I can get that info.
The template errors from the above code (again, it does at least show the templated category header, but not the forums or other info below that):
- Template public:forum_list: Accessed unknown getter 'record' on XF:Node[9] (src/XF/Mvc/Entity/Entity.php:190)
- Template public:forum_list: Accessed unknown getter 'children' on XF:Node[9] (src/XF/Mvc/Entity/Entity.php:190)
- Template public:forum_list: Cannot call method getNodeTemplateRenderer on a non-object (NULL) (src/XF/Template/Templater.php:970)
- Template public:forum_list: Illegal string offset 'macro' (internal_data/code_cache/templates/l1/s1/public/forum_list.php:22)
- Template public:forum_list: Illegal string offset 'template' (internal_data/code_cache/templates/l1/s1/public/forum_list.php:32)
EDIT:
Also, CatShow definition for reference, used to get around assertCanonicalUrl() causing failure and being unnecessary for this:
PHP:
use \XF\Pub\Controller\Category;
class CatShow extends Category
{
public function assertCanonicalUrl($linkUrl) { return; }
}
Anyone have a better idea of how to do this in XF 2.1, or any other thoughts? I'm about at my wit's end here.
Last edited: