CMP to dynamically generate resources?

Excuse me If I am in the wrong area here, but I’ve come up with an idea and I am not sure how to proceed.

This is the website I am creating using modx.
https://www.tuscarorabaptist.com

As of right now I am having to create the resources for the ‘Sermon’ pages. What I would like to accomplish is a way in the manager to create the resources dynamically using php. IE.

a directory in assets will contain the directory structure and files sermons>[sermon-category]>[single-sermon]

In the manager I would like to create a simple script that parses that top ‘Sermons’ directory and then dynamically generates resources based on that structure, folders are parent resources and files are sub-resources. This then allows me to use getResources to dynamically generate the web pages based on that Sermon parent>Single sermon structure.

I really have no idea where to get started and when I do research I am kind of overwhelmed with the different information presented. Any help and guidance on this process would be greatly appreciated, along with any gotchas etc.

I’m normally able to muddle my way through things, but this seems like a stretch too far atm.

I think there is a tutorial on the docs site for using migx cmp as a way to manage and create resources. I would suggest looking at that and making edits where needed and you should be off to a good start. if you can’t find it let me know and I’ll try and dig it out.

@jasincole, I feel like I’m partially following you, but I also feel like I might be over thinking it…? :slightly_smiling_face:

It sounds like you want to generate pages (resources) of content from something. So instead of using pages (resources), what are your thoughts on the delivery of the content? Where would the content be? Is the content literally the MP3s?

