SSbits - Home page
Site by Carbon Crayon
Submit a Post >

Tutorials - Big bits of code to help you do more

Create a front end theme switcher

So you wanna make a demo site for your customers to show all your template skills in one site. A simple theme switcher can come in handy. It's quite easy to implement this. 

First add two new functions to your Page_Controller class:

function themeSwitcher(){    
        $folders = scandir(Director::baseFolder()."/themes");
        $exclude = array(".", "..", ".DS_Store", "_notes");
        $themes = array_diff($folders, $exclude);
        $selected = Session::get('theme');
        
        $fields = new FieldSet(
          $fields =      new DropdownField('theme','theme', $themes, $selected, '', 'Select Theme')
      );
        $actions = new FieldSet(
          new FormAction('switchTheme', 'Switch')
      );
      return new Form($this, "switchTheme", $fields, $actions); 
    }
    
    function switchTheme($data){        
        if($data['theme']){
            Session::set('theme', $data['theme']);    
        } else {
            unset($_SESSION['theme']);
        }
        Director::redirect(Director::baseURL(). $this->URLSegment);
    }

The first function themeSwitcher() will scan the themes folder for themes and create a dropdown menu with all templates. The exclude array and array_diff will exclude the dots and Apple DS_Store files and Dreamweaver _notes folders. You could use this array to add themes you want to exclude in the switch.

The Session::get('theme') will get the selected theme which will be set in the second function. The last part creates the dropdown field and form.

The second function switchTheme($data) will process the form and set the selected theme as session data, so the theme change will be remembered when you navigate through your site. I added an if/else to unset the theme session variable. This is done to prevent errors when 'Select Theme' is selected, which returns 0. The default theme that is set in your _config.php will be used by default.

The Director rule will bring you back to the page where you selected a new theme.

The last bit of code will be placed in the function init() of your Page_Controller before the Requirements rules.

$theme = Session::get('theme');
        if($theme){
            $folders = scandir(Director::baseFolder()."/themes");
            $exclude = array(".", "..", ".DS_Store", "_notes");
            $themes = array_diff($folders, $exclude);
            
            SSViewer::set_theme($themes[$theme]);
        }

Since the dropdown field created by SilverStripe populate the option values with integers, we need to translate those integers with the actual theme name. That's why we scan the theme folder again.

First we get the selected theme from the session variable, check if it is set to prevent errors and set the new theme with SSViewer.  Since the $themes is an array we only need to pick the selected folder name with $themes[$theme].

Now you only need to place the form somewhere in your templates by using the variable $themeSwitcher and you are able to change your themes with a simple form.

Note: remember to add $themeSwitcher in all your themes you have in your dropdown field.

Martijn van Nieuwenhoven avatar

Martijn van Nieuwenhoven

Martijn van Nieuwenhoven is a freelance Silverstripe developer based in the Netherlands and runs the largest Dutch Jobboard for Media, Marcom and Graphic related jobs.

  • Cigaweed
    03/04/2011 9:08pm (3 years ago)

    I love this approach, and it's awesome if you're a total SS Nub like me but i'm having issues when switching themes. Would it be possible to get an example or where exactly i should be putting the $themeSwitcher call in each page.ss of my templates?

  • Dredd
    25/04/2012 3:18pm (2 years ago)

    This didn't work for me, so I came up with my own solution ( SS v.2.4.7) :
    1. Added private var $_config to Page class
    2. Added following code to Page_Controller::init()
    $this->_config = SiteConfig::current_site_config();
    3. ThemeSwither function:
    public function ThemeSwitcher()
    {
    $themes = $this->_config->getAvailableThemes();
    $selected = SSViewer::current_theme();
    $fields = new FieldSet(
    new DropdownField(
    'theme',
    'Theme',
    $themes,
    $selected)
    );
    $actions = new FieldSet(
    new FormAction('SwitchTheme', 'Switch')
    );
    return new Form($this, 'ThemeSwitcher', $fields, $actions);
    }
    4. SwitchTheme function:
    public function SwitchTheme($data)
    {
    if ($data['theme']) {
    SSViewer::set_theme($data['theme']);
    $this->_config->Theme = $data['theme'];
    $this->_config->write();
    }
    Director::redirect(Director::baseURL() . $this->URLSegment);
    }
    5. To allow switching in a theme use $ThemeSwitcher in template

Post a comment ...

You cannot post comments until you have logged in. Login Here.

Advertisement

Site of the Month

Find SSbits on

Top Contributers

Rank Avatar Name
1 article image Aram Balakjian
2 article image Daniel Hensby
3 article image Marcus Dalgren
4 article image Hamish Campbell
5 article image Ty Barho
6 article image njorndare
7 article image Martijn van Nieuwenhoven
8 article image Darren-Lee
9 article image Roman Schmid
10 article image Matt Clegg

View full leaderboard


Advertisement