GetSimple Support Forum
Function: per page components. - Printable Version

+- GetSimple Support Forum (http://get-simple.info/forums)
+-- Forum: GetSimple (http://get-simple.info/forums/forumdisplay.php?fid=3)
+--- Forum: Scripts & Components (http://get-simple.info/forums/forumdisplay.php?fid=11)
+--- Thread: Function: per page components. (/showthread.php?tid=204)



Function: per page components. - Zegnåt - 2009-10-31

For a layout I was messing around with I wanted to be able to adjust the footer for certain pages only. As I thought I had seen something like that here on the forum I did a little search. I found a question by TwentyTwoBelow asking about the ability to set up components on a per page basis.

Chris came up with a way to do it:
Code:
if ( return_page_slug() == 'about' ) {
    get_component('about-component');
} elseif ( return_page_slug() == 'index' ) {
    get_component('homepage-component');
} else {
    get_component('generic-component');
}
However, I feel this will get very frustrating in the long run as I will have to edit the template for every page I want to use a different component on. I do like the idea Chris coined, placing different labels in front of the component name. If only this could be automated...

Well, of course it can be automated!

I wrote my own get_component() function called component_master(), that you can find at the bottom of this topic. If you want to use it for your template just put it in the functions.php that you have (or must create) in your theme folder.

How to use it, an example.

In the basic theme Cardinal you will find the following piece of code in the template.php:
Code:
<div class="section">
            <?php get_component('sidebar'); ?>
        </div>
Change it to this:
Code:
<div class="section">
            <?php component_master('sidebar'); ?>
        </div>
That's all. Nothing should break and it should still include the contents of the sidebar component.

To change the sidebar on the homepage we don't have to change anything in the theme any more. All we do is add a new component on the components page of the admin panel. If we create a component called index-sidebar this component will overwrite the one called sidebar on our homepage but on no other pages!

By simply putting the slug of the page we want to target in front of the component name it will show up. Of course, all pages that you don't specifically target with different components get the one with the name we put into the component_master() function. In the case of our example all pages that don't have a matching component will be showing the content of the component called sidebar.

What if I don't want to overwrite but just want to add something?

I thought about this and came up with a solution. If you want the generic component to show but want to add a per page component you can create components named with the following pattern: slug-extra-component. To fall back on my previous example I could create a component called index-extra-sidebar and this one will be appended to the sidebar component. Of course if slug-component (eg. index-sidebar) exists the extra component is ignored.

In case your template needs the extra addition to the component to not follow the generic one but be rendered before it you want to change your template.php a little.

You will need to call the component_master() function with an extra argument:
Code:
component_master('sidebar',true);

Now the order of the way it prints the components will be turned around.

The function as is.

I provide this function as it is. I will probably update it when a GetSimple update breaks it or when others come up with suggestions, but I won't promise that. If anything suddenly wipes your system clean when you use this, don't look at me either.
Code:
function component_master($id,$first=false) {
        if (file_exists('data/other/components.xml')) {
            $master = return_page_slug();
            $extra = false;
            $standard = false;
            $thisfile = file_get_contents("data/other/components.xml");
            $data = simplexml_load_string($thisfile, NULL, LIBXML_NOCDATA);
            $components = $data->item;
            
            if (count($components) != 0) {
                foreach ($components as $component) {
                    if ($master.'-'.$id == $component->slug) {
                        eval("?>" . stripslashes(htmlspecialchars_decode($component->value, ENT_QUOTES)) . "<?php ");
                        return;
                    } elseif ($master.'-extra-'.$id == $component->slug) {
                        $extra = $component->value;
                    } elseif ($id == $component->slug) {
                        $standard = $component->value;
                    }
                }
                if ($standard) {
                    eval("?>" . ($extra&&$first?stripslashes(htmlspecialchars_decode($extra, ENT_QUOTES)):'') . stripslashes(htmlspecialchars_decode($standard, ENT_QUOTES)) . ($extra&&!$first?stripslashes(htmlspecialchars_decode($extra, ENT_QUOTES)):'') . "<?php ");
                }
            }
        }
    }



Function: per page components. - GetSimple.RU - 2009-11-13

Thanks for this!


Function: per page components. - Zegnåt - 2009-11-14

GetSimple.RU Wrote:Thanks for this!
Nice to hear someone likes it. Be sure to let me know how it works out for you!


Function: per page components. - focoves - 2009-12-15

Hi Zegnåt,
thanks for sharing this !
is very usefull
and great explanation ... (mm teacher?)

I'm trying to implement it, but got some on function.php pasted code ... Could you check it please? or just attach the file.
thanks again


Function: per page components. - Zegnåt - 2009-12-15

focoves Wrote:is very usefull
Thanks!

focoves Wrote:teacher?
Hahaha, far from. I’m only 18 years old, sorry to let you down ;-)

focoves Wrote:I'm trying to implement it, but got some on function.php pasted code ... Could you check it please?
If you have nothing else in functions.php be sure to not forget the <?php and ?> around the function, to make it PHP.

Still problems? Attach your functions.php and I’ll be happy to take a look.


Function: per page components. - tyee - 2010-02-10

This is great. I'm going to try it now. I have been using WolfCMS which like GS is small and fast. It also has this feature called "Page Parts" which is the same as per page components.

One thing I am concerned with is that all these addons (which are awesome, btw) should be included as plugins and not code hacking. I was using sNews a few years ago but left that because all they would do is hack the code, which works, but on program update, you have to hack it all again just to get what you had. That was very frustrating to say the least. I hope GS does not turn into this. I know GS is young and growing which is great, but I hope feature additions will be done as plugins.

Keep up the good work everyone!


Function: per page components. - tyee - 2010-02-10

Update! Installed fine. I put a slideshow in the sidebar and it only shows on the index page which is correct. However, on the other pages Firefox is now giving me a warning that "DIV with ID XX not found on page". Of course Firefox, it's not supposed to be there. The thing is the slideshow script is in the head of the template and that's why Firefox is expecting that DIV.

Am I missing something here? Can I not use a slideshow script in the head of the template??

Update - Found bug in slideshow.js


Function: per page components. - Origin - 2010-05-20

I just wanted to say your solution works great. I'd love the ability to add multiple sidebar components for each specific page, but this much, much easier than the


Function: per page components. - jasonbill - 2010-10-12

You did well because it is easier process. Is it working properly in IE or safari?
If it is working properly i will use it in my new upcoming websites.


Function: per page components. - Zegnåt - 2010-10-13

jasonbill Wrote:Is it working properly in IE or Safari?
It works in all browsers, because the system is 100% PHP and everything runs on the server.


Function: per page components. - quite_me - 2010-11-19

Hi Zegnåt,

thanks for this function, it's very useful.

In one of my project I need to change a component in page by return_page_slug and return_parent, so I modified your first script in
Code:
if ( return_page_slug() == 'index' ) {
                get_component('component-1');
            } elseif ( return_page_slug() == 'page-1' ) {
                get_component('component-2');
            } if ( return_parent() == 'index' ) {
                get_component('component-1');
            } elseif ( return_parent() == 'page-1' ) {
                get_component('component-2');
            }

As you can see I'm not a php coder, so I would like to know if the script is ok about you or you have to suggest something to me.

Thanks in advance!


Function: per page components. - Zegnåt - 2010-11-20

Your script is based more on Chris’ function than on mine. But let me put in a comment.

You will want to change line 5 to elseif instead of just if. It will save PHP some computing time. Also, the way it is now if page-1 is the child of index it will show both component-2 and component-1. I don’t think that’s what you want.

What you want is this:
Code:
if ( return_page_slug() == 'index' ) {
     get_component('component-1');
} elseif ( return_page_slug() == 'page-1' ) {
     get_component('component-2');
} elseif ( return_parent() == 'index' ) {
     get_component('component-1');
} elseif ( return_parent() == 'page-1' ) {
     get_component('component-2');
}
You could also make the if-clauses a little longer and get down to only 2 seperate checks:
Code:
if ( return_page_slug() == 'index' || return_parent() == 'index' ) {
     get_component('component-1');
} elseif ( return_page_slug() == 'page-1' || return_parent() == 'page-1' ) {
     get_component('component-2');
}
Hope you’ll be able to put this to use!


Function: per page components. - quite_me - 2010-11-20

Zegnåt Wrote:You could also make the if-clauses a little longer and get down to only 2 seperate checks:
Code:
if ( return_page_slug() == 'index' || return_parent() == 'index' ) {
     get_component('component-1');
} elseif ( return_page_slug() == 'page-1' || return_parent() == 'page-1' ) {
     get_component('component-2');
}
Works like a charm and it is really elegant, much more than mine, this is for sure!

Many thanks Zegnat!

I'll publish the site in the right forum section when it will be finished, hope you'll have a look to it.


Function: per page components. - vladislav - 2011-04-13

Did anyone try it with 3.0?


Function: per page components. - Oleg06 - 2011-04-13

yes works


Function: per page components. - crusher88 - 2011-05-16

Thanks! This made life easier since I basically want to have different sidebar content on each page.

Is there any way of combining this function with the i18n plugin?
http://get-simple.info/extend/plugin/i18n/69/?

The plugin wants me to replace get_component with get_i18n_component, which obviously conflicts with the
Code:
<div class="section">
            <?php component_master('sidebar'); ?>
        </div>

Any help appreciated! Smile


Function: per page components. - mvlcek - 2011-05-17

crusher88 Wrote:Thanks! This made life easier since I basically want to have different sidebar content on each page.

Is there any way of combining this function with the i18n plugin?
http://get-simple.info/extend/plugin/i18n/69/?

You could of course change the component master function to behave "I18Nily".

Or you can use Chris' way to do it, where you can replace get_component with get_i18n_component.

Or you can do it like this (example for additional language German):
  • Install the I18N CustomFields plugin
  • Create your sidebar components, e.g. "sidebar1", "sidebar1_de", "sidebar2", "sidebar2_de", ...
  • Goto Plugins/Configure I18N Custom Fields and add a field named "sbcomp", text "Sidebar", type "dropdown" and enter an empty line and all possible sidebars below the type, e.g.
Code:
sidebar1
sidebar2
  • Edit each page which should have a custom sidebar component and select the corresponding component from the list, then save.
  • Include the following code in your template:
Code:
<?php get_i18n_component(return_custom_field('sbcomp') ? return_custom_field('sbcomp') : 'sidebar'); ?>
This assumes that you have a standard sidebar component "sidebar" (and "sidebar_de") that you want to display, if the custom field is not set.

The advantage to Zegnat's approach is that you can use a component for multiple pages, a disadvantage might be that you have to select the sidebar component per page.


Function: per page components. - crusher88 - 2011-05-17

mvlcek Wrote:Or you can do it like this (example for additional language German):
  • Install the I18N CustomFields plugin
  • Create your sidebar components, e.g. "sidebar1", "sidebar1_de", "sidebar2", "sidebar2_de", ...
  • Goto Plugins/Configure I18N Custom Fields and add a field named "sbcomp", text "Sidebar", type "dropdown" and enter an empty line and all possible sidebars below the type, e.g.
Code:
sidebar1
sidebar2
  • Edit each page which should have a custom sidebar component and select the corresponding component from the list, then save.
  • Include the following code in your template:
Code:
<?php get_i18n_component(return_custom_field('sbcomp') ? return_custom_field('sbcomp') : 'sidebar'); ?>

Thanks a lot! This was excactly what I was looking for.

Sorry, Zegnåt, didn't mean to hijack your thread!