Am I gathering that you want to be able to automatically pull each MP3 (“assets/sermons/revelations/*.mp3”) and place it on an automatically generated page (resource)? Or?

Generating resources in PHP code is very simple, as is creating directories.

You might consider just creating a PHP array containing the directory structure, then generate both the directories (which you may not actually need) and the resources from it.

yes, I think you are following. The content is just the mp3 files. At first I decided to use getResources to pull in the files. This worked, but I found manually creating the resource entries for the audio files (IE. one child resource for each audio file) to be much more work than I expected and wasn’t really the solution I was looking for.

As of right now I am using a snippet that I created to generate the HTML code from the audio files themselves using a naming convention. This reduced my use of resources down to just the directories which organize the audio files into relevant groups.

The simple reason for needing resources is so I can specify more information. Like longtitle, description, TV’s, etc that can be used to create the sermon page that displays the sermon categories. As well as other features like publishing etc.

I may be able to help with this @jasincole. I have built a ‘static resource creator’ for a site that drag/drop uploads the files and automaigcally creates the static resources to go with those files in the tree when the uploads are done.

Does that sound like the kind of thing you’re after? Are you planning this for ongoing use or just to get everything created in the first instance and add them the ‘slow way’ week to week?

Using this system you’d need to generate the folders, but then uploading the MP3s and having a resource-per-file created in the right place in the tree would be pretty straight forward.

Quick tip: I’d set the social icons in the page header open in new tabs so people don’t get taken right away from your site. (If you’ve consciously chosen to have it as it is, then by all means ignore me though! :smiley: )

1 Like

I know, people use MODX - resources for all and everything, but often, it may be better to store stuff like that into custom - tables.

1 Like

I’ll admit to be new and naive, but I thought resources was the ‘modx’ way?

What are the benefit and drawbacks of doing it the way you suggest? Is there some reading material on how you propose to do just that?

Yea, he could probably store the extra data like “long title, description…” in the metadata of the file and pull that with PHP too. :yum:

As with most things MODX, there are many ways to achieve your objective :slight_smile:

It took me several years in my MODX career to learn that bolting TVs to templates wasn’t the best way to manage all my data too. As someone who would rather work with great tools than build them it was so easy and powerful and fast to create what I needed that way.

The thing with resources and then attaching TVs is they have a bunch of overhead because they’re actually for rendering pages. Under the hood, TV data is actually several database tables removed from the resources they’re attached to. So when you want to pull hundreds of items you’re asking for a fair bit of relatively heavy lifting to be done.

Compare that to a single database table which has a list of exactly what you need - it’s a single database grab for the software instead of many.

Honestly, on a small/quiet site with caching setup well you won’t see much real-world difference at the user end in terms of speed. There’s just a compounding effect.

Many moons ago I built an online store which worked that way. It was great during development - then they moved in a few hundred products and page load times jumped up around 30 seconds! I had to completely refactor it and shop around for better hosting to run it faster.

The different also plays out in the ‘niceness’ of managing the media. A MIGX CMP solution will get the media out of the tree into its own neat box for managing. The Collections extra can be used to manage that with resources - it just plays out with technical overhead again.

The main pro/con list as I see it is -

In resources
Pros

  • Easier to set up if you don’t know your way around setting up the database solution
  • Can feel more familiar to people used to working with resources

Cons

  • Slower page loads, getting worse as numbers get bigger
  • Managing large numbers of resources in the tree can become unsightly

In database/custom manager page
Pros

  • Sections the media off nicely in it’s own logical space for management
  • Faster and easier for the machines to work with

Cons

  • A bit more intensive to setup and comes with a learning curve if you’re familiar with resources and not with databases and classes
1 Like

This is a great point!

If you just need a few fields of data and you want to use resources, rather than adding new TVs which adds overhead, you can use Manager Customisation to rename existing fields. Relabel ‘Long title’ as ‘Running time’ and you have your running time field etc.

And if you use the Static Resources type then the content field becomes your file pointer.

To circle back to your original question: once this decision is made (sticking with resources is fine vs I’d like to try database tables) then we push on to the best way to get the data imported.

Since I haven’t decided on an approach yet, so I was trying out some snippet code to create resources using runProcessor() but I don’t know where I went wrong

This works as I would expect it makes test2 resource in website root
$response = $modx->runProcessor('resource/create', array('pagetitle' => 'test2'));

This doesn’t work at all. Yes, ID(45) is created and isFolder so what in the world is going wrong? I don’t even get an error, nothing is returned.
$response = $modx->runProcessor('resource/create', array('pagetitle' => 'test3', 'parent' => 45));

There are a number of fields that MUST be set for this processor to work. Was there anything in the error log that might have indicated what it didn’t have that it needed?

I’ve just gone for a dig in one of my projects and here’s the code I use to create a new resource:

$fields = array();

// Set the page title
$fields['pagetitle'] = "Your page title";
// Set the parent you'd like this resource to have in the tree
$fields['parent'] = 23;
// Set the content field
$fields['content'] = "/path/to/your.file";
// Set published to yes
$fields['published'] = 1;
// Set the content type to modStaticResource (so you have a static resource)
$fields['class_key'] = "modStaticResource";
// Set the context you'd like the thing to appear in - if you don't know what this means you want 'web'
$fields['context_key'] = "web";
// Set the content type to the ID of the content type created for MP3 (or whatever audio format you're using
$fields['content_type'] = 8;
// Set the template you'd like the resource to have
$fields['template'] = 8;
// Set content disposition to 1 which makes it an 'attachment' which pushes as a download rather than trying to display as code
$fields['content_dispo'] = 1;

// THEN run the processor
$response = $modx->runProcessor('resource/create', $fields);

From memory the only ones here that are vital are pagetitle and context_key, but it makes sense to lock in as many of these correctly as you can.

If you need more help with creating the ‘content_type’, let me know. This is the part that lets MODX successfully deliver the finished file in a way the browser understands.

Well I now see what the problem is, the reason I was having such a hard time was that $response->getMessage() didn’t actually return anything even though there was an error. The problem was the alias was already used.

Seems to me that getMessage() should report that. I know if you create a resource in the manager with the same alias an error is reported, so where is my error message?

here is my code

foreach(glob('*', GLOB_ONLYDIR) as $directory) {
    $fields['pagetitle'] = $directory;
    $fields['alias'] = $directory;
    print_r($fields);
    
    $response = $modx->runProcessor('resource/create', $fields);
    if($response->isError()) {
        print_r($response->getMessage());
        return;
    }
}

EDIT I got it now, I had a peek at the api docs and a call to getAllErrors() returns the error.