Hello! Welcome to my humble web presence. I'm Mark Hamstra, 28 years young, wearer of many hats at modmore, resident of Leeuwarden, the Netherlands. Most of my time is spent building and maintaining awesome extras and tools at modmore, but I also love gaming, cooking, and my dogs. More about me.

This site is where I share thoughts, cool projects and other oddities related to MODX, xPDO and ExtJS. I also write about MODX regularly over at MODX.today. Sometimes I post three blogs in a week, sometimes there's nothing new here in a year. Read a random article.


As promised in a recent announcement, I was going to provide some tips on serving MODX sites over SSL based on my move to a complete SSL-based website. Here they are!

SSL Tip 1: Using protocol insensitive URLs for assets from the get go

You can apply this tip, even if you are not going to be serving anything over SSL soon! If you, like me, point to assets complete with the domain, you will risk serving non-secure content when making the switch. This is easy to prevent by not specifying the protocol, which is the "http" or "https" part.

An example before:

and after:

So basically you take a full URL, and instead of specifying "http://" or "https://", you simply specify "//" which will make it relative to the protocol in use.

SSL Tip 2: Generating HTTPS urls with MODX by default

When using the url syntax (like [[~1]]), this is usually relative to the site_url, the default. However it's easy to change this to use any other scheme both on a per case basis, and across the entire site through a system setting.

To change one link, pass &scheme=`https` to the link tag. Wait, you can add properties to link tags too? Yeah! For example, this is completely valid: [[~1? &scheme=`full`]].

To change all links to use https, find the link_tag_scheme system setting and change its value to "https". When not using https, I like to change this setting to "http" so all urls are absolute. All possible values for the &scheme property or link_tag_scheme setting can be found in the makeUrl documentation

Now, there are some Extras that don't neccessarily follow suit here and use their own defaults. Wayfinder, for example, has its own &scheme property you will want to change. And when Wayfinder points to the homepage of a context, it points directly to the contexts' site_url, so make sure that has https as well.

SSL Tip 3: Telling Quip to use secure Gravatar URLs

If you're using Quip for comments (like me!), you will usually use Gravatar for comments which usually serves over http. Luckily, Gravatar does offer a secure link to avatar images but Quip isn't aware of that by default. But it does give you the opportunity to change the link to the gravatar images. This allows you to use a proxy on your own server, or to point to the secure Gravatar url instead! :) This is the &gravatarUrl property. As the secure url for Gravatar is https://secure.gravatar.com/avatar/_MD5_of_email_h..., that's what we set the property to.

Before

After

That concludes this list for now. Do you have any good other ideas? Let me and other readers know in the comments below.

I've been really busy at my new job in between moving, throwing anniversary parties for the folks and trying to manage a couple of projects I'm still involved in personally. I've got some article ideas (and drafts) nearing a publish-ready state, but it really has been too quiet. In this post I want to provide you with a few quick updates with a promise for more quality posts "coming soon"!

Slight updates to my Design

You may have noticed while browsing the MODX Blog, Category or Archive pages, but I have been spicing things up a tiny bit! Blog items now show up with images in the listings, and the homepage has been updated to funnel people to the blog more easily as well. I am also using more images in article contents where applicable using my MIGX Gallery set-up and I have subtly improved the way my sidebar widgets appear on tablets. If anything my site is a constant work in progress and I hope you can appreciate these updates. If you have any feedback be sure to get in touch, or to leave a comment!

Doing my bit to make the web more Secure

Obviously by simply using MODX I'm doing my bit to make the web a more secure place to hang out at, but over the past week or so I've been working with my awesome hoster on serving my site over SSL.

Why?

Well, why not?

I'm already paying for a VPS (I need the processing power and storage for one of my personal projects) and as SSL certificates start at like €15 a year, I couldn't come up with a good reason not to. My visitors will be able of browsing my site securely (even if there's no log-in or personal data going 'round) and it's a nice experiment in general. 

There were a few challenges to getting to this point, but all in all it went mostly smoothly.

  1. The site needed to move to its own dedicated IP. Normally this is quite smooth, but it resulted in a few hours of down time due to the odd way I originally set up this site, which meant that for this to work smoothly, the site needed to be migrated to a new user on the server manually (which is harder than it may sound with all the loosely connected legacy cruft this site has already built up!). 
  2. As I've been using an assets sub-domain (among others) to split requests and speed up site loading, the sub-domain also needed to be served over SSL. Patrick did a great job helping to get that up and running. 
  3. This is probably the most annoying challenge, which is making sure you do not point to any non-ssl scripts or images - anywhere. There's stylesheets in the header, scripts in the footer, and most importantly: images in the content. There is also comments which uses Gravatar over non-SSL by default.

