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

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

Discussion in 'XenForo Development Discussions' started by Jaxel, Nov 30, 2014.

  1. Jaxel

    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.
     
  2. Jake B.

    Jake B. Well-Known Member

    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: Dec 1, 2014
    Digital Doctor likes this.
  3. Jake B.

    Jake B. Well-Known Member

    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.
     
    Digital Doctor likes this.
  4. Jaxel

    Jaxel Well-Known Member

    Thanks, thats exactly what I was looking for.
     
  5. Jaxel

    Jaxel Well-Known Member

    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.
     
  6. Jake B.

    Jake B. Well-Known Member

    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.
     

    Attached Files:

    Last edited: Dec 4, 2014
    Mike Creuzer likes this.
  7. Jaxel

    Jaxel Well-Known Member

    Yep, that was it. I simply forgot those last 4 lines.
     

Share This Page