Stand With Ukraine. Stop Putin. Stop War.

New Extras are released all the time, MODX LLC is always working on the next big thing and the Community is growing exponentially. In this series I'm going to try and keep you posted on interesting initiatives and stuff coming up. Welcome to Episode 1!

In this episode:

  1. [Extras] Interesting new TV Input Types
  2. [Extras] All things Analytics
  3. [MODX] Mostly Cloudy, with a 100% chance of MODX™
  4. [Evolution] Security fix for 1.0.5 now available

1. Interesting new TV Input Types

Many consider Template Variables the number 1 reason they like MODX, which is definitely something I can relate to. However, did you know you can also develop new input types to bring it all to the next level? Well, you can!

A lot of people know about MIGX, short for Multi Items Grid TV (for MODX?), which allows you to work with a grid, or table, enabling you to add an unlimited list of items. I think it could use a cleanup, but it does what it promises on the tin and I use it quite often. 

In the last few weeks, a couple more interesting TV Input Types have been released. ColorPickerImagePlus TV Input and SuperBoxSelect.

ColorPicker is not exactly new, the first version was released back in November, but it gives you a pretty nice colorpicker with different output types (such as HEX, RGB or JSON). If you allow users to change the color of certain template aspects, ColorPicker sounds perfect for the job.

ImagePlus TV Input is for those times where the default image cropping of PhpThumb(Of) is not enough, and you need to define exactly what is shown yourself to prevent weird results (like seeing only half of a face). While there's still a few bugs and I wouldn't recommend production use yet, this is definitely something to keep an eye out for as it gets further developed.

SuperBoxSelect, by the same author as ColorPicker and also first released in November, is a variation to the default ResourceList input type which allows you to select multiple resources through a combo (dropdown/select) box. 

2. All things Analytics

