Can Sling handle "virtual resources"?
Background: I've been tasked with implementing search engine sitemaps for a website running on Sling. The site has multiple country-specific sites, and every country-specific sites can have multiple localizations - for instance, http://ca.example.com/fr would be the French-localized version of the Canadian site, and would map to /content/ca/fr . I can't change this content structure, and unfortunately both the country and localization nodes have the same sling:resourceType
. Also, the administrative types want a sitemap.xml for each country/localization pair, not one per country site.
Generating the sitemaps is an easy task, my problem is needing a 'sitemap' node for each country/localization pair - because of the way countries and localizations nodes added (and them having the same resource type), I can't currently think of a good automated way to add the sitemap node.
It would be nice if I could somehow define a "virtual resource" that maps requests for /{country}/{localization}/sitemap.xml to a handling script; I've been browsing around and have bumped into ResourceProvider
and OptingServlet
, but they seem to be pretty focused on开发者_高级运维 absolute paths - or adding selectors to an existing resource, which doesn't seem like an option to me.
Any ideas if there's some more or less clean way to handle this? Adding new countries/localizations doesn't happen every day, but having to add the 'sitemap' node manually still isn't an optimal solution.
I've been considering whether it's perhaps a better idea to have a running service that updates the sitemaps X times per day, and generate the sitemap.xml nodes as simple file resources in the JCR, instead of involving the Sling resolver... but before going that route, I'd like some feedback :)
EDIT:
Turns out requirements changed, and they now want the sitemaps to be configurable per localization - makes my job easier, and I won't have to work against Sling :)
Sling is a resource based framework, so you have to have a resource (node) in JCR which your requests targets.
You have two options: 1) Create a Sitemap template which includes the logic to display the Sitemap, or has your Sitemap component included on it. The Sitemap logic can be extracted into a class or service as you see fit. The site map for each site would live at: - /content/us/en/sitemap.xml - /content/ca/fr/sitemap.xml
2) Create a single sitemap resource (node) that you reference using 2 sling selectors; the country and language codes - this method allows for caching, however you may run into cache clearing issues as its a single resource.
- /content/sitemap.us.en.xml
- /content/sitemap.ca.fr.xml
You can look at: PathInfo for extracting the Sling Selector information for determining which Sitemap to render.
http://dev.day.com/docs/en/cq/current/javadoc/com/day/cq/commons/PathInfo.html
If i were doing this I would require the manual addition of the Sitemap to each site, and keep the resource under /content//
You could even look into creating a Blueprint site using MSM (if youre using the platform I think you are) and roll out new sites using that which lets you create a site template.
If you want a GET to /{country}/{localization}/sitemap.xml to be processed by custom code, simply create a node at that location and set its sling:resourceType as needed to call a custom servlet or script.
To create those sitemap.xml nodes automatically, you could use a JCR observer to be notified when new /{country}/{localization} trees are created, and create the sitemap.xml node then.
For configurable sitemaps you can add properties to the sitemap.xml node, and have your custom servlet or script use their values to shape its output.
You could do that without having a sitemap.xml node in the repository, using a servlet filter or a custom ResourceProvider, but having those nodes makes things much easier to implement and understand.
Note I am working on a sling resource merger, which is a custom resource provider, with ability to merge multiple resources based on your search paths.
For instance, if your search paths are /apps /libs
Hitting /virtual/my/resource/is/here will check /apps/my/resource/is/here /libs/my/resource/is/here
There are some options like:
- add/override property
- delete a property of the resource under /libs
- reorder nodes if available
I intend to submit this patch as soon as possible.
Code is currently located at https://github.com/gknob/sling-resourcemerger and tracked by https://issues.apache.org/jira/browse/SLING-2986
精彩评论