Despite all of the many strengths of MODx, one thing it lacks is a native way of creating data relationships, so I’m going to propose a way to do this. [The topic of data relationships between documents/objects/resources, etc. in MODx was mentioned in a previous thread (
http://modxcms.com/forums/index.php/topic,28190.0.html) but I think it deserves its own thread, so I’ve begun one here.]
STORING RELATIONSHIPS
First of all, we need a table that can accommodate the relationships. I’ll call it
modx_site_relationship_data. I would create the following fields:
* id
* id2
* rank
where id and id2 contain the MODx IDs of documents. This structure can accommodate one-to-one, one-to-many, and many-to-many relationships (e.g. there will be an entry in the database for each relationship, possibly resulting in several entries with the same value for "id", with a theoretically infinite number of values for id2). That’s a starting point.
The "rank" field adds the ability to rank order the relationships, to force them to appear in a custom order.
If we want to extend the possibilities, we could either create extra fields in the modx_site_relationships_data table or create extra table(s) to allow for relationships between objects that don’t have MODx ids (files, urls, etc.). This is especially relevant in the next generation of MODx where files are visible in the tree structure.
DEFINING RELATIONSHIPS
We’ll need a table to define the type (one-to-one, one-to-many, or many-to-many) and parameters of the relationships. I’ll call this table
modx_site_relationships. Parameters can include some ready-made options, but also allow for custom options. Examples of some useful ready-made options are:
* all documents with a certain template (or templates)
* all documents with a certain parent (or parents)
It would also be nice to have a built-in "where" option so that users could type in things like "where id < 200" or "where pagetitle like ’%2008%’, etc.
For non-standard situations, users would also be able to write custom PHP snippets to specify custom relationship parameters.
There would be a few options for displaying the relationship options when editing the page. Some possibilities include:
* as checkboxes
* as radio buttons
* as a single-select drop down list
* as a multi-select drop down list
* as a text input, for typing in the ids of the documents as a comma separated list
So the fields for this table would be something like this:
* name (the name of the relationship)
* type (one-to-one || one-to-many || many-to-many)
* parameters (from a list of ready-made parameters)
* where (simple filter for the ready-made parameters)
* custom_parameters (referring to a custom snippet)
* control_type (checkboxes || radio buttons || single-select drop down... etc.)
ASSOCIATING RELATIONSHIPS WITH TEMPLATES
It would probably also be wise to have specify relationships at the template level. This would require another table (e.g.
modx_site_relationships_templates) that associates the relationship with templates. It could include the following fields:
* template_id
* relationship_id
CREATING RELATIONSHIPS
Users would create relationships when editing or creating documents in MODx. They would see the control type specified in the modx_site_relationships table, and potentially would see a list of documents to choose from.
This would be the easy part! And this is where the benefits really begin to show.
(Note: When chosing from multi-select lists, one thing that I think will be very important is to have a JavaScript or AJAX control that writes to the page as soon as items are selected, by displaying a new line of text for each relationship as soon as it is formed either above or below the list, with an "X" by them for easy deletion. Othewise, users have to remember to hold down the CTRL/option key while selecting items, and may make a mistake and accidentally de-select them all.)
RETRIEVING AND DISPLAYING RELATIONSHIPS
We’d have to come up with a new way of retrieving and displaying relationships, because until now, all of the MODx tags (e.g. for TVs, links, system settings, etc.) refer to a single value, not to a list/array of values. We would need to create a new kind of tag that specifies a relationship and allows for parameters. Here’s an example of displaying a list of instructors for a course (using syntax more like the next generation of MODx):
<ul>
[[@course_instructors
<li>[[*instructors.fname]] [[*instructors.lname]]</li>
]]
</ul>
Explanation:
* The "[[@" is a tag I made up to specify an array or list (any syntax could be used; it doesn’t have to be "@")
* "course_instructors" is the name of the entry in the "modx_site_relationships" table
* Notice that the "<ul>" and "</ul>" tags are outside of the reference to the relationship
* Notice also that there is only one list item within the relationship tag, because this information will be looped.
* The name of the table (or I guess it would be the name of the template) is specified, to ensure we get the data from the right place. We could place document data from either side of the relationship within the call to the relationship (e.g. [[*instructors.email]] and [[*course.title]])
It should also be possible to put snippets, PHx syntax, or other types of information within the array object. Here’s a quick example:
<ul>
[[@course_instructors
[[custom_instructor_snippet]]
]]
</ul>
Final Comments
The exact details of this proposed solution could be worked out and modified, but I believe this is a solid start to solving an important MODx weakness.