We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 14883 ☆ A M B ☆
    • 450 Posts
    I've been using :notempty filters to wrap MODX tags in some HTML for years:

    [[!mySnippet:notempty=`<div class="foo">[[!mySnippet]]</div>`]]


    Reading Jason Coward's blog post on conditionals in tags (http://modx.com/blog/2012/09/14/tags-as-the-result-or-how-conditionals-are-like-mosquitoes/) got me thinking recently about how this method basically calls the entire snippet twice. I'm not sure if I'm thinking intelligently or not, but I am thinking. Which is usually dangerous for me.

    Today I had the idea to use a custom output filter instead of the :notempty filter.It looks something like this:

    [[!mySnippet:wrapper=`div.foo`]]


    'wrapper' is a Custom Output Modifier that sees if 'mySnippet' returns an empty value, and, if not, returns it wrapped in the chunk 'div.foo'

    'wrapper' snippet:
    if (strlen(trim($input)) > 0) {
      $modx->setPlaceholder('inner.content', $input);
      return $modx->getChunk($options);
    }


    'div.foo' chunk:
    <div class="foo">[[+inner.content]]</div>


    This also lets me control the wrapper HTML in a chunk, allowing me to create a reusable library of wrapper chunks.

    I have to go back and look at a lot of code I've written to see just how useful this idea is, but I think it might be pretty useful.

    I'd be curious to know others' thoughts on it.
      • 18373 ☆ A M B ☆
      • 3,141 Posts
      Mark Hamstra Reply #2, 14 years ago
      If it's a custom snippet, you should totally use an outerTpl in that.

      Otherwise, I think it's a great idea for when you are *not* using a custom snippet.

      This is the way I'd probably do it tho:
      if (strlen(trim($input)) > 0) {
        return $modx->getChunk($options, array('inner.content' => $input));
      } else {
        return '';
      }
        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.
        • 22303 MODX Staff
        • 10,725 Posts
        Great stuff James; this also makes your site easier to change in the future IMO. Embedding HTML within MODX tags always looks so ugly anyway. smiley

        Though not using output filters, I do use generic chunks all the time for various wrapping needs. Consider this $sidebox chunk I use on my personal site:

        <div class="sidebox">
        <h1>[[+title]]</h1>
        [[[[+element]][[+properties]]]]
        </div>


        I call it various ways in my Templates/Template Variables...

        [[$sidebox?
            &title=`[[getValue? &class=`modResource` &field=`menutitle` &where=`{"id":[[UltimateParent]]}`]]`
            &element=`Wayfinder`
            &properties=`@SidebarMenu? &startId=`[[UltimateParent]]``
        ]]
        
        [[!$sidebox?
            &title=`Notable Quotable`
            &element=`getResources`
            &properties=`@quotes-random? &limit=`1``
        ]]
        
        [[$sidebox?
            &title=`Search`
            &element=`$search`
        ]]


        Keep the ideas coming everybody...sharing them like this can help us all create better sites in MODX and steer product development in the right direction.
          • 28042 ☆ A M B ☆
          • 24,524 Posts
          Actually that could even be reduced a bit more...

          (strlen(trim($input)) > 0) ? return $modx->getChunk($options, array('inner.content' => $input)) : return;
          
            Studying MODX in the desert - http://sottwell.com
            Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
            Join the Slack Community - http://modx.org
            • 14883 ☆ A M B ☆
            • 450 Posts
            Bob Ray suggests on Twitter that it would be faster to call the wrapper snippet and pass it the original content element as an argument:

            [[! Wrap? &content = `errorMessage`]]


            I'll take his word on the speed issue, but a few other thoughts come to mind:

            • in order to not pass a tag that would get parsed, an elementType argument would also need to be included:
              [[!wrap?&content=`errorMessage`&elType=`snippet`]]
            • You'd still want to be able to specify an output chunk as well, so that would be one more property to pass.
            • Most importantly (in my opinion), the "content logic", if you will, of the document would be fundamentally altered in a way that bothers me on some deep level. If I'm including some chunk like $myCustomSidebar, I want that to be the element that gets called in that place, rather than calling a "wrap" snippet and passing my content element as an argument. Something about it just doesn't feel right to me.

            @Mark, is outerTpl something I've overlooked in the API? Or a best practice for writing custom snippets?

            I think most of the time this would be useful for uncached placeholders. I used a snippet in the example just because...
              • 33968
              • 863 Posts
              This reminded me of something similar I've used (although more simple). I was fed up with markup like this leaving empty tags when the placeholder was empty:
              <h3>[[+placeholder]]</h3>
              

              So I built a new modifier to wrap the placeholder with the tag specified:
              [[+placeholder:wrap=`h3`]]
              
              <!-- cleaner than this: -->
              [[+placeholder:!empty=`<h3>[[+placeholder]]</h3>`]]
              

              Where the wrap modifier is simply:
              <?php
              if (!empty($input) && !empty($options)) {
                return '<'.$options.'>'.$input.'</'.$options.'>';
              }
              return $input;
              

              We should start a forum for custom output filters - I imagine it would be handy for those who are not so comfortable with php.

              I prefer to use a snippet whenever possible for efficiency, but sometimes filters/modifiers make for simpler, easy to read markup. If cached, it's usually not a big deal where performance is concerned.
                • 4172
                • 5,888 Posts
                  -------------------------------

                  you can buy me a beer, if you like MIGX

                  http://webcmsolutions.de/migx.html

                  Thanks!
                  • 14883 ☆ A M B ☆
                  • 450 Posts
                  @Lucas,

                  That seems to be exactly what I'm after here. And nice job of summarizing the path from bad (markup that leaves empty tags), to the better (explicitly placing the markup in a notempty conditional), to the best (custom output filter).

                  A forum for custom output filters would be a great idea.
                    • 3749
                    • 24,544 Posts
                    Lucas -- almost exactly what I had in my head, but I used a snippet, which might be slightly more efficient:

                    [[!Wrap? &input=`[[+placeholder]]` &tag=`h3`]]
                    


                    <?php
                    if (!empty($input) && !empty($tag)) {
                      return '<'.$tag.'>'.$input.'</'.$tag.'>';
                    }
                    return $input;


                    Your method might work better if the tag is in a Tpl chunk -- I'm not sure.


                    ------------------------------------------------------------------------------------------
                    PLEASE, PLEASE specify the version of MODX you are using.
                    MODX info for everyone: http://bobsguides.com/modx.html
                      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
                      • 36416
                      • 589 Posts