Stand With Ukraine. Stop Putin. Stop War.

Some time ago @tlyczko suggested I write a how-to on using MIGX with image Galleries or Sliders. As I'm using MIGX all over the place, I guess it can't hurt to spread the love with this How-To! We'll go over the basics of MIGX and work towards the new slider I recently set up for use in my blog.

Try MoreGallery!

While you can still use MIGX for image galleries, I have recently released MoreGallery, a custom Gallery resource for MODX, as part of my new business modmore. The user experience is significantly better compared to using MIGX, so check it out.

The end-result of what we're doing will be the following slider which you may have seen in my MODX Meetup post recently:

    no stuff


  1. A MODX Revolution site. This one is on 2.1.5, but MODX Revolution 2.2 will work fine..
  2. The MIGX custom TV input type installed (available via package management or from here).
  3. A slider or gallery script we'll want to integrate. I went for FlexSlider by WooThemes as it adjusts itself to its containers' width (which is quite important with a responsive design!). It's also quite configurable, supports swiping on smart phones and it looks pretty good out of the box.
  4. The phpthumbof snippet installed via the Package Manager for autocropping images.
  5. Some images!

Getting Started

There's a few parts involved. There's the back-end MIGX TV we'll need to set up, and we need to take that data to our front-end to put our slider to work. As this tutorial assumes WooThemes' FlexSlider, we will make sure the markup is exactly what that needs - but it should be easy enough to adapt for other sliders as well.

Step 1: Setting up the MIGX TV to manage Images

Let's start with setting up the TV. The beauty of MIGX is that you can define the fields you want. You should basically see it as a table, and you get to define the headers. In this case, I will want three different fields:

  1. An image input field to select an image from the file system (or in 2.2, from your media source).
  2. A simple text input to give a caption / tag-line / description. FlexSlider handles captions quite nicely, so we'll be using that.
  3. I'm also adding a text input for "Set". As we'll see later, I'm using this to manage an infinite amount of individual sliders which could be added at any point in the resource.
You can use different fields if you want, though the rest of the tutorial will assume the fields above.

Now let's start creating the TV. Here's a quick slider with an overview of the things you should be seeing (in 2.1-UI style), in case the blurb of text catches you off-guard.

    no stuff

Create a new Template Variable via the left-hand Elements tab, and give it a proper name. I called it mh.images, so if you gave it a different name make sure to replace [[*mh.images]] with the right one further on in the tutorial. On the Input Options tab, choose the "migx" input type drop down. If you're not seeing it there, make sure you have installed the MIGX Package through Package Manager. You will notice that a couple of options have been added to the bottom of the screen, including Form Tabs and Grid Columns. If you're not seeing this and running MODX 2.0, sorry - it's slightly different there and you really should consider updating soon.

Note: Both the Form Tabs and Grid Columns field expect to be fed a valid JSON string. JSON is basically a way of showing objects, arrays or just key -> value combinations in a way that is supported in pretty much any programming language available. There's a technical specification and some examples available on the official JSON website.

Setting the Form Tabs

As the name implies, the form allows different tabs to be used. Every tab has a caption and a number of fields. There are some advanced things you can do with this, though most usages will only use a single tab so we'll keep it at that for now. Here's the Form Tabs JSON I am using:

