We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 813 ☆ A M B ☆
    • 326 Posts
    I’ve gotten really good at begging for help in the last few months, so I thought it was high time for me to give something back to this amazing community wink If this has already been demonstrated elsewhere or if any advanced users see a coding issue with what I’ve created, please let me know!

    I’m currently building a site for a Lutheran church, and they wanted certain visual elements to be changeable depending on the current liturgical church season. My immediate thought was to build a dynamic, TV-based CSS switcher like the one described in the MODx Wiki (http://wiki.modxcms.com/index.php/Dynamic_CSS_with_TVs). However, it was just slightly different from what I was wanting to accomplish. Unlike the tutorial, which alters the CSS on a page-by-page basis, I wanted a single drop-down menu that would change the stylesheet for the entire site. My solution uses a TV, a snippet and some quick-and-dirty API trickery to pull this off.

    Here’s how it works:

    1. Create a subdirectory in the /assets/ folder to store the CSS files you’ll be creating in Step 2. Honestly, it doesn’t really matter where you keep them, so long as they are all in the same folder (mine is located at /assets/css/seasons/).


    2. Create your stylesheet files. Each file should have a unique name (mine are called advent.css, easter.css, christmas.css, etc.) and contain all of the elements that will change with the seasons (i.e., colors, background images, fonts, etc.) Your main CSS file should still contain all of your other styles; these are only the elements that will change.


    3. In the <head> section of ALL of your site’s templates, after your main CSS file, add this line:

    <link type="text/css" rel="stylesheet" href="assets/css/seasons/[!AddCss!]" media="screen" />


    Adjust the path to match the one you created in Step 1.


    4. Create a new Snippet called "AddCss" and paste in the following code:

    <?php
    $tvCss = $modx->getTemplateVarOutput(array("cssfiles"),$docid='1',$published=1);
    echo $tvCss['cssfiles'];
    ?>


    (One important detail: in Step 5, you’ll be associating this Snippet with a single page via a Template Variable (probably your homepage). If the page you use has a different ID than 1, change it in the "docid" code above.)


    5. Create a new Template Variable called "cssfiles" and attach it ONLY to the template you want to change the stylesheets with (for me, it’s the homepage template). I’m pretty sure you only want to use this template for this one page -- duplicate it if you need to use the same template with other pages. Under "Input Type," choose "DropDown List Menu." Under "Input Option Values," add a list of items that corresponds with the names of the stylesheet files you created in Step 2 (i.e., Advent==advent.css||Easter==easter.css||Christmas==christmas.css).


    That’s it! Now edit your homepage, and you should see the DropDown List. Choose the stylesheet you want to use from the list, hit save, and the styles from that stylesheet should now be applied sitewide. I’m fortunate in that one (and only one) of these "special" stylesheets will always be in use, but if you need them to be optional or want to load more than one, it wouldn’t be too difficult to slightly alter the Snippet or use a little PHx to pull off the desired effect.

    Hope this comes in handy for someone else! I’m not quite good enough with PHP or the API to develop this into a full-fledged Snippet with parameters, but if anyone would like to take on that project, let me know.

      • 20413
      • 2,877 Posts
        @hawproductions | http://mrhaw.com/

        Infograph: MODX Advanced Install in 7 steps:
        http://forums.modx.com/thread/96954/infograph-modx-advanced-install-in-7-steps

        Recap: Portland, OR (PDX) MODX CMS Meetup, Oct 6, 2015. US Bancorp Tower
        http://mrhaw.com/modx_portland_oregon_pdx_modx_cms_meetup_oct_2015_us_bancorp_tower
        • 813 ☆ A M B ☆
        • 326 Posts
        Awesome! I’d seen the first method before, but not that second post. Thanks for the links! Correct me if I’m wrong, though, but wouldn’t both of those be page-specific? What I’ve done will be reflected site-wide.
          • 3749
          • 24,544 Posts
          If I’m understanding what you want to do, you could also just write a snippet that figures out what season it is and returns the name of the correct CSS file for that season. That way everything will change automatically with the seasons.

          I’ve got a season calculating function I wrote a while back. I can try to dig it up if you want it. smiley
            Did I help you? Buy me a beer
            Get my Book: MODX:The Official Guide
            MODX info for everyone: http://bobsguides.com/modx.html
            My MODX Extras
            Bob's Guides is now hosted at A2 MODX Hosting
            • 3604
            • 13 Posts
            You can even do this for inline style elements too if you want. Like, say, a a background image that you want changed. Not to mention dynamic favicons, and column layouts.
              • 813 ☆ A M B ☆
              • 326 Posts
              mrhaw: The @DIRECTORY binding is a great idea -- thanks! It eliminates the need to manually add new stylesheets to the TV as they’re created. The only disadvantage I see, although minor, is that it lists the file names as-is. My method gave you the ability to clean up the file names a little bit and eliminate some confusion for the client (i.e., christmas.css could show up as Christmas in the drop-down list). Is there a way to reformat the @DIRECTORY output that I’m not thinking of? If not, it’s not that big of a deal.

              BobRay: If you can find your old script, I would really appreciate that! I had a feeling someone with more experience had already created something similar, but I couldn’t find anything in the repository or forums. I’m not sure if the Lutheran calendar changes every year or follows the same pattern, but if it’s a pattern, this would work great.
                • 3749
                • 24,544 Posts
                Here it is. I spiffed it up a little, but there’s no language support for it and I’m not sure if the dates are good outside the USA.

                It should be very easy to modify to meet your needs. Let me know if you need help.

                <?php
                /* Season Snippet
                 * Author: Bob Ray
                 * Date: 08/09/09
                
                This snippet can be used to automatically produce seasonal changes on your web site.
                
                Usage:  [!Season!]
                        [!Season? &summer=`something` &fall=`something` &winter=`something` &spring=`something` !]
                
                The first version returns the name of the season.
                The second returns the appropriate "something." It could be a string, a chunk name, a URL, and image reference, or a file path.
                
                You could use this to change the CSS with the seasons by putting the path to a different CSS file 
                in each parameter and using the snippet call in your template where the CSS file is specified. 
                
                Using an image reference, it could be used to change an image or background image with the seasons. 
                
                If you put a chunk name for each parameter, a chunk tag containing the snippet call will output a different chunk for each season.
                
                Installation: Just paste this code into a snippet called "Season" (without the quotes) and save it.
                
                Note: If your page is cached, you may need to call the snippet uncached ([[Season]]).
                
                */
                
                /* This function returns the name of the current season */
                
                function season() {
                    $limits=array('/12/21'=>'Winter', '/09/21'=>'Fall', '/06/21'=>'Summer', '/03/21'=>'Spring', '/01/01'=>'Winter');
                    $adate = date("M d Y");  /* set $adate to today */
                
                    foreach ($limits AS $key => $value) {
                
                        $limit=date("Y").$key;
                         if (strtotime($adate)>=strtotime($limit)) {
                
                            return $value;
                        }
                    }
                }
                /* Set the defaults if parameters are not sent */
                
                $summer = empty($summer)? 'Summer' : $summer;
                $fall = empty($fall)? 'Fall' : $fall;
                $winter = empty($winter)? 'Winter' : $winter;
                $spring = empty($spring)? 'Spring' : $spring;
                
                
                /* pick the right one, and return it */
                        switch( season() ) {
                            case "Spring": {
                                $output = $spring;
                                break;
                            }
                            case "Summer": {
                                $output = $summer;
                                break;
                            }
                            case "Fall": {
                                $output = $fall;
                                break;
                            }
                            case "Winter": {
                                $output = $winter;
                
                                break;
                            }
                            default:
                                $output = "<p>   Sorry, there's an Error in the Season Snippet<br />Please notify the webmaster</p>";
                        }
                       
                return $output;
                ?>
                  Did I help you? Buy me a beer
                  Get my Book: MODX:The Official Guide
                  MODX info for everyone: http://bobsguides.com/modx.html
                  My MODX Extras
                  Bob's Guides is now hosted at A2 MODX Hosting
                  • 20413
                  • 2,877 Posts
                  Quote from: aladage at Aug 09, 2009, 08:29 PM

                  mrhaw: The @DIRECTORY binding is a great idea -- thanks! It eliminates the need to manually add new stylesheets to the TV as they’re created. The only disadvantage I see, although minor, is that it lists the file names as-is. My method gave you the ability to clean up the file names a little bit and eliminate some confusion for the client (i.e., christmas.css could show up as Christmas in the drop-down list). Is there a way to reformat the @DIRECTORY output that I’m not thinking of? If not, it’s not that big of a deal.

                  Hmm, wonder if ManagerManager... Naw, don’t think so.
                  So either core-hacking or use another tv and a @EVAL...

                  Not worth the sweat... laugh
                    @hawproductions | http://mrhaw.com/

                    Infograph: MODX Advanced Install in 7 steps:
                    http://forums.modx.com/thread/96954/infograph-modx-advanced-install-in-7-steps

                    Recap: Portland, OR (PDX) MODX CMS Meetup, Oct 6, 2015. US Bancorp Tower
                    http://mrhaw.com/modx_portland_oregon_pdx_modx_cms_meetup_oct_2015_us_bancorp_tower
                    • 813 ☆ A M B ☆
                    • 326 Posts
                    BobRay: That script is great -- it’s exactly what I’d need to automate this process. I do have one challenge, however -- the Lutheran liturgical calendar is sort of a nightmare. It’s on a three-year cycle that varies year-to-year, and some church events (like Easter) change dates every year based on a variety of factors, such as lunar cycle. If you’re interested:

                    http://en.wikipedia.org/wiki/Liturgical_calendar_%28Lutheran%29
                    http://www.elca.org/Growing-In-Faith/Worship/Lectionary/Year-C.aspx

                    That’s going to make setting up the limits pretty tricky. What I’m thinking, if I decide it’s worth the effort, is that someone would have to go in at the beginning of every church year and change the start dates for the seasons. Honestly, it may just be easier to stick with my method and have someone manually change it. That’s changing one drop-down every few months vs. setting a whole bunch of dates once a year. Regardless, I appreciate the script -- I’ll be making use of that on some other projects for sure.


                    mrhaw: I think you’re right. It’s not worth the effort. I’ll either use @DIRECTORY and hope they can tell what the files are for, or use my original method and put in a little extra manual effort before I hand it over.

                      • 3749
                      • 24,544 Posts
                      No kidding. That’s one complicated calendar. I looked, but was unable to find any PHP code related to generating the dates.

                      I guess you could use TV’s (set once a year) in the snippet parameters with the critical dates in them, but you may be right that it’s easier to just set them manually as they come up, although someone has to remember to switch them at just the right time.

                        Did I help you? Buy me a beer
                        Get my Book: MODX:The Official Guide
                        MODX info for everyone: http://bobsguides.com/modx.html
                        My MODX Extras
                        Bob's Guides is now hosted at A2 MODX Hosting