• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

xen:link population

silence

Well-known member
#1
So let's say I have a model function as follows:
PHP:
    public function getAllStuff()
    {
        return $this->fetchAllKeyed('
            SELECT stuff.*
            FROM xf_stuff AS stuff
            ORDER BY stuff_id
        ', 'stuff_id');
    }
And I put that into a variable called $stuff and send it to my template.

How come the following doesn't work:

HTML:
{xen:link stuff, $stuff}
It's not making a link of https://website.com/stuff/1.
Why wouldn't it be doing this?
 

Brogan

XenForo moderator
Staff member
#2
What is the format of the array?
Xen:link expects certain content.

If it's not as expected, you could run the array through a (prepare) function.

Presumably you already have the /stuff route created?
 

silence

Well-known member
#3
What is the format of the array?
Xen:link expects certain content.

If it's not as expected, you could run the array through a (prepare) function.

Presumably you already have the /stuff route created?
Array looks something like this:
Code:
array(
    'stuff_id' => '1',
    'content' => 'blahfdsanklfdsa'
);
And the route:

PHP:
<?php

class Route_Prefix_Stuff implements XenForo_Route_Interface
{
    protected $_subComponents = array(
        'index' => array(
            'controller' => 'ControllerPublic_Stuff',
            'intId' => 'stuff_id',
        )
    );

    public function match($routePath, Zend_Controller_Request_Http $request, XenForo_Router $router)
    {
        $controller = 'ControllerPublic_Stuff';
        $action = $router->getSubComponentAction($this->_subComponents, $routePath, $request, $controller);

        return $router->getRouteMatch($controller, $action, 'stuff');
    }

    public function buildLink($originalPrefix, $outputPrefix, $action, $extension, $data, array &$extraParams)
    {
        return XenForo_Link::buildSubComponentLink($this->_subComponents, $outputPrefix, $action, $extension, $data);
    }
}
 

Chris D

XenForo developer
Staff member
#4
I imagine you've structured the code like that because you eventually plan to add sub component routes, but I don't think that's going to work for you in its current form.

You would be looking at something like this:

PHP:
    protected $_subComponents = array(
        'otherstuff' => array(
            'intId' => 'other_stuff_id'
        )
    );

    /**
    * Match a specific route for an already matched prefix.
    *
    * @see XenForo_Route_Interface::match()
    */
    public function match($routePath, Zend_Controller_Request_Http $request, XenForo_Router $router)
    {
        $controller = 'ControllerPublic_Stuff';
        $action = $router->getSubComponentAction($this->_subComponents, $routePath, $request, $controller);
        if ($action === false)
        {
            $action = $router->resolveActionWithIntegerParam($routePath, $request, 'stuff_id');
        }

        return $router->getRouteMatch($controller, $action, 'stuff');
    }

    /**
    * Method to build a link to the specified page/action with the provided
    * data and params.
    *
    * @see XenForo_Route_BuilderInterface
    */
    public function buildLink($originalPrefix, $outputPrefix, $action, $extension, $data, array &$extraParams)
    {
        $link = XenForo_Link::buildSubComponentLink($this->_subComponents, $outputPrefix, $action, $extension, $data);
        if (!$link)
        {
            $link = XenForo_Link::buildBasicLinkWithIntegerParam($outputPrefix, $action, $extension, $data, 'stuff_id');
        }

        return $link;
    }
Finally, if you have no intention to use sub components, e.g. stuff/otherstuff/other-thing.123/action then you would be better off not having sub component stuff at all, e.g. something similar to how most of the default XF routes work.
 

silence

Well-known member
#5
I imagine you've structured the code like that because you eventually plan to add sub component routes, but I don't think that's going to work for you in its current form.

You would be looking at something like this:

PHP:
    protected $_subComponents = array(
        'otherstuff' => array(
            'intId' => 'other_stuff_id'
        )
    );

    /**
    * Match a specific route for an already matched prefix.
    *
    * @see XenForo_Route_Interface::match()
    */
    public function match($routePath, Zend_Controller_Request_Http $request, XenForo_Router $router)
    {
        $controller = 'ControllerPublic_Stuff';
        $action = $router->getSubComponentAction($this->_subComponents, $routePath, $request, $controller);
        if ($action === false)
        {
            $action = $router->resolveActionWithIntegerParam($routePath, $request, 'stuff_id');
        }

        return $router->getRouteMatch($controller, $action, 'stuff');
    }

    /**
    * Method to build a link to the specified page/action with the provided
    * data and params.
    *
    * @see XenForo_Route_BuilderInterface
    */
    public function buildLink($originalPrefix, $outputPrefix, $action, $extension, $data, array &$extraParams)
    {
        $link = XenForo_Link::buildSubComponentLink($this->_subComponents, $outputPrefix, $action, $extension, $data);
        if (!$link)
        {
            $link = XenForo_Link::buildBasicLinkWithIntegerParam($outputPrefix, $action, $extension, $data, 'stuff_id');
        }

        return $link;
    }
Finally, if you have no intention to use sub components, e.g. stuff/otherstuff/other-thing.123/action then you would be better off not having sub component stuff at all, e.g. something similar to how most of the default XF routes work.
Yeah I'm planning on subcomponents :( But I guess the buildLink function is what I forgot!
 

Chris D

XenForo developer
Staff member
#6
Well, I don't think it's merely the build link function. My point is, your default route shouldn't be listed as a subcomponent.

So your sub components right now should be an empty array, then if $action (or $link) == false then it should just have some default behaviour assigned to handle that.
 

silence

Well-known member
#7
Well, I don't think it's merely the build link function. My point is, your default route shouldn't be listed as a subcomponent.

So your sub components right now should be an empty array, then if $action (or $link) == false then it should just have some default behaviour assigned to handle that.
Ah gotcha. But any extensions of it can have sub components without issue? Say stuff/test ?