Let's just briefly go through that per line:

  1. Line one shows us opening the array of tabs with a square bracket ( [ ), and opening the tab object with the curly bracket ( { ). After that we define our caption option with a value of Image. Note that it is important to use double quotes ( " " ) for both the properties and its values, as single quotes are not according to the spec and can have unexpected results. If you have any double quotes inside any properties or values, escape it with a slash ( \ ). After we defined our caption, we go ahead and start defining the "fields" array by opening it with the square bracket ( [ ).
  2. We define our first field, the set in this case. The "field" property defines we want to be able of accessing it in the code as "set" - this would be the name part of a regular text input as well. Next we give it a caption of "Set", which will be shown in the form as field label.
  3. Next we define the description field in the same way.
  4. Line 4 defines the image. What's special here is that it uses another TV (with the name "image") as input type. This is a very powerful feature of MIGX that allows you to use other TVs to build up your form. In this case, the "image" template variable is really simple. Input type is an image, and in 2.2 you would assign it to the right media source as well. You don't need to link it to a template to make this work. Another way you could use this (which I use in another MIGX powered TV) is to build radio boxes or select boxes.
  5. Line five closes the fields array. Also note that the last field definition line (image) does not end with a comma - this is important! If you leave a trailing comma in an array it will not be able to process your JSON, and your form would not work.
  6. Line six closes the tab object as well as the tabs array.
Having put that in place (and having created the "image" TV!) you should have a working form, though there's no grid to show its values yet..

Setting the Grid Columns

The Grid Columns are what builds up the actual table (grid) in the resource's TV panel. You get to define the headers for that grid with the Grid Columns input option.

Here's the (again, JSON) definition I'm use:

Per line:

  1. Open the array of headers with the square bracket ( [ ), and the first column header object with the curly bracket ( { ).
  2. We give the header a title of "Set", say it can be sorted (optional), and tell it the dataIndex is "set", which corresponds with the Set Form Tabs definition which had "field":"set".
  3. End Set / start Description
  4. Give the header a title of "Description", sortable, and match it with the Descriptions' field with dataIndex.
  5. End Description / start Image
  6. Give the header a title of "Image", not sortable, and match it with the Images' field with dataIndex. We also define a renderer which is an ExtJS thing that allows you to change how the value is displayed. In this case, the "this.renderImage" renderer will automatically take the selected image URL, and show a thumbnail for it instead of the url itself.
  7. End Image object, end headers array.
Now that's done, you can assign it to your template and check out the result. No grid or form showing up? Go back to your tab fields and make sure you have all properties and their values enclosed in double quotes, not single ones, and if there are any trailing or missing commas. Can't find anything wrong? It's probably something easy to miss. Use JSONLint to validate the JSON.

Step 1a: Fill in some data!

Find some kitty or dog pictures and put them in through the new magical MIGX TV.

Step 2: Take the data to the Front End

Now you could do something funny to your visitors, and just throw your [[*mh.images]] TV somewhere in the template and telling them to imagine it's all images.If I would have done that to you, the example slider would have looked something like this (without the nice indentation I threw in for readability) instead:

Correct, that's a JSON array with our fields and values!

Now, luckily, MIGX comes with a snippet called getImageList which can help you make sense of that JSON. As I'm a developer and it's easier for me to write an 8 line piece of PHP to parse it, I tend to write that 8 line php myself and not use getImageList at all. If you do want to use getImageList, you can find the documation for it here.

Here's the snippet (which I called mh.parseMIGXToGallery) I'm using to generate the markup (from a &tpl chunk) based on the TV data:

That looks easy enough don't you think? Let's just go through it line by line again.

  1. We take the $input variable (which is populated by the data passed in by &input on the snippet call, more on that later), and parse the JSON into a php array.
  2. We set up an empty array to hold our output.
  3. We make sure the $input variable isn't NULL or false, which would mean there was either no JSON passed or it was not valid, as well as we check the $tpl variable (passed from &tpl in the snippet call) isn't empty. If either condition is true we'll return an error "no stuff' which is a hint for you, as content manager, that something's not set up right.
  4. Next we loop over each item in the $input array as $row.
  5. We check if the $set variable (which is set by calling &set on the snippet) is set, and if it's not empty we match it against what the value of "set" in the current row is. If it's not the same as what we want, we continue to the next item in the array.
  6. We get the chunk by the name of $tpl, and inject the values of the current row into it as placeholders.
  7. We close the foreach loop.
  8. Finally we glue together the $output array, separating every entry with a simple line break, and return it to the page.
So to sum that up, we take our input, loop over the individual rows and if they belong to the set we defined it gets the chunk we defined and adds that to the output.

Putting the Snippet to work

Now all we need is a snippet call where we want our images to appear and a chunk that matches the markup required for FlexSlider. Here's how we'd call the snippet:

and the chunk to match what FlexSlider is looking for is as follows:

and we will also need to wrap the entire snippet output in a div with an unordered list, according to the FlexSlider documentation. To make that easier (and a helluva lot more client friendly), is to put all that in a chunk. My chunk is called mh.slider and has the following contents:

With this chunk in place, I can simply reference the following in the content which is much easier to remember or to put on a cheat sheet.

We could also use a TV to have it type in the name of the set (gallery or collection) in a TV which, when filled in, puts that chunk in a predefined place in the template.

Now we've got our raw markup as FlexSlider wants.. but it's not doing much yet. Off to hook up FlexSlider!

Step 3: Hooking up FlexSlider

FlexSlider is relatively easy to use (download its files here), and there's a number of examples on its site to look at if you need help. You will need to include jQuery on the page, as well as its CSS file (found in the zip) and the FlexSlider plugin (also found in the zip). After having done that you will need to initiate it on the right element, using a code like the following:

The website advises to put all of it in the head of the file, though I personally put it in the bottom. If your slider will appear near the top of the page (above the fold), it can be better to put it in the <head> so it loads before the page shows, though that's just a preference.

And that sums it up for this very long article! I hope this how-to can help people getting started with MIGX and galleries like FlexSlider!

It's now mid-April. Realizing that, it's almost a shock to think I will be back from my week-long trip to Chicago for the CMS Expo in a month! It's time to start packing... I've never been to the US of A before. I've never been to an actual web conference either. But all that is about to change!

As you may have heard (if you follow me on twitter and you didn't, you're not paying attention!) there is a great web conference in Chicago this year, called the CMS Expo. It's hosted by John Coonen and his wife Linda and will take place in a four star hotel, spread out over three days (and a bit).

The reason I've signed up should be obvious: MODX is one of the Spotlight CMS' this year, and there will be some great announcements and presentations there for MODX specifically as well as content management in general (and the other CMS there, of course).

Ryan Thrash, the MODX Leader of Awesomeness, will be taking the stage to tell the world MODX is ready for take off and to make the life of designers and developers easier all over the globe. He will also be joining the CTO of SoftLayer Duke Skarda, one of the great sponsors behind MODX, to talk about the next big thing: MODX Cloud.

The official MODX itinerary will be announced soon, however,  there is simply no way we're not throwing together a MODX Meetup while we're there. Ryan is in town, I will be in town and a number of clients and fellow freelancers are also attending the conference who I look forward to meeting in person.

You've still got until April 30th to get your tickets at $779 for three days, or $679 if you enter code MODX2012. See you there!

    no stuff

Images above are from the 2011 Expo, credits go to Monty Ksycki and Chris Hammond (last picture).

Last week we had a MODX Meetup here in Leeuwarden (The Netherlands), and I figured I'd write a lil' bit about it and why I think you need to host one too. I think they're a great way to socialize with people that use (or are simply looking into) the same system. Not just if you're top-notch developer, or an expert in the field - everyone who uses MODX one way or another should take part in events like this. There's something to gain in them for everyone, and it's a great excuse to have a couple of beers together!

Here's the history.

Let me just take you through my history with meetups and what I learned from each of them.

Meetup #1: July 2011, Noordwolde (Friesland)

You have to start somewhere, and this is where it did for me. Together with Gauke Pieter of Sterc Internet Marketing I organised a meetup in 't Vlechtwerk, Noordwolde. This one was quite formal with a firm schedule (that we didn't even exactly follow). There were two main presentations, one by Gauke on MODX in general and SEO, and one by myself about customizing the manager. On top of that we had a skype video call with the MODX HQ over in Dallas where some great questions were asked and answered, which was really very much appreciated - not everyone gets to talk to those great folks on a regular basis :) We finished the evening with informal chatting which was a great time to catch up with people and to exchange business cards and the likes.

    no stuff

Don't think it was too bad for a first time, though I do think it was too tightly organised, and that I needed to let go some more and let the attendees help build the evening more. It was great to finally meet so many people (25!) that I've known via Twitter or Skype for a longer period of time.

Meetup #2: March 23rd 2012, Tilburg (Noord-Brabant)

As I was headed for a show just across the border in Belgium, a few tweets were sent out looking for people who would like to attend (and host) a meetup in the area. The next day we had a location at Yoman's Studio in Tilburg and Jasper also offered to arrange drinks, some snacks etc. As there were literally four days between confirming the location and the planned date, there were not a lot of attendees (5), but nevertheless it was a great evening with some very creative individuals who each have their own way of working with MODX.

This meetup learned me that it can be as easy as reaching out to people in order to get a meetup going.

Meetup #3: April 11th 2012, Leeuwarden, (Friesland)

For the meetup in Leeuwarden, which was hosted at Grand Café de Walrus, I took a way different route compared to the first Dutch meetup. This time, I prepared nothing - no presentations, schedules etc. Just get people to come, have a drink and see where it ends up. Despite some internet issues I think it was quite fun, and with about 15 attendees there were a surprising amount of new faces. MODX is definitely growing in the Netherlands!

Now, the lack of any planning did make it quite chaotic (though there were plenty of drinks!). People sat together in small groups to discuss things together, and I think it would have been more beneficial to people to sit together and discuss things in a larger group. So next time; a general schedule to kick things off.

Now it's your turn!

MODX is growing, rapidly. Start networking, pick a date, and host a meetup in your office, a local bar or a conference centre if you fancy. It doesn't have to be complicated or hard to host one, but do start some time in advance. I'd at least give people a month or so to keep an eye out on their schedule, make babysitter arrangements or to convince their boss to pay for the traffic costs. Use Twitter (mention @modxcms and use the #MODX hashtag), Facebook (post it on the MODX CMS page, or your countrie's/state's page) and send personal emails to people you know who may be interested, asking them to spread the word with any of their contacts who may be interested too. The MODX'ers are there, you just need to put some time into finding them and having them find you.

You don't need big names, big budgets or dedicated teams to get a meetup going. Find a way to offer attendees value (provide quality content, sponsor the first drink, try to get some big names involved to speak or share experiences, give them a sponsored goodybag.. be creative) and get them interested. Often it's enough to just give people the opportunity to get to know eachother.

So. When's your next meetup?

One of the new features in MODX 2.2.1 is the ability to indicate if a user is a "sudo" user. This humble checkbox is one to be extremely careful with, as it allows a user to completely bypass ANY access control you may have set up. This bypass is in the core, and will therefore also affect any custom access policies you built up and access policies by 3PCs, such as Quip.

When to use sudo users

Its goal is to allow the concept of a super user or administrator which is not affected by the security setting... you can imagine that to be helpful when you are working on actually setting up the security (to prevent yourself from getting locked out), or when you want to make sure someone has access to it all. This was a much requested feature from the forums.

More importantly: when NOT to use them

Please do not set a front-end user to be a "sudo" user. All access permissions means all access permissions, and if they find out the link to your manager (cause, being security aware, you used the advanced distribution to move it, right?) they are free to do ANYTHING, from editing resources to deleting your account or other wrecking things.

Sudo users don't even need to be assigned to any user groups in order to get full access.

Sudo users are to be used for providing access to everything in the manager and all front-end contexts - if you don't feel at ease with someone having that access, do NOT set them as a sudo user. Simple as that.

How to set a user as Sudo user in MODX

If you are updating to MODX 2.2.1, you will find that any users which are assigned to the Administrator user group with Super User permissions will have been marked as a sudo user. The first account you create via the installer (for a new install) will also be set to be a sudo user by default.

To set other users as sudo users, open Security > Users in your MODX 2.2.1 manager, and edit a user you want to give full access. You'll see the below screen. Simply tick the Sudo user box, and save the user.

How to set a user as Sudo user in MODX

Programmatically setting a user as sudo user

As we're dealing with what is pretty much root permissions, it is not possible to simply use sudo in a modUser->set() or modUser->fromArray() method - this is filtered out and will return false. This is to prevent auto assignment exploits (like the ones that caused an uproar in the Rails & Github communities recently).

Instead, you will want to use the modUser->setSudo(true|false) method. Pass it a boolean true to mark a user as sudo user.

Conclusion thingy

Do not start handing out sudo permissions! It's an extremely easy way to lose control over your manager if the user is not to be trusted. Every user set as sudo user could get its password guessed and cause you some major problems. But it's a great feature for developers setting up the security who don't like getting locked out!