We all like Google Analytics (and making sure manager users don't show in the stats!), and over the past period a number of addons specifically for Google Analytics have been released.

First we have the Google Analytics Dashboard (for 2.1), its MODX 2.2 spin off using a Dashboard Widget and Big Brother, all of which request the Analytics data through its API (after authorization of course) and shows it to you the moment you login to your Manager. I've been using both the GA Dashboard Widget and Big Brother, and I have to admit I prefer Big Brother. Its authorization process was smoother (and looks super fancy, too!), and more matched the information I expected on the dashboard.

We also have two extras to put the analytics code into your templates, which are Analytics and Google Analytics (the naming isn't as original as Big Brother!). 

3. Mostly Cloudy, with a 100% chance of MODX™

.. or at least that's what the MODX team is telling us!

MODX Cloud, which is currently in private beta, will (again) revolutionize the MODX world by offering a cloud based platform where you get a fully configured installation of MODX Revolution in the Cloud. This new infrastructure, which is powered by MODX Sponsor Softlayer, will likely come with all the flexibility and benefits of cloud hosting: super fast and easy deployments, easy migration between servers and of course scaling with a click of a button (if that!) when you most need it. Rumours tell me there are some specific MODX benefits attached to Cloud as well (no specifics here though!), and from the looks of it you will also be able of getting access to MODX Cloud through the all new "coming soon" MODX College.

Seeing how the Revo development on Github has been a tad slower lately compared to the past weeks, I'm going to bet the team is working hard to get this out there! ;)

4. Security fix for MODX Evolution 1.0.5 available

Last week a critical security issue in Evolution 1.0.5 was discovered, which allows certain (Extra) configurations to be exploited, resulting in executing of snippet tags. Some people have indicated added files in the assets/cache folder which did not belong there and may have provided an entry point for further exploitation. More details in the Security Notice on the forums

The fix be applied manually by replacing the contents of your manager/includes/ file with the version on Github. Alternatively MODX Evolution 1.0.6 should be available soon with this fix and possibly more.

In the next episode...

I've got some ideas for the next in this series, but do let me know what you would like to hear about! The next episode will probably arrive in a few weeks.

Have you ever had a client asking for showing a list of related articles or news items? Chances are you've applied a technique to show a list of all articles in a Template Variable, allowing the client to handpick the ones that are related. This is a great technique and I have written about it in the MODX Documentation, but the admin or editor still has to manually pick what is related. Surely there's an automated way as well?

Back in fall 2011 I was contacted by Vierkante Meter, a Dutch web agency focusing on accessible websites, with exactly that request: a way to automatically show related articles. Some time later getRelated was born as the answer to their questions as well as that of many other developers. I've even deployed it on my own site! Just look a the "Related Articles" block to the bottom right of this post (not visible on mobile for now).

getRelated is very powerful, but, if I can say so myself, still very easy to use. It can be installed via the MODX Package Manager and from there you just need to call the snippet in your template - and it's there! But of course, the power is in the details..

What makes getRelated awesome

(More information about the aspects mentioned below can of course be found in the getRelated Documentation.)

#1: Configurable algorithm.

getRelated checks out the resource it is called on (or the resource you specify with &resource=`ID`), and identifies unique words in the fields you specified, and it uses those to find matching resources. To come up with the order in which they are returned, it specifies a value for every field. A value of 5 means that every matching word in that field is rewarded with 5 points added to the total. At the end of the processing cycle it sorts the results by the amount of points rewarded.

By default it only looks at the pagetitle and introtext, but by simply specifying the &fields property you can tell it what fields to use and how valuable they are. According to the docs:

That's a lot of information in only a few lines, but it tells you how to define the value of each field, and that you can even use TVs for them. To show how that works, here's the &fields property used on my site:

The most value is assigned to the "mh.categories" template variable: it's what I use to categorize my posts in 2 or 3 categories each, such as front end development or ExtJS. The "12" means that every category is worth 12 points when it matches on a different resource. So if another article has one category in common it scored 12 points. Every matching word in the pagetitle is worth 6 points, longtitle gets 4 points per matched word and the introtext gives 2 points. By defining all of that in the &fields property you can pretty much define your own algorithm for finding related pages automatically. You may use both categories and tags, so you could give categories a higher value compared to the tags to get the most accurate results.

#2: Completely configurable output

Besides the ability to specify, you are able of completely configuring how your related resource is shown. The default is a h3 tag and an unordered list with the top 3 related resources. But using the &tplOuter and &tplRow property you can change it to your hearts content. 

As performance is a big priority with a tool like this, it only sets placeholders for the fields you specified, and as of the 1.1 release (for MODX 2.1+) it also allows you to use TVs in the output. Just specify the resource fields (ie pagetitle, introtext) in the &returnFields property and the TV names in &returnTVs. Again, for speed it only gets the TVs for the top ranking results, so no performance is lost. 

For example, this is a screenshot from a current project (a jewellery webshop) of mine, which uses getRelated with returnTVs to show related articles. 

And the getRelated snippet call:

The match is completely defined on TVs used for products: the tagline, colors, materials and stones. Here's the getrelated.row chunk:

The getFirstImage custom snippet is used to get the first image: the product.images TV uses MIGX to allow unlimited amount of images. The custom snippet uses the following chunk to show the image (product.firstname chunk):

#3: Excited client!

#4, #5, #6 etc: More possibilities!

Use the &parents, &includeHidden, &hideContainers, &contexts, &exclude and more properties to decide which resources to include or not. 

Spotted in the wild!

We've just hit 650 downloads (well, okay: 647, but close enough!) of getRelated so far, I am very interested in seeing how people have been using it! Feel free to leave a link in the comments to show how you're applying it... I may feature the most impressive uses here as well!

Since the launch of MODX Revolution 2.2pl, the use of the Articles blogging tool has been growing exponentially as well. This post walks you through a question that is being asked several times per day: how do I show Articles on my homepage or in a sidebar?

Including Articles in Wayfinder or getResources

As individual articles are stored and used just like any other resource, you can use the same tools to display them such as getResources or Wayfinder. The trick there is that Articles are set as hidden from menus, which both of these snippets hide by default. Luckily both of the mentioned snippets support including those as well using a simple property, as shown below.

Wayfinder uses the &ignoreHidden property. As it is primarily a menu building tool, if you want it to to show hidden resources you tell it to ignore the hidden state. getResources is not linked with menus directly, and uses the &showHidden property to indicate you also want hidden resources to show up. So they do the same, but the terminology used for it is slightly different and can seem counter intuitive at first. 

But what if you don't want them included?

Excluding Articles in Wayfinder or getResources

If you don't want the articles posts to show up in a Wayfinder menu or getResources list, you can filter them out by checking against the "class_key" variable.

Normal resources have that set to modDocument (or modWebLink, modSymLink or modStaticResource), but as Articles installs a custom resource class the class_key is different as well. The blog container itself is an ArticlesContainer class, and the individual articles are of class Article. Knowing this, we can filter against this using the &where property. This &where property, commonly available in extras, accepts a json string representing an array (with xPDOQuery::where style comparisons). That may sound complicated, but here's an example for Wayfinder and getResources:

And that's all! Happy blogging!


Mere houres after publishing this article the MODX RTFM was updated with some more information on accessing all of the placeholders used in the Articles templates,  including the latest articles, tags and comments. Find it here.

Monday at about 4.30 CET the hosting provider of my host got hacked at the root level which resulted in all of my websites going down, until manually being restored to an old backup Wednesday morning at about 4am CET. 

Just to clarify this before getting started.. while I purchase my hosting of Skytoaster, this specific server is run by AltusHost. If the following post is too long for your liking: I still recommend Skytoaster, just please do not, ever, trust a host that doesn't keep backups. And keep backups more often than I did.

What happened?

According to the official statement of AltusHost posted on Facebook, their version of WHMCS (which seems shady to say the least) a hacker gained root access to their billing panel and started removing servers, which lasted about 10 minutes. While they're statement says 5PM CET, I was working on a site on that server at around 4.30PM when it started showing connectivity issues, so my guess is that they've rounded up the time.

When a server gets deleted, I can imagine that a site goes down, and when there's a lot of sites to restore that can take time. While annoyed I could not finish the site I was working on, I think I'm quite forgiving when it comes to people doing stuff I know little about and when that goes wrong. I assume there are a lot of people all over the globe working on it who are just as frustrated (if not more), so let them do their thing. Spent the night hanging out with friends so tried not too worry about it too much.

At Tuesday morning 2am CET I received an update from Skytoaster on the situation, mainly letting me know that AltusHost was working on getting servers back online and to explain the situation. At that point it wasn't clear yet if my server was one of the removed ones or not.

And yes, it was.

A few hours later Patrick came back with a confirmation that it indeed was. We had been provided a new (empty) server which we could use to put up some sort of notice or restore from a backup of our own. The backup server, which was apparently with Altus as well, had not yet been located and the fate of that was unknown. That morning I worked with Patrick to put up a brief explanation on my websites, and started to upload backup data to try and get the site back up. Right now all articles are back up, no comments though.

I guess I'm a bit naive when it comes to servers, as I only tend to take backups when making major changes such as my relaunch back in December. That's the last one I could find on my computer, even though I recall clicking cPanel's "backup" button a week or two ago, I never downloaded it from the server after it was done generating. After all, I've been promised 7 days of backups on server-level, so in the event something goes seriously wrong with the server, that would be more easily restored than something I download manually per user on the VPS. Not a big deal, until it is.

Here's where it gets nasty.

Now, the real problems only became evident late Tuesday evening. The backup had been uploading and was almost ready when I managed to get hold off a technical support member who told me "we have no backups for our main hardware node".

I'm not sure about you, but I don't run a hosting company nor do I have the wish or expertise to start one. And I do realize in the end it's the responsibility of the user to backup what they create. But what I don't understand is how on earth someone can have the gut to run a hosting company without any backups of servers you're selling. When something goes wrong, and I do think eventually something goes wrong with any server as there's just so much things to worry about, you will want to be able of either re-routing requests to a different mirrored server or be able of restoring from the backup made last night... right? As a hosting company you would want the certainty that in case something goes wrong, you can keep your clients satisfied with a quick solution right? Well, apparently AltusHost doesn't.

Restoration Phase

After hearing this news that there's no chance of the server being restored from their end, roughly 30 hours after witnessing the first symptoms, it kinda gave me no reason but looking at getting my site back up one way or another. And this is where Patrick reminded me why I hosted with SkyToaster again as he had been working through my local backups and after getting at least my personal sites back to the way they were on December 22nd, he has been helping me manually restoring my blog articles and other websites from Google Cache in a time period of over 4 hours. Thanks Patrick!

Never, ever, ever again.

Somewhere in between, he also set up a new US based backup server (unaffiliated with the current provider) which automatically writes a nightly, weekly and monthly backup of all users on my VPS which I can access directly as well. While they made a mistake in working with Altus for their Dutch VPS, he's been working day and night (literally) to prevent this from ever being possible again.

Now what?

I'm still a great fan of Skytoasters' service. Patrick (and Sal too for that matter) are easy enough to get hold off and respond promptly when needed. They're all human, who made a mistake when signing up with Altus, but up to now all my hosting (shared and VPS) has been great. We've got most of the stuff back thanks to the hard work by Patrick, which once again proves to me they are passionate about what they do, and willing to step up when things go wrong. I'll be working with Sal & Patrick over the next weeks to find out where to move from here (they and Altus aren't off the hook yet!), but getting back up and running is priority number one.

Oh, and I'm setting up automatic downloading of backups to various locations for my own sites as well now.

Question from Twitter: "What does Skytoaster have to do with AltusHost?"

Nothing, except that the VPS I bought from them was physically hosted with AltusHost (and I've been aware of it not being one of their own servers from the get go). While Skytoaster didn't get everything right in this case, I consider most of the blame to be with Altus who knowingly risks their clients' data and, in retrospect, seems to be a bit of a shady business in general.

While there is most likely a much, much longer preparation to this great news, there was a very fascinating tweet this afternoon by Digital Butter, a MODX Premier Partner based in Hong Kong, which happens to be one of my clients last summer.

In case you missed it, here's the tweet and accompanying screenshot that was tweeted:

For anyone who has worked with Media Sources before, this screen shouldn't be unfamiliar (minus that new "Dropbox" option!). If you haven't yet, however, you need to know that a Media Source is some kind of abstraction for the file tree as well as file browser in MODX. Prior to MODX 2.2 it was a pain to properly assign different permissions to different user groups, and when throwing some contexts into the mix it quickly got ugly. Now with MODX 2.2 you can create Media Sources which can be assigned to specific Template Variables, have certain base paths/urls so only certain areas of the filesystem are visible and more. However it also adds the ability for different storage systems, such as the Amazon S3 bucket which is included in the core. From the start it was clear that it would be able to offer more if people would develop the integrations. If I were to guess, a Flickr and Dropbox integration were the top two requested media source types. And, according to that tweet, we can now add Dropbox to the mix! (Don't have Dropbox yet? Feel free to use my referal link to give me an extra 250mb of space when you sign up.. much appreciated!)

You can probably imagine I got a little excited (and sidetracked from work, obviously) when I saw the tweet.. and to add to that, no more than two minutes after hitting the ReTweet button I got an email from James Bodell (lead Digital Butter fella and a great guy in general) titled "give this a spin", complete with a beta version of the package attached. Wicked!!! And so, I went off to investigate and see just how complicated it would be to get Dropbox integrated into my local test install. Turns out, it aint too bad but is frick'n awesome!!

How does it work?

After installing the package, there's a few steps you need to take.

  1. Create a Dropbox Application and get the App Key and Secret codes from here.
  2. Create a new Media Source (see the screenshot that was tweeted above), choosing "Dropbox" as Source Type.
  3. Update the Media Source, and fill in your App Key in the consumerKey property, and the App Secret into the consumerSecret property. Also make sure the accessType is correct - this depends on what you chose while setting up your Dropbox application, and in my case this was the Application Folder. Save the properties.
  4. Refresh the page (this is needed for the Media Source to verify your App details), and expand the description for the authToken by clicking the green plus sign. You should now see a link there (if not, your App details probably weren't valid or you didn't refresh the page) which you need to click to authenticate the Media Source to access your dropbox.

And that's it, and it doesn't take more than a minute or two (and adding some files to your new Dropbox/Apps/Name Of Application/ folder and letting that synchronize to the web) to end up with Dropbox integrated within MODX seamlessly.

Dropbox Media Source in Action

As with other Media Sources, you can restrict access to the Media Source through the Access Permissions tab so you have full control over who can access is and who can't.

Using the Dropbox Media Source

To use your Dropbox Media Source, it's probably easiest to drag and drop from your Files tab to the content or where-ever you want to use your Dropbox files. For example, if I wanted to write an article about some crazy bug I found, and I added the screenshot for it to my dropbox's app folder, I can write my content and drag the bug.PNG file to where I need it to appear. It will automatically get the right link which routes the request through your Media Source configuration and returns the proper file.

Using the Dropbox Media Source

Which results in your image being displayed as normal...

Front-end display of MODX Dropbox Media Source by Digital Butter

James told me they are not ready to publicly release it yet as the amount of support requests and bug reports coming in would be too much for them to handle right now, and instead they are having the team and friends beta it for a bit. I'll definitely be playing with this some more, and hopefully this will see a release for others soon. You can however find a package and the source on Github.

Now, I don't know about you, but I think we owe our Hong Kong MODX Development friends a round of applause for making this happen!

I like numbers, and analyzing them to see what is going on. As a result of that, I spend too much time in my Google Analytics code figuring out what is going on with my site and what content is most appreciated. However, I keep on finding non-public URLs for blogs which haven't been published yet in my stats.. but no more.

These visits are from when I visit a blog post which I've written to give it a quick proof-read, or to make sure the code blocks show up like they should. While not a disaster, I want to tackle this inconvenience and stop tracking my own visits. And hey, perhaps you can improve the quality of your clients' statistics with the same thing as well?

The Different Options and Considerations

There's a few things you can do. You can disable tracking for your IP through a Google Analytics filter, or by setting up a special page on your website/domain which sets a user cookie indicating we don't want Google Analytics to track us. While that would work, I also use my phone with HandyMan on 3G to work on my site or respond to comments and it would become a bit cumbersome to keep visiting a no-track page everytime I want to check my own site (as I'm pretty sure my phone's 3G IP changes quite often).

I just want to make sure anyone that is logged into the manager is not being tracked. So, perhaps I should just whip up a quick plugin that sets the Analytics cookie from the manager? Too bad that doesn't solve the issue when working on content on my phone yet...

Let's just get rid of the code!

The option I ended up going with is to just get rid of the entire Google Analytics code whenever I'm logged in on the Manager. This will work with HandyMan, as that simply logs you in to the manager as well, and I can live with seeing my own pageviews in my stats when I'm commenting on something without being logged in - after all, that's pretty much a valid request, right? :)

For this I first tried the "memberof" output filter on the 0 tag, however that gave problems when there was no user logged in as it returned a fatal error.. oops. I suspect this has been addressed in MODX 2.2, but as I haven't had the chance to test some quick-'n-dirty custom coding on my site in 2.2, I'm delaying doing the upgrade for now (tho it is a frick'n awesome release and I did launch some sites on it already!).

Now what? Custom snippet to the rescue!

Instead I quickly rolled my own code in a tiny snippet I called "isAdmin". The snippet looks somewhat (well, exactly) like this:

if ($modx->user instanceof modUser) {
  if ($modx->user->hasSessionContext('mgr')) { 
    return true;
return false;

All it does is check to make sure we've got an active user account, and if we do it checks if we are authorized for the "mgr" context. It either returns true (which translates to 1) or false (0), so on its own it's not too useful yet.. however that does work pretty well with the "empty" and "notempty" output filters/modifiers.

Using the Snippet & Output Filters

To cut to the chase (this was supposed to be a quick tip) here's my Google Analytics chunk with the all new isAdmin snippet in action.

What's going on here:

  1. We're calling the isAdmin snippet uncached, as per Caching Guideline 2 for MODX Revolution.
  2. We're checking if the result of the snippet is notempty (so we see if it has data, in the case of our snippet that's a boolean "true" or "1" when a Manager user is logged in). If the snippet returns something we put in an HTML comment, that way you still know the Google Analytics is being parsed.
  3. Next we check the output with the "default" output filter, which is the same as "empty". As we've chained these output modifiers, the snippet would have the HTML comment as value at this point in case the snippet originally returned "1". If it returned "0" it would still be considered empty at this point, which means we dump our Google Analytics code to the screen.
  4. And of course don't forget to close the tag at the end :)

Something else: as you can see I'm also using a setting with key "ga" to store my Google Analytics code in a system-wide or context-specific setting, allowing me to reuse the chunk across contexts without having to change it, by simply setting the right analytics profile ID in the context setting. I'm also telling Google Analytics to track the page load time, which is a nifty statistic to have.

Alright, that's it for now! Enjoy!