News:

Want to get involved in developing SMF? Why not lend a hand on our GitHub!

Main Menu

Adding a sidebar without template edits

Started by Robert., December 18, 2011, 07:05:12 AM

Previous topic - Next topic

Robert.

G'day!
Yesterday I released v2.0 Final of my software and I think it's time to take a break and do something else instead.
I came up with the idea of a sidebar mod for SMF, so I started thinking. How would I do that? I know I can edit
templates and css, but that's what I want to avoid. Does anyone know how I can add a sidebar without theme edits
on every page? Just a sidebar, I don't care how big it is. I used Google, but they said I need to use layers, but
I still don't really understand. Perhaps there is a better way. Any ideas?

Bugo

http://wiki.simplemachines.org/smf/Integration_hooks

Hooks that may be useful for you:
integrate_pre_include
integrate_load_theme
integrate_buffer

Robert.

Thanks for your reply Bugo :D Still not sure how hooks work and how I can add a sidebar without theme edits though :P

SoLoGHoST

You can create your own theme (template.php) file and use that instead.  use the pre_include hook to include your source file, load_theme hook for your own template, and integrate_buffer could be used for placement of the template onto the page for where you want it to be placed (left, right, top, bottom).  Just my 2 cents on that.  I'm not an SMF Expert, but that's where I would start.

Robert.

Thanks for your reply SoLoGHoST :) Going to check 'em out asap

IchBin™

In order to add your sidebar without theme edits, you'll need to use the layers in SMF theme system. Here's a brief explanation that I got from Bloc at one time which helped me understand them.
Quote- Say you just added a new action and do all sorts of stuff inside Yourpage.php, and now gonna render the template. First you add a layer by adding a name to the variable $context['template_layers'].this HAS to be done BEFORE calling the template(which you nromally doa t the ery end of Yourpage.php, or a function within it)

    $context['template_layers'][] = 'yourpage';

    Then SMF will now try execute "template_yourpage_above" and "template_yourapge_below". So you just stick whatever you want into these two, much like "template_body_above". Like a sandwich lol.

    Those two functions needs to be loaded in though, and thats where loadtemplate('yourpage'); comes in: You stick the two functions into a file called "yourpage_template.php" and put it into Themes/default. Its important that naming is consistant, otherwise SMF won't find it.

    Done.

    .....

    Now, often you like do subtemplates for example, for a specific part of your page/mod. That would then be executed BETWEEN the function "template_yourpage_above" and "template_yourpage_below", and needs to be named like this:

    $context['sub_template'] = 'yourpage_mysub';

    Then SMF will try render things like this:

    - template_yourpage_above()
    - template_yourpage_mysub()
    - template_yourpage_below()

    So you just put all those functions into yourpage.template.php. You can add more by just setting the correct subtemplate + making sure the function exist in the template.
IchBin™        TinyPortal

Robert.

Thanks for your reply :) So, I can create a sidebar by putting the normal content in a specified width? Like this:

- Width, float, etc
- Sidebar
- Close the above
- Width and float
- Regular content
- Close the above

IchBin™

Not sure I understand your list of explanation, but yes you can put any column and specify the width of course.
IchBin™        TinyPortal

Matthew K.

You could also use... $context['insert_after_template'] .= ''; which would allow you to do the same thing.

Robert.

Thank you both, going to try out that tomorrow :D

Matthew K.

Pretty simple, you just need to make sure you add your stuff after the variable is defined, or it'll redefine it as nothing.

So, open ./Sources/Load.php and search for the following:
Code (Find) Select
$context['insert_after_template'] = '';
Code (Add After) Select
$context['insert_after_template'] .= 'Your Code';

IchBin™

Yeah it's too bad there's no insert_before_template
IchBin™        TinyPortal

Matthew K.

Yeah, seriously. It'd be simple to add...

emanuele

* emanuele thanks IchBin and Bloc and goes to the wiki in order to write the explanation in a very easy to find place! ;D


