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

How to add code before or after a condition (Hook)

Zephyr

Well-known member
#1
Hello, how to add code before or after a condition or some text without editing the template (using hook) please?
 

Zephyr

Well-known member
#3
Already seen but I'm stuck.

My hook:

PHP:
<?php
 
class XenCrea_ColorPicker_Hook_ColorPicker
{
    public static function templateHook($hookName, &$contents, array $hookParams, XenForo_Template_Abstract $template)
    {
        switch ($hookName)
        {
            case 'breadcrumb':
            {
                  // here, how add text before or after <xen:if is="{$navigation}"> please ?
            }
        }
    }
}

Template breadcrumb:

PHP:
            // ... My text here
            <xen:if is="{$navigation}"> //Line to replace.
            // ... or here
                <xen:foreach loop="$navigation" value="$breadcrumb" i="$i" count="$count">
                    <span class="crust"{xen:if $microdata, ' itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb"'}>
                        <a href="{xen:raw $breadcrumb.href}" class="crumb"{xen:if $microdata, ' rel="up" itemprop="url"'}><span{xen:if $microdata, ' itemprop="title"'}>{xen:raw $breadcrumb.value}</span></a>
                        <span class="arrow"><span>&gt;</span></span>
                    </span>
                </xen:foreach>
            </xen:if>
        </span>
    </fieldset>
</nav>
 

Chris D

XenForo developer
Staff member
#5
First of all, your code is looking for a template hook called 'breadcrumb'.

There is a template called breadcrumb, but there isn't a hook called breadcrumb.

You can only play with template content that sits between template hook tags.

A template hook tag looks like:

<xen:hook name="body">

You will probably want to use the page_container_breadcrumb_top hook.

This is the hook that contains the breadcrumb template.

The code within that hook is:

<div class="breadBoxTop">
<xen:if is="{$topctrl}"><div class="topCtrl">{xen:raw $topctrl}</div></xen:if>
<xen:include template="breadcrumb"><xen:set var="$microdata">1</xen:set></xen:include>
</div>

With that in mind you might want to try something like:

PHP:
<?php
 
class XenCrea_ColorPicker_Hook_ColorPicker
{
    public static function templateHook($hookName, &$contents, array $hookParams, XenForo_Template_Abstract $template)
    {
        switch ($hookName)
        {
            case 'page_container_breadcrumb_top':
            {
                  $contents = str_replace('<div class="breadBoxTop">', '<div class="breadBoxTop">YOUR TEXT HERE', $contents);
            }
        }
    }
}
 

Zephyr

Well-known member
#7
Hello, I have this:

PHP:
            case 'page_container_head':
            {
                $codeToReplace        = '<!--XenForo_Require:JS-->';
                $remplacementCode    = '<!--XenForo_Require:JS-->
 
                    <xen:include template="XenCreaColorPickerCookie.js" />
                    <xen:include template="XenCreaColorPicker.js" />
                    <xen:include template="XenCreaColorPickerExtra.js" />
                ';
 
              $contents = str_replace($codeToReplace, $remplacementCode, $contents);
            }
But javascript is not loaded, code is not parsed ?
And </head> and <body> is duplicated (a problem with my hook).

Html Source:


Do you know why please? :)

Complete file:

PHP:
<?php
class XenCrea_ColorPicker_Hook_ColorPicker
{
    public static function templateHook($hookName, &$contents, array $hookParams, XenForo_Template_Abstract $template)
    {
        switch ($hookName)
        {
            case 'page_container_breadcrumb_top':
            {
              $contents = str_replace('<fieldset class="breadcrumb">', '<fieldset class="breadcrumb">
       
                <!-- .... -->
 
              ', $contents);
            }
     
            case 'page_container_head':
            {
                $codeToReplace        = '<!--XenForo_Require:JS-->';
                $remplacementCode    = '<!--XenForo_Require:JS-->
         
                    <xen:include template="XenCreaColorPickerCookie.js" />
                    <xen:include template="XenCreaColorPicker.js" />
                    <xen:include template="XenCreaColorPickerExtra.js" />
                ';
     
              $contents = str_replace($codeToReplace, $remplacementCode, $contents);
            }
        }
    }
}
?>
 

Zephyr

Well-known member
#8
It's good now :)

PHP:
<?php
class XenCrea_ColorPicker_Hook_ColorPicker
{
    public static function templateHook($hookName, &$contents, array $hookParams, XenForo_Template_Abstract $template)
    {
        switch ($hookName)
        {
            case 'page_container_breadcrumb_top':
            {
              $contents = str_replace('<fieldset class="breadcrumb">', '<fieldset class="breadcrumb">
             
                    <!-- ... -->
 
              ', $contents);
            }
           
            case 'page_container_head':
            {
                $Template1 = $template->create('XenCreaColorPickerCookie.js', $template->getParams());
                $rendered1 = $Template1->render();
 
                $Template1 = $template->create('XenCreaColorPicker.js', $template->getParams());
                $rendered2 = $Template1->render();
 
                $Template1 = $template->create('XenCreaColorPickerExtra.js', $template->getParams());
                $rendered3 = $Template1->render();
 
                $contents .= $rendered1;
                $contents .= $rendered2;
                $contents .= $rendered3;
            }
        }
    }
}


But the javascript is displayed inside the source code:
Is there a more "clean" methode please? :)

 

Chris D

XenForo developer
Staff member
#9
You should put your code into js files, not into the template system.

So physically create files at, e.g:

js/XenCrea/XenCreaColorPickerCookie.js

And then you can call that in your Listener.

So instead of $template->create use this instead to add an external JS file:

PHP:
$template->addRequiredExternal('js', 'js/XenCrea/XenCreaColorPickerCookie.js');
EDIT: I also note that in your example above, that you're implementing a Cookie plugin. XenForo has this functionality built in.

To set a Cookie use:

$.setCookie('name', 'value');

To get a Cookie use:

$.getCookie('name');
 

Zephyr

Well-known member
#10
Thanks :)
But I have:

$template->preloadTemplate('XenCreaColorPickerCookie.js');
$template->preloadTemplate('XenCreaColorPicker.js');
$template->preloadTemplate('XenCreaColorPickerExtra.js');

It's optional now ? :)

Else it's possible to minify the javascript?
The template system tell me an error when I did that.

External js compatible with minify ?
 

Chris D

XenForo developer
Staff member
#11
It really isn't normal to display javascript inline in the raw HTML.

It is always best practice to have Javascript in external js files.

Ideally - and you will see it done this way in most add-ons - you will create your own templates which you add via hooks. Those templates can include external js using <xen:require js="js/YourAddOn/YourJsFile.js" />.

If for whatever reason you can't or don't need your own templates, you can certainly use the method I mentioned above which would be:

$contents .= $template->addRequiredExternal('js', 'js/XenCrea/XenCreaColorPickerCookie.js');

The benefit then is that it is more optimal for the browser, should improve page load time, SEO, the javascript can be cached by the browser to save http requests and best of all, it can be minified which as you've found out - you cannot use minified JS code in raw HTML.