I will be publishing a new article probably next week with some specific and easy to action tips on preparing your MODX site for running over SSL.. stay tuned for that! Over the next few days I will start enforcing HTTPS as well (you can still visit over HTTP for now by changing the url), so if you do spot any issues - be sure to let me know!

VersionX 2.0.0-rc2 and 2.0.0-rc3!

I have to admit: VersionX is my favorite Extra right now. It sits in the background doing its thing, and when you screw something up you can go back and restore an older version. RC2, released on May 28th and RC3 released on July 8th, both fix a number of bugs that people have reported on the Github page, and it now has an interface for all data it collects! The next version will likely get rid of the "release candidate" moniker and introduce some more restore options that are not yet available. 

Read more about VersionX, just download the package, or make a donation

getRelated 1.2.0

If you don't know what this is, getRelated can be used to automatically show related items on a Resource. It's used in this site and I have seen many examples of it in use all over the place. By taking a getResources-like approach and offering easy ways to customize the sorta complex algorithm it uses, the result can be fine tuned to the bone and templated all the way you want it. 

In the June 7th release of getRelated 1.2.0 this is even further improved, as it now features a &stopwords property to assign a custom comma separated list of words to ignore for that instance, it properly supports multiple (different) snippet calls per page now, adds Russian support and the default output is now a bit more sensible too.

Read more about getRelateddownload the package or read the documentation.

ContextRouter

While released in March already, I never really publicized it much, but with the MODX Cloud Beta rolling out (which was the inspiration for writing it!) I'm plugging it here. ContextRouter is a plugin that eases setting up different (sub)domain contexts by taking your http_host context settings into a custom cache file, and routing requests to the proper context based on that. It's available via the package manager as well. 

You probably noticed MODX was represented at the CMS Expo in Chicago, already a week and a half ago. I was there too! For me personally, this was a week of "firsts". First time on an 8hr flight, first time outside Europe and in the United States, first time visiting Chicago and first time meeting my employers (fun story).

The week was awesome.

Arriving on Saturday at 2pm (after leaving Amsterdam at 2.40pm, aint that amazing?), I was completely broken and barely managed to stay awake until 9pm which is when I hit the very comfy king-size bed at Hotel Orrington. Sunday morning I bought myself a week-pass for the public transit to head downtown... Holy cow, 45 minutes per train to get into downtown Chicago?! This city is huge! After strolling around a bit and heading for Millennium Park, it started to rain and I found my way to Panama Bread for some lunch. Back to the hotel in Evanston to check in on the folks at home, email and the social networks. By the time all that was done I headed to Austin Tacos... Let's just say America has funny tacos. :P

    no stuff

The next day, which was Monday, was when the rest of the MODX team was going to arrive as well as the first attendees of the conference. After grabbing a cup of coffee to-go and intending to wait for them to arrive in the lobby, the door was opened and some faces that I just knew from avatars on Skype and Twitter walked in.

How do you greet people you have never met in person before, but have been in touch with for ages and now work with every day? I think I got as far as "you guys have to be from MODX!", or something silly along those lines. Kinda weird moment, but definitely one of the highlights of the week. The day went on with a mix of hanging out, building a booth, meeting more people formerly known as twitter or skype nicknames and getting to see some American excess first-hand at a local pizza place. I also had the pleasure of meeting Aaron Ladage (/la-dag-gie/, not /la-daaj/ as I imagined) and JP De Vries as well as others  - familiar names, but new faces.

Tuesday, Wednesday and Thursday were conference days which meant lots of talking, talking and spying on..er..getting inspired by the work of other platforms represented there. I personally got to see some Wondercode (odd business model, but a real WYSIWYG editor) and MuraCMS (awesome import/export functionality and some other interesting features) flyovers as well as the majority of the keynotes in the ballroom on content management strategy and history (instead of just the tools which highlighted the rest of the conference).

