I'm working on a custom module but I need some advice on how to implement part of the business logic. The purpose of the module is to allow an admin to easily schedule particular pieces of content for specific regions. The part that makes this different from something like the block module is that the user would like the content to vary depending on the page. Specifically, the use case involves advertisements and choosing specific ads to run on specific pages.
Since the ads will differ depending on the category of the story, etc. it doesn't make sense to have dozens and dozens of blocks which point to the same region in the template. My idea is to allow the user to schedule a particular piece of HTML content for a particular region and then to specify which URL patterns to use to determine if that rule should be followed. Later I will be adding the ability to also schedule a date range but I'm keeping it simple for now.
I was wondering if anyone could give me some good advice on the "rendering" part of the process. The module will need to look through the possible URL matches and pick the "most relevant one." For example you have the url http://example.com/foo/bar/node16. One rule might have a pattern of foo, another foo/bar and another foo/bar/node16. We'd want the most specific match to show up.
I'm brand new to Drupal and PHP although I'm an experienced Java programmer. So I'm wondering if there are some obvious api calls I should be leveraging to help with this business logic. Sample code/pseudo code would be greatly appreciated. I'm also willing to contribute the final product if there is interest.
TIA,
flanderz
Comments
Some thoughts that may help
First for path/page matching you may wish to look to the block module. See the function block_list() and look for the comment "Match path if necessary" (line 662 in my copy). This would speed things up and use an interface that is already used.
Next consider you do not really need to use block if you are going to schedule the HTML content to a region. If you do things this way you could use the init hook to determine the content to show and use drupal_set_region() to directly place the content in the region. (you could of course associate the HTML content with a block (instead of a region) and use the block hook.
If I was doing this I would schedule and node node based content. I would use the form_alter hook to modify the content type setting page so a user/admin could enable/disable scheduling to a region per content type. (This way they can chose which content type can be scheduled). The also using the form alter hook, if scheduling has been enabled for the content type add the approriate fields so the content can be scheduled.
Thanks for the feedback. I
Thanks for the feedback. I suspected there might be some helpful API functions out there (like block_list), I just needed some advice on where to start looking.
I wasn't really considering using blocks. I only mentioned them as an alternative (but complicated) solution to my problem. I agree writing content to the region is exactly the way to go. I took a look at hook_init but the docs suggest that you not use this for pages that could otherwise be cached. In my use case I think its ok to cache the ad content as long as the cache is cleared whenver the user changes the scheduler (plus a periodic cron run once I add specific time schedule parameters.) Any other ideas on where to perform the call to drupal_set_region()?
What about hook_node_api? I
What about hook_node_api? I tried the following
It seemed to work fine. Will this only be called on a "fresh" page view? In other words, will the region content be cached for each page once it has been determined? I think that would perform better since it will take some db calls to determine what content should be shown and there are a minimum of four regions per page (sometimes quite a few more.)
node_api hook only called when viewing nodes
The possible draw back to using the node_api hook it is only called when viewing a node. So for pages that do not show any node content, your code would never run. An additional problem would be pages that show a list of nodes, in that case the hook is called once for each node.
As for the init hook, it plus footer seems to be the only hooks always called per page. Given what you want to do it the init hook seems an appropriate place to do it.
A few issues with that solution
That's ok I think. The page consists of stories, blogs and forums. There are some static pages but those will all be ad-free so I don't need the ad regions for those anyways. Biggest problem seems to be on forum landing page and a few other spots where I would like to see the ads.
Can you give an example of such a page? Is there a way to detect a request for a node list vs. node render? If not that would seem to be an unfortunate oversight in the API.
But there will be no cacheing of this code right? I'm concerned about performance. Is there no other way? Maybe I could implement my own cache of these results. Is there a way to access Drupal's cache for this?
Thanks for the great feedback.