Stand With Ukraine. Stop Putin. Stop War.

Hello! Welcome to my humble web presence. I'm Mark Hamstra, 33 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 Sometimes I post three blogs in a week, sometimes there's nothing new here in a year. Read a random article.

14:50 And we're done. I'm up now, so can't continue blogging :) Leave a comment if you want to see more like this.

14:50 Susan Ottwell highlighting how awesome Revolution is because it lets you override basically anything, without meddling what's already there.

14:48 Breaking: Bert doesn't like MIGXdb.

14:48 Google is useful.

14:47 Most of the examples can be found in the Extending modUser document in the RTFM.

14:46 Why choose MODX? Interesting question at a MODXpo... ;)

14:46 Changing the table later is possible with modManager using addField/alterField methods. You don't lose data when the model changes but you do need to update the table.

14:44 Great question from Susan; why not extend modUserProfile? Could do that, but in this case just extending modUser seems to be fine.

14:43 Using the User extended fields doesn't work when you need to search through the data, as it's stored as JSON.

14:41 Bert claims he can't access the ExtJS files from here, but I think he just doesn't want to show it :P

14:40 To add the tabs to the user edit screen, a plugin is used that triggers on the OnUserFormPrerender event. It also triggers on the OnUserFormSave event which seems to do stuff for licenses. People want to see all code now!

14:39 Several people are mocking the usage of ExtJS. Can't blame 'm. :D

14:38 There's also another component that lists all the users and their licenses.

14:37 Now we're seeing the manager page for the extended modUser that Bert uses for SimpleCart. It has a new tab that Bert added using ExtJS, which shows the API Keys (licenses) for users.

14:35 With extending modUser we're not calling $modx->addPackage; instead we are only adding the extension package (using $modx->addExtensionPackage()) as that will make sure the package is loaded on every request.

14:34 Someone in the crowd recommends checking out MIGXdb to easily build from the schema.

14:33 The build script is run once to generate the models from the schema. The same as regular component development. The build script can be found in the RTFM. See here.

14:32 And that's a wrap! Time for questions.

14:32 We're indeed seeing that the fullname method works. We can still use the xPDO getOne method to get related objects, in this case the dateProfile object is huge!

14:31 Login not working! Okay, it did work the second time :)

14:30 Some clarification based on a question, the first and lastname are stored in the dateProfile object related to the dateUser. So this is stored separately (in the dateProfile table) from the core modUser (modx_users) table.

14:29 Unsurprisingly, the getFullname method gets the dateProfile object, and adds the first and last name together.

14:28 Back to the model to show the getFullname method. Bug spotted! The getFullname method uses the core xPDO methods such as xPDOObject->getOne to load related models.

14:27 We're now looking at an example snippet that checks if the user is logged in (using the hasSessionContext setting) and if so, it returns the fullname from the getFullname method, that was added to the custom user model.

14:26 Question from the audience, is it possible to set a default class key? Answer: not in the manager, but in the frontend using the Register snippet you can set a property to make sure new users are created with that class.

14:25 Of course all normal functionality and methods are available too.

14:24 MODX loaded. We're now seeing the class key is different, but everything else is the same as regular users. Awesome! When the user logs in it will use the custom model (dateUser), so you can access everything as normal (core) user methods.

14:24 Using the normal Login snippet you can login in the frontend of the site with an extended user. We're now waiting for MODX to load...

14:23 Bert explained how using custom methods on the extended modUser object can help keep things organised.

14:22 It's important to add the extended user as an Extension Package using the addExtensionPackage method on the modX object. This is also discussed in the Extending modUser documentation.

14:20 As with normal component development, you'll need to build the model out of the schema. A script for that is available from the RTFM, this one to be exact.

14:19 The manager pages for editing users does not change by using a custom modUser object. You can of course add custom manager pages for editing that.

14:19 Because the relation is composite, there is no need to manually remove the dateProfile objects after removing the dateUser. Aint xPDO awesome? :D

14:18 We're now looking at the schema file which shows a relation between the dateUser (an extended modUser) and a dateProfile which contains the extra data.

14:16 For component developers, the model and schema files are exactly the same as what they're used to.

14:14 Bert is talking about a dating site he built that had specific requirements to the user, such as encryption.

14:12 Bert is explaining the general modUser setup as it is in the core. This contains the modUserProfile (name, address etc), modUserGroup (permissions) and a number of useful methods such as isMember, hasSessionContext and isAUthenticated, generatePassword, sendEmail. Other useful data includes user settings, messages and profile data.

14:11 Bert Oost will be talking about extending modUser today.

It's that time of the year again. Working on projects and, oh look at the time fly by! I recall telling myself I wouldn't host MODXpo 2013 so I could just attend a conference instead of stressing myself out... yet here I am again. Along with a bunch of German MODX ambassadors and of course the MODX team, I'm on the organising committee for MODXpo Europe 2013.

Here's the facts you need right now:

  • November 1st (Friday) and November 2nd (Saturday) 2013.
  • 2 days, 1 track, 15 or so sessions, breakout rooms available for work/workshops/hackathons.
  • Lunch and drinks are included on both days.
  • KOMED Meeting-Centre at the Köln (Cologne) Media Park
  • Tickets are on sale now, with advance tickets available until August 15th at € 99. Tickets are bumped up to €149 after the 15th, and will be bumped to €199 in October. The earlier you get your tickets, the better!
  • NH Hotel Cologne Media Park is located pretty much next door. I stayed there a few months ago while visiting a Cologne MODX Meetup and am planning to for MODXpo too.
  • We're looking for speakers!