There was also plenty of MODX, of course. From the showcase session to the impromptu code share meeting in a room we sort of claimed, and the MODX (and friends) meetup at a local restaurant on Wednesday where everyone was too busy chatting and drinking "Revolution" beer (I kid you not!), to think about silly stuff like food. The team also brought along "the helmet", and many attendees were spotted wearing it (on picture, too).

    no stuff

After more talking, demo-ing and having a great time at the expo, the Thursday ended with an open showcase where site builders could show off their sites (MODX heavily represented with some truly stunning sites), and finally the famous "gotta have it gadget giveaway". I won a laptop cooler (one of those things you put on your lap that cools your laptop and prevents burning your delicate parts at the same time), but if he had not had an early flight back north our one and only Jay Gilmore would have won an iPad3 ...!! I hope that is a lesson for one and all to not leave before the final session..you never know what happens! ;)

After all that and saying our "see you later"-s to the people rushing back home I finally got to try the legendary pizza place in Evanston with JP De Vries and Jason Sonderman, also a MODXer from Kansas, things finally slowed down.

Friday I went downtown Chicago again, this time to visit Intelligentsia Coffee for coffee geek brother Kevin, the Chicago Cultural Center for the obligatory cultural sniffing and the Sears/Willis tower - 103 floors up in the tallest building of North America.

    no stuff

Saturday I had to get to the airport for my 4pm-7am (local) flight back home, after which I went back to bed and woke up just on time for dinner.... The joys of a jetlag. I did manage to get some nice shots on the flight home.

    no stuff

Now, all this was two weeks ago. Last week I also (finally) moved, and I now have my own place (with plenty of room for receiving people) in Leeuwarden, the Netherlands. I also released VersionX 2.0.0-rc2 last night.

In December 2010 I started developing VersionX 1.0 as a pet project. Now, 16 months later, I'm very glad to announce the immediate release of VersionX 2.0 - more stable, powerful, better organised, and available for MODX 2.0-2.2. 

While you can view the entire 2.0 changelog on Github, here's the gist of what you really want to know right now:

  1. Keeps track of changes to Resources (including TV values), Templates, Template Variables, Chunks, Snippets and Plugins. If you don't want to version a specific type of element, you can also disable that per element type.
  2. Offers a central component to view the details of versions and compare them for Resources, Templates and Template Variables.
  3. Offers the ability to revert Resources to a prior state.
  4. Has the (optional) ability to display tabs with a versions grid on Resource and Template update forms. 
  5. It's free (though donations are appreciated)

VersionX is now available as a release candidate from the MODX Extras Repository, and the source as well as issues list is available on Github

    no stuff

You can help!

We're currently in a release candidate phase. That means I have been using it for months on my own and client sites, but that it could probably do with more real world testing and people breaking it in ways I wouldn't have been able of thinking off.

Here's some ways to help shape up VersionX:

  • First of all: install it, use it, think of ways to make it better and post it on Github.
  • Developers: find bugs or requested features, and use Github to send over a pull request with your addition.
  • International folks: translate the lexicon file (just one for now) to your native tongue for inclusion in the next version.
  • Make a donation.
  • Spread the word! Blog about it, point people to the package when they need Versioning, share it on facebook or tweet it out!

Just a quick post here for something that I see asked (or, more accurately, see being done in the wrong way) way too often.

When you're building your own components or data model using xPDO Schemas, you will probably be working with that data in processors, snippets or external applications as well. At some point you will have related tables, and you will love coming across methods like addOne and addMany - they're awesome!

There's one big caveat when using them, and that is to figure out which one to use.

Oh, you use addOne when you want to add *one* related object, and addMany when you want to add multiple in one go? WRONG. Well, okay - there's a small truth in there. But it is not related to the fact if you're in the process of adding only one related object or an array of objects. If you are using the wrong method you can often see this by the lack of relation being added to the extra object(s), like the relation is not "sticking" for some reason.

So do I use addOne or addMany?

If you've read the Defining Relationships documentation page, which is a great introduction to aggregate and composite relations with xPDO schemas, you should have noticed this thing called the cardinality. This little thing is very important and the key to figuring out when you need addOne, and when you need addMany.

You see, if the cardinality is one, you will need to use addOne. If the cardinality is many, you will need to use addMany. And that's all folks.

That's all folks!

Teaser image by Sepehr Ehsani.

