Curious as to why something is programmed some way...

Jaxel

Well-known member
So I am writing XenPorta2. And in the addon, I transform the thread view using custom templates. This has always been a very simple process because of the way XenForo is set up. However, it gets a bit more complicated when you consider the AJAX component of XenForo. For instance, when I use quick reply on the thread, instead of it loading up the customized post bit, it loads up the original post bit.

This particular problem I solved relatively simply by hooking into the controller for thread:
Code:
public function actionAddReply()
{
    $response = parent::actionAddReply();
   
    if ($this->_noRedirect() &&
        $this->getModelFromCache('EWRporta2_Model_Articles')->getArticleByThreadId($response->params['thread']['thread_id']))
    {
            return $this->responseView(
                'XenForo_ViewPublic_Thread_ViewNewPosts',
                'EWRporta2_Article_NewPosts',
                $response->params
            );
    }
   
    return $response;
}

However, there are other places which aren't so easy to fix. One in particular: "thread/show-posts". The show-posts action seems to rely completely on javascript and has no method to degrade back to a static page. Because of this, the action has a lot of it's configuration done in the view instead of in the controller. Instead of declaring the template 'post' in the controller, its iterated in the view.

I'm wondering why it was programmed this way. The javascript in XenForo is WAAAAY over my head; so I'm sure there is a good reason for it.
 
actionShowPosts is run after quick reply so it shows the changes without reloading the page. It uses the normal post template to display it. I can help you out with it after I get home and am able to actually look at it again.

Everything relevant to this is contained in XenForo_ControllerPublic_Thread and XenForo_ViewPublic_Thread_ViewPosts
 
Last edited:
The specific part you're looking for is likely this:

Code:
foreach ($this->_params['posts'] AS $postId => $post)
{
     $output['messagesTemplateHtml']["#post-$postId"] =
          $this->createTemplateObject('post', array_merge($this->_params, array('post' => $post)))->render();
}

It uses the normal post template, and adds information for the posts and then displays them at the end on the same page you created your reply from.

When you save a post from the quick reply it goes through the
XenForo_ControllerPublic_Post::actionSaveInline with no redirect and returns:

Code:
$this->_request->setParam('thread_id', $thread['thread_id']);
return $this->responseReroute('XenForo_ControllerPublic_Thread', 'show-posts');

The rest is handled by the AutoValidator. You can probably extend
XenForo_ViewPublic_Thread_ViewPosts and change the following:

Code:
$output['messagesTemplateHtml']["#post-$postId"] =$this->createTemplateObject('post', array_merge($this->_params, array('post' => $post)))->render();

in your extended class to use your article template if necessary, or use the normal post layout when needed.
 
Hmm, I seem to be having issues rewriting the response. This is my extension:

Code:
<?php

class EWRporta2_ViewPublic_ThreadViewPosts extends XFCP_EWRporta2_ViewPublic_ThreadViewPosts
{
    public function renderJson()
    {
        $response = parent::renderJson();
        $articleModel = XenForo_Model::create('EWRporta2_Model_Articles');
       
        if ($article = $articleModel->getArticleByThreadId($this->_params['thread']['thread_id']))
        {
            if(!empty($article['article_options']['comments']))
            {
                foreach ($this->_params['posts'] AS $postId => $post)
                {
                    $output['messagesTemplateHtml']["#post-$postId"] =
                        $this->createTemplateObject('EWRporta2_Article_Post', array_merge($this->_params, array('post' => $post)))->render();
                }
            }
        }
       
        return $response;
    }
}

It doesn't seem to be rewriting the response though and inline-edits are still return the 'post' template.
 
You're returning $response that was generated by the parent function. You'll need to regenerate the response if it's an article with:

Code:
return XenForo_ViewRenderer_Json::jsonEncodeForOutput($output);

Make sure you have all of the required keys inside the $output array as well,

Code:
$output['css'] = $template->getRequiredExternals('css');
$output['js'] = $template->getRequiredExternals('js');

Try the attachment, not sure if it'll work as it's untested and just theory based on what you provided.
 

Attachments

Last edited:
Top Bottom