• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.
  • This forum has been archived. New threads and replies may not be made. All add-ons/resources that are active should be migrated to the Resource Manager. See this thread for more information.

Creating a beautiful looking SPOILER tag...

Jaxel

Well-known member
#1
I've never liked how most spoiler tags look on forums. Now with XenForo, we finally have something to work with that is truly beautiful.

I do all customization on my forum to a product called "EWRcustom", its basically an Add-On that I don't release to the public, which contains all my custom settings and changes. This add-on has things like my sub forum grid listing, advert placements, thread sticky separations, user ribbons, etc. There are many hooks, custom models, listeners etc in this custom add-on of mine, but I will not be releasing the most of them to the public.

Today I will show you how to do the spoiler tags I have on 8WAYRUN...
http://www.8wayrun.com/threads/8wayrun-com-now-running-the-xenforo-beta.6406/page-10#post-237171

First you have your listener class:
Code:
<?php
 
class EWRcustom_Listener_BbCode
{
    public static function listen($class, array &$extend)
    {
        if ($class == 'XenForo_BbCode_Formatter_Base')
        {
            $extend[] = 'EWRcustom_BbCode_Formatter';
        }
    }
}
This listener extends the EWRcustom BbCode Formatter into the existing BbCode Formatter Base.

Then you have your EWRcustom BbCode Formatter:
Code:
<?php
 
class EWRcustom_BbCode_Formatter extends XFCP_EWRcustom_BbCode_Formatter
{
    protected $_tags;
 
    public function getTags()
    {
        $this->_tags = parent::getTags();
 
        $this->_tags['spoiler'] = array(
            'trimLeadingLinesAfter' => 1,
            'callback' => array($this, 'renderTagSpoiler')
        );
 
        return $this->_tags;
    }
 
    public function renderTagSpoiler(array $tag, array $rendererStates)
    {
        $content = $this->renderSubTree($tag['children'], $rendererStates);
        $spoiler = $tag['option'];
 
        if ($this->_view)
        {
            $template = $this->_view->createTemplateObject('EWRcustom_spoiler', array(
                'content' => $content,
                'spoiler' => $spoiler
            ));
            return $template->render();
        }
        else
        {
            $name = '<div>' . new XenForo_Phrase('spoiler_warning') . ($spoiler ? ': '.$spoiler : '') . '</div>';
            return '<blockquote>' . $name . $content . '</blockquote>';
        }
    }
}
Its pretty simple, it looks for the
tag, then determines view information, as well if the post is using
or
. It then references a custom template called EWRcustom_spoiler.

Next we create that custom template "EWRcustom_spoiler".
Code:
<xen:require css="bb_code.css" />
<xen:require css="EWRcustom_spoiler.css" />
<xen:require js="js/8wayrun/EWRcustom_ajax.js" />
 
<div class="bbCodeBlock bbCodeQuote bbCodeSpoiler">
    <aside>
        <div class="spoilerBar attribution type">
            <div class="spoilerWarning">
                <b>{xen:phrase spoiler}</b><xen:if is="{$spoiler}">: {$spoiler}</xen:if>
            </div>
            <a href="#" class="spoilerToggle button primary">{xen:phrase toggle_spoiler}</a>
        </div>
        <blockquote class="spoilerContent">{xen:raw $content}</blockquote>
    </aside>
</div>
Next we create that custom template "EWRcustom_spoiler.css".
Code:
.bbCodeBlock.bbCodeSpoiler .spoilerBar { text-align: right; }
.bbCodeBlock.bbCodeSpoiler .spoilerBar .spoilerWarning { float: left; }
.bbCodeBlock.bbCodeSpoiler .spoilerBar .spoilerWarning b { font-size: 19px; }
Very simple template, you will notice that it references a custom JS file. You will now have to create this JS file. And yes, I know its not actually using AJAX, but thats just what I name every javascript I do with XenForo that uses it's jQuery base.
Code:
/** @param {jQuery} $ jQuery Object */
!function($, window, document, _undefined)
{
    XenForo.Spoiler = function($spoiler)
    {
        var $content = $spoiler.find('.spoilerContent:first').hide();
 
        $spoiler.find('.spoilerToggle:first').click(function(e)
        {
            e.preventDefault();
            $content.toggle('slow');
        });
    }
 
    // *********************************************************************
 
    XenForo.register('.bbCodeSpoiler', 'XenForo.Spoiler');
}
(jQuery, this, document);
Simple, first thing it does is find all spoiler zones and hides them... then links the spoiler toggle link to a toggle function. With this system, spoiler zones degrade gracefully, so if a user doesn't have javascript, they will still be able to access the relevant information.

Then, simply create the code event listener in your AdminCP.
(I will not write a tutorial on how to do this as there are already several on this forum)
 
#10
Where did you put the spoiler.js? Everything is supposed to be in library/spoiler/.
Edit: I can't access any files in library/spoiler, could you please check the CHMOD permissions?
 
#12
HTML:
Forbidden
You don't have permission to access /forums/library/spoiler/spoiler.js on this server.
I guess that's the problem. Set chmod 644 the php and js files and 755 the spoiler directory.
 
#14
Found the problem, I will update the package and re-upload it.

Edit: Done, please re-upload the files and upgrade the add-on. The library directory is .htaccess protected, I have to place the js file into the appropriate js folder.