This year, MODXpo will be slightly different. It will be better. With more people involved in the organisation, a larger budget and a really, really cool conference venue it will be awesome.

Cologne is pretty too. There are talks of a Sunday touristy thing for people who are in town the day after as well, and of course there'll be plenty of opportunity to meet and greet MODXers.

Oh, and I'm bringing modmore swag and discounts, so you really have no excuse to miss this event.

Get your tickets | More information | Speak at MODXpo

Oh man, has it been over a month already? Please allow me to finally introduce to you modmore - More for MODX.

modmore is what I've been working on since resigning from my job at MODX. It launched for the general public on June 16th. My goal with modmore is to build a brand (which is bigger than just me) that makes working with MODX easier, better or just plain awesomer. Right now there's some really cool premium extras that provide designers and developers better tools for their clients, but in the future there will be other things, too, that I'm not yet going to talk about, hehe.

10% of all revenue of modmore is directly donated to MODX, too, which is just one of the ways I try to contribute to the future of the MODX core.

Thanks to modmore, I also get the chance to revamp some of the open source extras I've developed in the past, something I've only had limited time for in the past year. I just updated HandyMan to 1.0.0-pl for example (basically it works again after being broken for.. I don't know how long), I've started working on an all-new ImportX 2.0 that will blow your socks off and VersionX is next on the list with some nice new features to keep your content secured.

So.. what can you get at modmore? Besides €15 free credit for your first purchase when you sign up now, I mean.

At time of writing, three premium add-ons are available.


Currently the #1 selling add-on, Redactor is a really sweet rich text editor. It is based on years of work from Imperavi, and JP DeVries and myself have been spending a lot of time on making a really smooth integration. Since the first few beta releases I've been using it to write a lot of content myself and I really love the clean editing experience. Oh, but don't take my word for it - check out what others said about Redactor.

Redactor is available for €25 (that's give or take USD 33 / GBP 21,50 at current exchange rates) and you can read more and purchase it here.


If you're working with a larger client that wants to optimise conversions, SimpleAB is for you. It's a tool that lets you natively do A/B aka Split testing within MODX. Because it's all native, there's no performance hit from talking to external services and the user has no way of knowing if they're seeing a certain variation of your design or content. SimpleAB is available for € 49 (~ USD 65 / GBP 42) with everything you need to know here.


The latest addition to modmore is still in beta, but it already is catching up with Redactor in terms of sales! It's almost like people were waiting for a super user friendly, fast and flexible Gallery add-on that puts their galleries in the resources tree. Cause that's what MoreGallery is! Of course with drag and drop uploads and sorting of images and pretty much infinite possibility for front-end theming. Sign up for the beta.

All in all, modmore is just getting started and the first month definitely shows the potential premium extras have in the MODX world. I can't wait to bring you more great stuff and you can count on exactly that to happen.

Read the blog post at modmore introducing the concept in a bit more detail.

Sometimes you need to define multiple criteria in xPDO schemas to make sure your relations are properly defined. I came across this while working on a project that needed some existing databases integrated. This specific case had one "fl_translations" table that contained the translations for thousands of objects. To get the translations for a specific object, you would need to filter that table on the "originaltable" field. For example, one row might have originaltable=fl_colors and contains the translation for the color in a specific language.

In order to properly define this relation, I went browsing the MODX core schema for some ideas, and I stumbled across a pretty much undocumented feature of xPDO Schemas: relation criteria!

Here's a snippet of the final schema:

Basically, while with a normal relation you would immediately close the <composite> (or <aggregate>) element, but if you want additional filters (criteria) on the relation, you can define that. A simple <criteria> object with a target (I presume but haven't tested that you can add an additional <criteria> object with a target of local), and inside it a JSON object with the fieldname (of the foreign object) and the value it should have (in this case, fl_colors, as that's how it was set up).

This way of defining relations is very powerful and I imagine some really complicated relations could be defined once (in the schema) and reused without knowing all the details by simply calling getMany('RelationAlias').

The core uses this type of relationship for defining the PropertySets relations on elements and also in the modAccess definition. For example, here is a snippet from the core schema for modChunk:

xPDO is quite nifty eh?

Ever find yourself having so many tabs open in your browser, that you can't see what is what anymore? I just had that and ended up going into the wrong MODX manager tab to make changes. Argh!

Luckily there's a simple way to give the MODX Manager a distinct favicon if you want to, and if you find yourself in some sort of tab-ception and can't find the right tab, I encourage you to do the same.

Simply open your (Revolution 2.1 or up) manager, and head over to System > System Settings.

In the search field in the grid toolbar, type "favicon" and hit enter. You should find the manager_favicon_url setting.

Double click in the value column to open the editor, and then add either the full URL to your favicon, or an URL relative to the manager directory. In the screenshot below you'll see I referenced an icon for the modmore site - this shows me that I'm in the live site and not my local install I was working on..

Other urls that may be a nice fit for your manager (all of these ship with Revolution):

  • templates/default/images/modx-theme/grid/group-by.gif
  • templates/default/images/modx-theme/grid/hmenu-lock.gif
  • templates/default/images/restyle/icons/context.png
  • templates/default/images/restyle/icons/computer.png
  • templates/default/images/restyle/icons/database.png
  • templates/default/images/restyle/icons/disk.png
  • templates/default/images/restyle/icons/layout_edit.png
  • templates/default/images/restyle/icons/plugin.png
  • templates/default/images/restyle/icons/resources.png
  • templates/default/images/restyle/icons/template.png
  • templates/default/images/restyle/icons/user.png