XF 2.0 Definition of a node page

GeorgeS

Active member
Good evening,


I've created a copy of the current site and installed the XF 2.0 Beta. It went fine so far, except for one thing. I use a node page as main page. Calling that page gives an "Oops! We ran into some problems." statement.

When I inspect the node page definition, I can't save it:

d92GpqP.png


ZSL7RHj.png


It looks like XF 2.0 expects the node page definition on a different place? Currently it is in library/XenForo/Pages/SamplePage. Or has the layout of the class definition changed?


Georg
 
The library directory isn't used any longer. All files go in the "src" directory.

You likely want to change the prefix of your class name from "XenForo" to something else that's unique to you, in which case the files would go within "src/addons" (and then the path based on your class name).
 
Sorry, I'm still stuck here.

Assume, I rename the class definition to Georg_SamplePage, and the file is SamplePage.php, how do I define the PHP callback, assuming the file is stored as /var/www/src/addons/SamplePage/SamplePage.php?

I tried a few variations, but none was accepted from the software.

What's also irritating: do I need to use / or \? The description says "Example: AddOn\Path\To\ClassName"

Thanks for your help,
 
Your question above is slightly ambiguous so just to be clearer:

Any customisations made should be stored in a directory which identifies you as a developer (or a specific project). So if we just assume right now that your project is called Pages, you would create your directory here: src/addons/Pages.

Let’s call your page SamplePage.php which is stored in the path src/addons/Pages/SamplePage.php.

Inside the file, you need to define its namespace. The namespace is essentially a class prefix which represents all files in a given directory relative to the src/addons directory. So at the top of your file you will have:

PHP:
<?php
    
namespace Pages;
Note that to answer your question about / and \ if it relates to a namespace or class name it will always be a backslash \.

Now you need to write the rest of the outer block of code including the method name which we’ll call IncludeFile, so the rest of your file will now look like:

PHP:
<?php
    
namespace Pages;

class SamplePage
{
    public static function IncludeFile(\XF\Pub\Controller\Page $controller, \XF\Mvc\Reply\View &$view)
    {
        // YOUR FUNCTION CODE HERE
    }
}

The callback class you write when saving the page in the Admin CP will be Pages\SamplePage and the method name will be IncludeFile.

Now that should be it, and it will save. Though I suspect you will find that when you load the page it won’t work as I’ve spotted a bug. You might also need changes in your existing code if it uses the $controller or $view variables (or their equivalent) in your original code.

Before getting into that though, make sure it can save and he above generally makes sense :)
 
File: /var/www/src/addons/SamplePage/SamplePage.php
Code:
PHP:
<?php
namespace SamplePage;

use XF\Pub\Controller\AbstractController;
use XF\Mvc\Reply\AbstractReply;

class SamplePage
{
    public static function includeFile(AbstractController $controller, AbstractReply &$reply)
    {
        // your code here
    }
}
Callback: SamplePage\SamplePage::includeFile

... which is basically the same als @Chris D has posted except that the methodname is camelCase and classnames are aliases for the fully qualified base classes.
 
Last edited:
Thanks to both of you for your replies, I think I will be able to get this "cow off the ice" (German proverb).
 
It means to get a runaway cow from the ice before the cow enters a place where the ice is too thin :D

But while we're talking: the Template HTML looks like this:

Code:
<div class="baseHtml messageText">
{xen:raw $myContent}
</div>

The output looks like this:

{xen:raw $myContent}

The class definition itself (after slight modifications):

Code:
class SamplePage
{
    public static function  includeFile(AbstractController $controller, AbstractReply &$response)
    {
        ob_start();
        require('/var/www/SamplePage/index.php');
        $myContent = ob_get_contents();
        ob_end_clean();

        $params = array(
            'myContent'  => $myContent
        );

        $response->params = array_merge(
            $response->params,
            $params
        );
    }
}

I have the impression there are a few more modifications needed ...
 
I do undersand the meaning quite well as I am from Germany ;)

The whole code base has changed, including template syntax, phrase names and CSS classes.

Code:
{$myContent|raw}

PHP:
class SamplePage
{
    public static function includeFile(\XF\Pub\Controller\Page $controller, \XF\Mvc\Reply\View &$view)
    {
        ob_start();
        require('/var/www/SamplePage/index.php');
        $myContent = ob_get_contents();
        ob_end_clean();

        $view->setParam('myContent', $myContent);
    }
}

And you need to modify the CSS classes as well, though I don't know the XF2 ones top of my head.
 
Last edited:
Hello,


thank you for your replies, I tried them, but it's not working.

I can save the page definition, and it scans the file that contains the definition (had one bracket too much). But calling the page does not open the file in question (/var/www/SamplePage/index.php).
 
Well ... this is Beta software and it seems like you've hit a bug :D

Change src\XF\Pub\Controller\Page.php
PHP:
if (!$page->callback_class && $page->callback_method)

to

PHP:
if ($page->callback_class && $page->callback_method)

and it should work.
 
Hello,


Beta Software has never been a problem for me, as I am a software developer :D

This change made it better, my initial script is execute, but it fails here:

Code:
  XenForo_Autoloader::getInstance()->setupAutoloader($fileDir . '/library');
  XenForo_Application::set('page_start_time', $startTime);
  XenForo_Session::startPublicSession();
  $visitor   = XenForo_Visitor::getInstance();

It fails with "Fatal Error: Class 'XenForo_Autoloader' not found". I've just give the next lines, because there might be more changes to the system.
 
This is XF 1 code, you will have to port that to XF 2 - none of those classes that existed in XF1 does exist in XF 2.

But why do you want to perform a bootstrap (this looks like part of a bootstrap sequence) in a script that is called from within XF?
 
Last edited:
Hi, Kirby -


when I started this project some years ago, I followed a tutorial on how to write addons. I need access to the user information (user name, user class, etc.), so I used this code snippet, and it worked (maybe with an overhead) until the XF 2.0 beta. I will gladly accept a better solution.
 
It depends on what you want to achive, we can only give advice if we know what you want to do.
Though, as you are a software developer yourself, it shouldn't be too difficult to get started with XF 2:
https://xf2demo.xenforo.com/dev-docs/

You can also just post your whole script, might be more effiecient than asking questions chunk by chunk ;)
 
Hello,


it is not a script, but a complete set of (currently) 44 scripts, that would be too much to post here. The project deals with a disctinct database, but the authorisation is taken from the XenForo user definition, so I need access to the information that in XF 1.x was retrieved from XenForo_Visitor.

I will have a look at the docs (thanks for the link), but as I'm approacing 60 years and I have been a programmer all my life (as soon as I got my hands on a programmable calculator), my roots are with TI and HP pocket calculators and the mainframes. This was my first project with PHP at all.
 
Hello,


it really looks like problem come chunk by chunk, so I yell for help again.

Under XF 1.x, the instance of visitor had a property, csrf_token_page which contained the value to be used for _xfToken, this property is missing in 2.0. Where do I get a valid value for _xfToken now?

Thank you for your patience.
 
Hello,


it really looks like problem come chunk by chunk, so I yell for help again.

Under XF 1.x, the instance of visitor had a property, csrf_token_page which contained the value to be used for _xfToken, this property is missing in 2.0. Where do I get a valid value for _xfToken now?

Thank you for your patience.

Ideally you would just the xf:form tag for a form in templates, or use the standard XF javascript Ajax wrapper (XF.ajax()), or even more ideally for an Ajax call, look at some of the default XF stuff - such as the inserter framework. These will add the csrf token to the request automatically.

Liam
 
Top Bottom