We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 36461
    • 102 Posts
    Hello,

    I have a content div which has a background picture, I would like for this background picture to change when different site pages are opened. But I'm not sure how to do it.

    There was a similar thread on forum but it involved php and some othe thing I hadn't heard of before. If possible please suggest a simple method. [ed. note: viltnieks last edited this post 15 years, 1 month ago.]
      • 3109 ☆ A M B ☆
      • 894 Posts
      The easiest way to do this is using inline CSS on your div and that allows you to use an image tv to specify your image for each page.

        Benjamin Marte
        Interactive Media Developer
        Follow Me on Twitter | Visit my site | Learn MODX
        • 3749
        • 24,544 Posts
        If you want to automate it, you can create a plugin to load the CSS for you. Something like this (attached to OnWebPagePrerender):

        <?php
        switch ($modx->resource->get('id') {
        
            case 12:
            case 15:
                $css = 'red.css';
                break;
        
            case 17:
            case 45:
                $css = 'blue.css';
                break;
        
            default:
                $css = 'green.css';
                break;
        }
        
        $modx->regClientCSS(MODX_ASSETS_PATH . 'css\' . $css);
        


        To get a little fancier, you could use a TV on each page to determine which CSS file is loaded. Something like this:

        TV: Background
        Input Option Values: red==red.css||blue==blue.css||green==green.css
        Default: @INHERIT green.css

        Then the plugin would look like this:

        <?php
        $css = $modx->resource->getTVValue('Background');
        
        $modx->regClientCSS(MODX_ASSETS_PATH . 'css\' . $css);
        


          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
          • 32316
          • 387 Posts
          inline css is hard to maintain
          BobRay's solution I'm sure works - but perhaps is more complicated than it needs to be.

          How about adding a class to your content div:
          <div class="contentDiv background[[*id]]">
          the content
          </div>

          and in your css:
          .background1 { background-image: url(myimage1.jpg); }
          .background3 { background-image: url(myimage3.jpg); }
          etc
          the css will style resources with ids of 1 and 3

          Simple as it gets I think while being easy to maintain.

          You could of course use an id instead of class but if i wrote it up that way it would be easy to get confused with id and id - the css one and the modx one, or is it the mySQL one?
          [ed. note: whistlemaker last edited this post 15 years, 1 month ago.]
            • 18373 ☆ A M B ☆
            • 3,141 Posts
            The solution Ben suggested is, in my opinion, the easiest one, and I wouldn't call it hard to maintain as it's done automagically smiley

            He (and me too) suggest using this in your template:
            <div style="background: url([[*backgroundImageTV]]) no-repeat top left;">
               ... content ...
            </div>
            

            where a backgroundImageTV exists which is an image input type allowing you to select the image from the file system or uploading a new one, displaying a thumbnail as well. Output type should be default.

            Of course, when things go beyond a different background image that can become a mess and it would be better to use a different solution. Either a TV choosing the css file or a plugin solution like Bob suggests. Or a body/div class referenced (hardcoded) in your css.
              Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

              Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.
              • 36461
              • 102 Posts
              Thank you guys, when you explained this all seems so easy smiley
              I'm a bit sad that I didn't think of this myself.
              It just amazes me how quite advanced (at least for me) things can be achieved so easy with modx.
              In the end I chose adding
              class="bg[[*id]]"
              , to div + css, works like a charm !

              Just one little question, if I will start using Friendly URL will this still work or will I need to change
              [[*id]]
              to
              [[*pagetitle]]
              ?
                • 9102 ☆ A M B ☆
                • 318 Posts
                You won't need to change anything. With FURLs on the id tag still returns the id number of the resource.

                The solution you're using appears to work fine for you, but it might be difficult to scale to a large number of pages and/or background images.

                However, resources can also be CSS files, not just HTML. To scale this approach, you could put the background image for each resource in a TV and then dynamically generate your CSS file using a GetResources call. I set this up the other day for dynamically generating a bunch of CSS sprites, it works well.

                That would scale up somewhat, but with a very large number of pages the CSS file would get huge. To circumvent that, you could write a snippet that accepts the page ID as a GET parameter and auto-generates CSS that's specific to that one page. I'd probably write a snippet just to acquire the GET parameter and set it in a placeholder, then use getResourceField to pull in the appropriate TV, that way at least some of the data would be cached to maximize performance. This approach adds an extra HTTP request to each page, however, and an uncached one at that, which might slow your load time significantly.

                So in the end, maybe the best and most scalable approach really is to just use inline CSS, unless you have strong objections to that for some reason.

                The inline CSS solution has a lot of advantages:


                • It's very simple and easy to implement.
                • It scales automatically to any number of resources without adding significant overhead.
                • It is completely cacheable, and doesn't make any snippet calls so it will perform very fast even uncached.

                Speed optimization tools will always tell you to put your CSS in external files for better performance, and that is usually true, but in this case I think it will actually perform quite a bit better inline, at least at a large scale. [ed. note: esnyder last edited this post 15 years, 1 month ago.]
                  • 36461
                  • 102 Posts
                  Thank you for explaining this in detail!

                  I will definitely keep this in mind, but I just needed this background change for few site pages and most likely it will remain this way.

                  I must admit that

                  To circumvent that, you could write a snippet that accepts the page ID as a GET parameter and auto-generates CSS that's specific to that one page. I'd probably write a snippet just to acquire the GET parameter and set it in a placeholder, then use getResourceField to pull in the appropriate TV, that way at least some of the data would be cached to maximize performance. This approach adds an extra HTTP request to each page, however, and an uncached one at that, which might slow your load time significantly.

                  Seems something out of my league, at least for for the moment :p
                    • 9102 ☆ A M B ☆
                    • 318 Posts
                    That's OK, I talked myself out of thinking it was a good idea anyway! wink