As of MODX Revolution 2.2, developers are handed class-based processors to speed up development of the back-end components. These are great, and I have blogged about Class Based Processors in general before with some quick examples, but in this article we'll dive into a particularly awesome one: modObjectGetListProcessor.

The modObjectGetList processor is mostly used for populating grids through the modExt Grid implementation, but you could also use it for any other widget that uses a JSON Data Store. And processors aren't limited to being used by connectors for back-end components.. they're also great to keep your code DRY (Don't Repeat Yourself) for use in Snippets!

For this article we'll assume a simple grid though. The techniques displayed can be used to point you in the right direction for other implementations.

The Basics

Here's basically the minimum processor file you can use:

.. and the reason they're so awesome. Brief, super awesome, working code!

The most important thing to note is the public variable $classKey, this is the class name of the object you are going to retrieve. Furthermore you'll see we define the $defaultSortField to the "initiatedon" date field from the schema, and with $defaultSortDirection we make sure we get the latest on top. The $objectType variable is not necessarily required, but allows you to use prefix (lexicon) error messages for some default sanity checks. For example in the update processor it will use the objectType to prefix _err_ns if the primary key is not specified.

We also make sure we return the name of our extended class in the end, as that is used to instantiate the processor when it's called. While you're free to name it whatever you want, I'd advise you to keep it the same as your classKey. That way, when adding a new processor, you can just copy/paste another one and find/replace the old classKey for the new one and you're good to go.

Exploring the Processor Process

Just like an earlier post, dealing with the modObjectUpdateProcessor class based processor, I have created a list of what happens in the processor that you will find below.

  1. Processor instantiated, properties being set.
  2. Using checkPermissions() the processor decides if the user is allowed to access it.
  3. The processor finds lexicon topics to load via getLanguageTopics, which gets its data from the languageTopics variable (as an array).
  4. initialize() is called on the processor, which sets a number of default properties including sort to the defaultSortField (default: name) class variable, and the direction to the defaultSortDirection variable (default: ASC).
  5. process() is called.
  6. beforeQuery() is triggered by process(), and if the result is not a boolean TRUE it will consider the processor to have failed and cancel further execution.
  7. getData() is triggered by process().
  8. The getData() method builds an xPDOQuery object for the classKey type.
  9. The getData() method calls prepareQueryBeforeCount(xPDOQuery $c) allowing you to add additional conditions to the queries. After calling that, it fetches the total amount of results using modX.getCount.
  10. prepareQueryAfterCount(xPDOQuery $c) is called by getData().
  11. The query is sorted with help of the getSortClassKey() method, and the sortAlias, sort and dir properties.
  12. If the limit property is larger than 0 it limits the query and sets an offset.
  13. modX.getCollection is called with your data, it's been retrieved.
  14. Every row is iterated over using the iterate(array $data) method. iterate calls beforeIteration(array $list), and starts looping over the rows.
  15. If the checkListPermission variable is true, the object extends modAccessibleObject and checkPolicy('list') is false, it skips the row.
  16. prepareRow(xPDOObject|modAccessibleObject $object) is called which needs to return an array with the objects' fields. Great method to customize the retrieved data. The array is added to the list.
  17. After iteration over the entire result set afterIteration(array $list) is called.
  18. The data is returned.

Example Usages

Defining Constraints (where field X has value Y)

When adding constraints, we will take our minimum processor and add (actually override) a new function called prepareQueryBeforeCount. This function takes in the xPDOQuery object as parameter, and expects it to be returned as well.

Easy enough we first get the "reservation" value using $this->getProperty(). By specifying a second value we are assigned a default instead of NULL. In this case I'm setting the default value to zero, which makes sure that if there is no reservation passed, it will not return any results - but no results instead (as all rows have a reservation set to > 0).

After getting the reservation variable, we just interact with the xPDOQuery $c as we would in a normal processor (or script) and pass our where condition.

In the end we return the xPDOQuery (this is important!) and we've limited our query to just that reservation.

Modifying the way row data is returned

In some cases, your database set up may not completely match how you want to display that data in the front end. For example, you may have an array (which is stored serialized), which you want returned as one line of text per array key=>value, for rending in a textarea for example.

You will also see that instead of calling simply $object->toArray(), I am passing some additional parameters.

Specifically selecting fields

You could also join tables in the prepareQueryBeforeCount processor, add additional constraints etc.

Are there any more examples you would like to see, or have some to share yourself? Let me know in the comments!