My latest assignment was a MODX site featuring a thumbnail gallery with the following requirements:
- List up to 8 thumbnails in a static-sized div.
- Thumbs pulled from end-user-created-and-editable MODX resources.
- If in photography section, clicking thumbs opens Lightbox.
- If in design section, clicking thumbs opens another page with more info.
- If more than 8 resources, pagination starts up.
- Lots of targeted styling.
So of course the first snippet that comes to mind is the venerable all-in-one toolbox called getResources and the sister-snippet getPage for the pagination feature. Let's walk through the install:
- getResources: https://rtfm.modx.com/extras/revo/getresources
- getPage: https://rtfm.modx.com/extras/revo/getpage
- Property Sets: https://rtfm.modx.com/revolution/2.x/making-sites-with-modx/customizing-content/properties-and-property-sets (you'll see later why I added this)
I'm assuming pretty good knowledge of MODX and getResources, although I think this tutorial could come in handy for Beginners all the way to Advanced Users.
I'm using one template for all possible portfolio-related pages. You could do this with several templates, but I like to push the boundaries of MODX TVs because you can give the end-user control over them or not, depending on the situation. Flexibility is part of what makes MODX great, right?
The template has a radio option TV so the user can select: Photo thumbnail gallery, Design thumbnail gallery, Lightbox image item, or Design item info page. The latter two are just page layouts - it's the first two we'll talk about here because they're essentially getPage snippet calls.
getPage Snippet Call
I started with the photography section, cuz I love photography :P
[[!getPage@Gallery? &element=`getResources` &parents=`[[*id]]` &limit=`8` &tpl=`photoTpl` &tpl_3=`photoTplThird` &tpl_6=`photoTplThird` &includeContent=`1` &includeTVs=`1` &processTVs=`1` &sortby=`menuindex` &sortdir=`ASC` ]]
Break it down:
[email protected]?» Uncached call with a custom Property Set attached! getPage is NOT a regular snippet where you can reference template chunk names in the snippet call. You must use a custom Property Set to define these values. If you're unfamiliar with them, check out the MODX Documentation (link above). I'll go over some of the template features later...
&element=`getResources`» this tells getPage to use getResources to...well, get the resources. Haha. Note from here on in, properties in this snippet call are all relating to getResources!
&parents=`[[*id]]`» Uses the current page as parent, so child resources of current page will be listed.
&limit» Sets the maximum number of resources to output.
&tpl» Chunk name for photo item template.
&tpl_3» Chunk name for template for every 3rd output photo item. This was necessary because the third item in each row had to be styled differently. Yes, I also used CSS Nth child, but not all browsers support (*sigh*). ** UPDATE: in 2015, it's safe to say browsers support Nth child ;)
&tpl_6» same as above
&includeContent/&includeTVs» Both these properties tell getResources to output the content and template variables. They are off by default to save on processing (& page load time - see the update at the end of the article)
&processTVs=`1`» Not only do you have to include template variables, if you want to process them and get their results you have to set this property.
&sortby/&sortdir» Pretty standard MODX snippet properties for sort order.
Now we look at one of the templates “photoTpl”
<a title="[[+pagetitle]]" href="[[+tv.photoSrc]]" rel="[[+tv.lightbox]]"> <img class="thumb" title="[[+tv.photoTitle]]" src="[[+tv.photoSrc]]" alt="[[+tv.photoAlt]]" /> </a>
Break it down:
- I'm outputting to an unordered list, which suits my purposes here. You can output to anything though. This template represents What Will Be "Gotten" From Each Resource, And Which Fields It Will Get Stuff From.
- Note the
[[+ ]]syntax: when writing a template for a snippet to use, you use the placeholder token “+” instead of
[[* ]]because the “*” token is reserved for the current Resource's fields (the Resource being requested by the user) whereas placeholders can be set by a snippet, plugin, or via Property Sets.
- Also note the `tv.` prefix. That is for TVs, if it wasn't obvious. This behaviour can be modified in your getResources call but I've left it as default in the example.
Extra detail about the TVs (skip this if you're bored) :
tv.photo...» These TVs hold data about the image. The user can upload & specify images from the Resource's Manager page. Having alt text and titles for everything is just a good idea (and to validate) - but not required.
tv.lightbox» Setting rel="lightbox" via a TV, so that the Manager user can include or exclude any image from the Lightbox functionality.
We pretty much have all of our requirements:
- Lists 8 thumbnails - Yes,
&limit=`8`. Although you can't see it here, the snippet call is inside a div so I can style the items as a group.
- Thumbs pulled from Resources - Yes. We're using getResources so this output is end-user-editable via Resources, with potential permissions & form customization, yada yada yada.
- Thumbs open Lightbox - Yes. There's extra JS & stuff but that's separate. Our “&photoTpl” provides the means to target the images for Lightbox functionality ( rel="lightbox" ) AND allows the end-user to turn this on/off via the TV.
- Pagination - Yes. We're using getPage which automatically outputs pagination, with a customized (@Gallery) Property Set.
- Targeted styling - Yes, “&photoTpl” allows us to set classes and IDs. Need SNIPER targeting?
- PRO TIP: Are You Ready? » Just add:
id="string-[[+id]]"(where “string” is an arbitrary string that complies with HTML spec for the ID attribute) to any html tag in the template and you will have a unique CSS selector for content derived from the Resource with ID
The customized Property Set for getPage allows you to setup templates for the pagination items, so even THAT can have custom selectors if you want. I wanted, and MODX delivered - as usual :P
<ul> <li id="prev" class="control"><span class="nav">prev</span></li> </ul>
This is almost the default “&tpl” for getPage, which you'll find in the snippet's properties page. I just added a custom #id and span element to the link text. That's all, folks!
Ok, ok, I missed the requirement "If design section, thumbs do something else..." Sheesh, you're demanding, aren't you? :P It's like this: the radio option TV I talked about above just selects different getPage snippet calls (or Property Sets), depending on which gallery style the user wants for the page. Each version of the snippet call can use a different “&tpl” for infinite possibilities. Why not just use different page templates, you ask? Because this way, the user can choose gallery style WITHOUT having access to change page templates. What if they chose the wrong template? A potentially broken, or at least unsightly page that will be unnerving for the user. “Aaargh! I broke the site!!” Rather, if they only have the power to choose the wrong Gallery style, it's not as big a deal most likely.
There. Hopefully worth the hours it took for me to write this and you to read it LOL.
**TUTORIAL UPDATE FEB/2012: the getResources snippet now has a new property that allows you to pass a comma-delimited list of template variable names for getResources to parse. This saves a LOT of processing and can greatly improve your page load times. It's used like this:
Just add that to the other properties in your getPage snippet call! END UPDATE**