Friendly url alias for data in custom database table

I’m working on a website that lists events in a calendar layout (date, title). Each event is organised into family and parent categories, and each event has a detail page to show further information (content, images…).

This is managed via MIGXdb and the output from the Family, Parent and Event tables is like

  • events
    • cycling (family)
      • sport (parent)
        • 2023-12-04 Time Trial Round 4 (event detail)
        • 2024-01-19 Time Trial Round 5
      • expert (parent)
    • rugby (family)
      • under 16s (parent)
        • 2024-05-12 Junior Cup Round 1
      • adults

The easy option to access the detail page is with a querystring eg. /events/detail?event_id=123 but this is not very user friendly. Instead the event detail URL should be like

/events/family/parent/yyyy-mm-dd--the-event-title-slug/

The date is included here as there is a high chance of future events having the same family, parent and title as they are annual leagues.

But this URL structure doesn’t handle the potential for Manager users to change the date/title of an event which would lead to 404 responses on the original URL.

Obviously each Event has a unique ID that could be used eg.

/events/family/parent/yyyy-mm-dd--the-event-title-slug/123

I could then use .htaccess to rewrite requests matching this pattern to the actual Event Detail page and use the ID to retreive the Event Details from the databaase. But the ID on the end is still untidy.

Can anyone suggest options to implemet native MODX style Friendly URLs in the same way that would be available if the Events were stored as MODX Resources rather than in the custom database?

Is there a simple way to use existing MODX functions to help?

The function that generates the modx_site_content.alias entry would be useful to generate the event-title-slug. Can this be invoked from a

How would you handle this?

Thanks,

Chris

Another option is to do this in PHP in a MODX event.
Usually the event OnPageNotFound is used for this.
(For example in the extra “Tagger”, there is a class “TaggerGateway” that handles request in the form mysite.com/my_resource/tagger_group/tagger_tag, extract the tags/tag-groups and uses $modx->sendForward() to show the correct resource my_resource.)


MODX has the function filterPathSegment that you can use to “filter a string for use as a URL path segment”.

Nice one, thank you. I’ll get a look at those.

The working TaggerGateway example will be especially useful.

There also exists the extra CustomRequest, that may work for your use case.
In case you don’t want to code the plugin yourself.

CustomRequest looks like it achieves 90% of my requirements.

I just need to figure how to implement the filterPathSegment element to add a friendly event title to the URi. Or I could take the easy route and just add the eventID to the URI.

Next time I’ll check the Extras catalog before posting - I should have found that on my own.

Thanks again.

There exists an output modifier for this: [[+pagetitle:filterPathSegment]].
Or you can call it in a snippet → $alias = $modx->filterPathSegment($title);

Genius, thank you.

I’ll think this through later to see how it would affect cases where a Manager user changes an Event Title but the original URI has been published on other websites/social media.

It wouldn’t matter if the Alias Path for CustomRequest was eg. /events/eventID/family/parent/+event_title:filterPathSegment/.

But search engines could still pick up the original URI which would still respond based on the eventID meaning the two URIs would compete with each other unless the canonical can be specified…

More thinking is required

@halftrainedharry finally looking at this again.

The solution to automatically create a slug (alias) from the Event title turned out to be straight forward.

In my existing custom migx update.php Processor I noticed a comment //overwrites on line 312 with examples of how to overwrite items in $postvalues.

So I added the following to generate the required slug.

if (($classname == 'VenueEvent') && (empty($postvalues['slug']))) {
    $postvalues['slug'] = $modx->filterPathSegment($postvalues['title']);
}

A better solution might have been to mirror the same functionality MODX uses to set the alias field using the pagetitle for a Resource but I couldn’t figure how to do this inside a MIGX update window.

The relevant code seems to be translitAlias: function(string) { in \manager\assets\modext\widgets\resource\modx.panel.resource.js, however even with your helpful video about MIGXdb Customisations I didn’t figure it out.

This function only works for the resource alias field.
In the function, the Resource/Translit processor is called (with Ajax) and the processor then executes filterPathSegment.

It’s theoretically possible in MIGX to use “Description is Code” = “yes” for the windows field to add event listeners (keyup, blur) and call a similar processor.
But such functionality is hard to implement (in MIGX) and the only advantage you have, is that the translit happens in real time (while you enter the title).

Noted - increasing the complexity is not part of the goal so I won’t look at this further.

The real time transliteration would be helpful from a user perspective and maintaining uniform behaviour across MODX. But good enough is good enough at this point and there are plenty of other items that need attention on this project.

Thanks again.

This topic was automatically closed 2 days after discussion ended and a solution was marked. New replies are no longer allowed. You can open a new topic by clicking the link icon below the original post or solution and selecting “+ New Topic”.