Take a peek at what I'm doing! ;D




Hai bisogno di supporto in Italiano?

Aiutateci ad aiutarvi: spiegate bene il vostro problema: no, "non funziona" non è una spiegazione!!
1) Cosa fai,
2) cosa ti aspetti,
3) cosa ottieni.

IchBin™

That's a great idea, if you don't do it let me know and I'll put it up there somewhere.
IchBin™        TinyPortal


bloc

Quote from: Labradoodle-360 on December 22, 2011, 01:04:48 PM
You could also use... $context['insert_after_template'] .= ''; which would allow you to do the same thing.
I see a problem with that..if anything else also adds itself to this variable it will possibly end up BEFORE your bars or even mix them up if those are also an attempt at encapsulating more bars lol(for example Ads mods).

Its better to put it in a layer, then add that layer to the $context. Then everything added to the before_template variable will also get into the content bar of your setup, leaving your sidebar ALWAYS present where it should. I assume the before_tempalte is added after any layers are executed, haven't checked.

Matthew K.


bloc

Let say a mod adds something to the "after_" variable, for example a wide image etc. Then you add your table, which then comes before this image...or content. Then your sidebar cannot control whether this output comes in the same bar as the other content. If you use the layers, the "after_" content will sit nicely with the rest of he content and your sidebar go all the way down along with it.

Its perhaps a subtle difference, but you have more control over the layout using layers. Besides, if a mod adds something before your that are wrong HTML, chances are its harder to find it, than examining what layers are added.

But above all, Unknown made the theme layer system precisely for this kind of use: to add or encapsulate content around SMF content, like layers in a onion.They can be re.arranged even, something just the "after_" (and perhaps "before_") will have a harder time to do. Example:  a mod wants no HTML layers, since its a splash page...easy, just null out all layers, and supply just their own. If anything is added to "after_" it will be just another part of the content, which its meant to be.Or rather to stick content in there, right after SMF content, but before the closing of the HTML/Body tags.

ascaland

Its too bad changes still need to be made for users with custom themes when it comes to modifying template layers, which is essentially the same annoyance with using the integrate_buffer hook. With sites having a lot of themes and template layer changes this could probably be tedious, unless the modification includes a file at the very beginning of execution using a hook with the 'layer functions' in the included template file. Seems pretty pointless for small mods that just need to slightly change a part of the template layers, or with many mods which modify the template layers. This could mean many template files being included for something that can be a very simple change.

In this case, I think a 'generic template' would be pretty good to have for SMF. Simply have the one file included along with the default index template file to pre include template functions and there you have it, a template file independent of themes. Rather than modifying a bunch of template files for something so simple, place it all in one file.

For example,
<?php

function template_GenericTemplate_init() {
   
   global
$settings;
   
   
// Prevents overriden caught actions being overwritten
   
if (!isset($settings['catch_action']))
       
// Custom generic action!
       
$settings['catch_action'] = array(
           
'template' => 'GenericTemplate',
           
'sub_template' => 'customActions'
       
);
}

// Specific "catch action" for Curve only!
function template_curveOnlyAction() {
   echo
'Executed from curve. Overriden from initial loading.';
}

// Sub templates usage
function template_customActions() {
   
   global
$context;
   
   if (
$context['current_action'] == 'test')
       echo
'my custom action';
   else
       
aCustomActionSubTemplate();
}

function
aCustomActionSubTemplate() {
   echo
'wat';
}

// Some layers - for a mod perhaps?
function template_grnTest_above() {
   
   global
$context, $settings;
   
   echo
'hello header!';
}

function
template_grnTest_below() {
   
   global
$context, $settings;
   
   echo
'hello footer!<br /><pre>';
   
print_r($context);
   echo
'<pre>';
}

?>


There you have it, generic custom actions using the templates (which can even be overriden for specific-template if need be), along with the layer solution.

That is just my two cents.

Advertisement: