I can see why Spaces currently enforces a single space per item. E.g., spaces_taxonomy is available only for vocabularies that don't support multiple terms per node; spaces_og limits content to a single group. Allowing individual items to be accessible in various spaces would introduce significant issues like duplicate content, path negotiation between different spaces, and persistence in a given space.
But I thought I'd spend some time looking at what it would take to address these issues.
I recently came across Node symlinks, which apparently "allows you to display the same content to users at multiple locations in the Drupal menu system". Then there's the Sites module, which aims to allow users "to share some content across sites and separate other content" (and has a lot of overlap with spaces_taxonomy--see this issue: #825530: Consider building off of or merging into spaces taxonomy). And of course Domain access, which "allows you to share users, content, and configurations across a group of sites".
But Spaces, the leading solution in this, um, space, already solves most of the problems of dividing a site between multiple sections and doesn't look to require too much to also support multiple spaces per item.
There's a relevant feature request on spaces_og, #671032: Standard group post in multiple group with Spaces, but spaces_taxonomy seems both the most straightforward and the most general-use place to begin. So here is a patch aiming to (a) put in place some general solutions to the problems presented by allowing multiple spaces per item and (b) implement those approaches in spaces_taxonomy.
This is a proof of concept and I'll need to adapt it to the current branch code. I tried to work with the DRUPAL-6--3 branch but it looks like that's in flux and currently not working so I patched instead the latest stable release.
If this patch is completed and accepted, future patches on e.g. spaces_og could build off of it.
Here's a summary of the general and specific approaches in the patch.
Canonical URLs
General principle: In the case that a single item (e.g., node) is assigned to more than one space, there should be a single space identified as the canonical location for that item.
Spaces implementation: The item is accessible at other spaces, but those other ones point to the canonical one (via a <link name="canonical" /> tag).
Spaces taxonomy implementation: If a node is being viewed at a taxonomy space other than its canonical one, set a canonical URL. Requires this proposed patch on PURL: #828384: Enable designation of a canonical path.
Persistence
General principle: The current space should persist if possible.
Spaces implementation: When a page loads in a space and the requested item has more than one space, the current space is selected if possible.
Spaces taxonomy implementation: If a node or taxonomy page requested has the current space's term, that space is selected.
Multiple handling
General principle: There should be (at least) two possible responses in the case that a user visits an item from outside any of its spaces: (a) the space is selected randomly from among the candidates, (b) a canonical space is selected.
Spaces taxonomy implementation: If the selected spaces_taxonomy vocabulary is multiple-enabled, the admin is presented with a second form element to select the desired multiple handling: random or canonical. If random is selected, terms are shuffled before being iterated, with the result that a different one may be selected with each visit.
Note: this patch requires the patch at #828384: Enable designation of a canonical path.
| Comment | File | Size | Author |
|---|---|---|---|
| #29 | spaces-multiple-828416-29.patch | 1018 bytes | guilopes |
| #28 | spaces-multiple-828416-28.patch | 683 bytes | guilopes |
| #25 | spaces-multiple-828416-25.patch | 12.11 KB | lukio |
| #17 | spaces-multiple-828416-17.patch | 21.4 KB | nedjo |
| #15 | 828416-15-spaces-multiple.patch | 22.55 KB | nedjo |
Comments
Comment #1
kyle_mathews commentedsubscribing. Looks exciting!
Comment #2
nedjoSuggesions for testing (from a clean D6 install):
* Apply this patch and the one at #828384: Enable designation of a canonical path.
* Enable Spaces taxonomy.
* Create a new vocabulary, e.g, "Sites", checking the "Multiple" checkbox.
* At admin/build/spaces/taxonomy, configure Spaces taxonomy to use the Sites vocabulary. Leave the "Method to select between multiple term spaces" setting at its default, random.
* Create multiple terms for the Sites vocabulary, giving each a Spaces path. E.g., terms "Africa" (path: africa), "South America" (path: south-america), and "Australia" (path: australia).
* Create three nodes, promoting them to the home page. Assign node 1 to the Australia site, node 2 to Africa, and node 3 to both "Africa" and "South America".
* Visit the home page. Click on the link for node 1. Expected result: you arrive at /australia/node/1.
* Return to the home page, which should be /australia. Click on the link for node 2. Expected result: You are forwarded to /africa/node/2.
* Return to home page (/africa). Click on link for node 3. Expected result: you arrive at /africa/node/3, because you are coming from the africa space and the node you're visiting has africa as one of its spaces.
* Manually enter /node/3 in your browser, emulating arriving from outside either of the node's spaces. Repeat several times. Expected result: sometimes you arrive at /africa/node/3, other times at /south-america/node/3 (because the default multiple handling is random).
* Visit /africa/node/3. View the page source. Ensure there is no
<link name="canonical" />tag.* Visit /latin-america/node/3. View the page source. Ensure there is a canonical link pointing to the africa space, e.g.,
<link name="canonical" href="/africa/node/3" />tag.* At admin/build/spaces/taxonomy, configure "Method to select between multiple term spaces" to "first (canonical)".
* Visit /node/3 several times. Expected result: you are forwarded every time to /africa/node/3.
Comment #3
ttaylor797 commentedWell done - Nedjo! I am looking forward to testing this out.
Comment #4
jmiccolis commented@nedjo, a couple conceptual questions;
* Can you give me an example of a situation when SPACES_MULTIPLE_HANDLING_RANDOM would be ok? I'm just not sure we should let that be an option.
* What's you idea for how a canonical term would be designated in taxonomy spaces? Just grabbing the first one isn't generally going to work.
Cheers,
Jeff
Comment #5
nedjoHi Jeff,
Thanks for following up. Good questions.
On some sites it's strategically important that one subsite or section (space) not be given priority over another. An example is a http://comminit.com, a site I'm helping upgrade from D5. A key requirement is that users coming from offsite should be distributed equally among the various subsites.
On thinking this through a bit more, I realize there are probably two different use cases that need distinct handling for both canonical URL and multiples handling, and that the patch would need updating to meet both.
In this use case, every piece of content included in spaces_taxonomy has a primary home: one of the terms. This term should be designated as the canonical URL. Traffic from offsite is expected to resolve to this canonical space. The result should be a lot like the handling of url aliases in Drupal core. A node can have multiple aliases and is reachable at any of them, but a generic link should always lead to the primary alias. Sample canonical url: /africa/node/3.
In this use case, content has no primary location but is equally at home in any of its spaces. Traffic from offsite should have an equal chance of reaching any one of the relevant spaces. If use case 1 is like url aliases, here a closer analogy might be node translation. For viewing purposes, each member of a translation set is equally relevant. For the canonical url, we can't use any particular space so we'd use the original node url. Sample canonical url: /node/3.
Yes, site or content administrators will want some control over designating the canonical URL. By default terms are loaded by term weight and then alphabetically, so a site admin would have some rough control over designating a canonical URL, by changing term order in the spaces_taxonomy vocabulary. But is that enough? Nodewords has support for manually designating a node's cononical URL, but that won't help here because we have multiple displays of the same node. I suppose we could introduce optional support for http://drupal.org/project/primary_term, respecting a primary term if one is designated. Does that sound useful?
Comment #6
owen barton commentedI was thinking along the same lines for spaces OG - I think the principle is sound and captures a useful balance of functionality and ease of use.
Comment #7
cwaring commentedSubscribing
Comment #8
nedjoRevised patch implementing the approaches outlined in #5.
Changes and fixes since previous patch include:
* Canonical space for primary (canonical) handling (use case 1 in #5, above) is the first term, e.g., africa/node/3. Canonical space for random handling (use case 2) is node/3 (no PURL modifier).
* Don't disable term select on node edit form if spaces vocabulary is multiple.
* Optional support for primary_term module, which can be used to set canonical space per node. Form altering tweaked to preselect the current space if applicable, as is done with the term select.
* Ensure canonical URLs set only when there are multiple spaces terms for the current node and when the current space is not the canonical space.
Complex to test manually. I'm working on some simpletests.
Comment #9
nedjoWith tests. This is now ready for review.
Comment #10
nedjoHere's a drush make file to help with testing. It'll set up a test site and apply the needed patches.
From there, enable simpletest and run the spaces taxonomy tests. There are exceptions generated by the primary_term module but otherwise it's doing well.
Comment #11
nedjoThis patch currently hardcodes two potential multiple handlers: primary and random. Likely it would be better to allow modules to register their own handlers, so they could add new options. E.g., if spaces (e.g., taxonomy terms or organic groups) were cities, a given module might enable the space to default to the city closest to the visitor by IP address. This is comparable to content language negotiation in D7.
Would require some refactoring. Any tips or feedback before I dig into this would be great.
Comment #12
butler360 commentedSubscribing.
Comment #13
that0n3guy commentedsub...
Comment #14
Grayside commentedSo Random is intended as an enforced round-robin of space destinations? More function-oriented UI on that is probably a good thing.
I like this approach.
Something that occurs to me (more from a multi-group perspective, but it may matter here) is an option to restrict edit rights to the canonical location. Definitely a follow-up issue
Comment #15
nedjoFix a couple of issues, one introduced by a recent change in Spaces:
* use arg() tests rather than menu_get_object() as latter caused a loop.
* shuffle() resets keys, test original $node->taxonomy array for tid values.
Comment #16
johngriffin commentedFirstly, fantastic patch, I've just tested it with the purl patch and primary term and it does everything it claims to. So, thank you!
Secondly, I have a use case which is slightly outside this functionality but very similar. I would like to always redirect users to the canonical URL, so that even if they try to access it with a different space path in the URL, it will redirect them to the canonical URL and set the space accordingly. I have achieved this for the moment by commenting out the code that keeps you within the current space if a node has that space's term - for anyone that's interested it's in space_taxonomy.inc at line 88 and should look something like:
However, I'm wondering whether there should be an option for this behaviour, perhaps on the admin/build/spaces/taxonomy page. It only applies to the primary (canonical) method of selecting between spaces, so either an additional radio button or a checkbox [always use primary (canonical)] that only applies when the "primary (canonical)" radio button is selected.
Comment #17
nedjoRefreshing the patch but only for D6 so far. Needs to be ported to D7.
Adding a missed call to drupal_clone() in spaces_taxonomy.inc, which is needed to avoid altering the original node.
Comment #18
patcon commentedIn case anyone's interested, John did up an awesome post on using this technique:
http://atchai.com/blog/spaces-module-drupal-multi-site-alternative
Comment #19
sammys commented@nedjo: I agree this is the right way to go. I've ported your changes to D7 also to suit the site I'm building. I am guessing that you're putting the multiple term handling into place first then bubbling it up to have multiple spaces set active at one time. This would be quite handy because one could add content in a term space and have it combined with content of the same type created in a group space all displayed in one place. I.e. allowing a cross-section of spaces.
I've built some prototype code as proof of concept and it involved making a
spaces_get_space_multiple()andspaces_set_space_multiple()then making the single space versions talk to those. I then added space ordering where the highest active one in the list is the "canonical" for each page. This involved a change to_spaces_registry()for sorting by a configured weight (UI config was added to the spaces admin page).While the prototype isn't finished yet I figured I should post this and get a feeling from people if this is the right direction before continuing. There are only a few little pieces left to iron out. One is restricting the override to the canonical space. Another is improving the canonical space selection. I imagine this is going to be quite a humdinger.
Looking forward to hearing whether this is the right direction.
Comment #20
mrfelton commented@sammys - would you be able to post a patch of what you have so far so that we can try out your code on the D7 version?
Comment #21
Anonymous (not verified) commentedSeconding the request for a D7 version... Thanks!
Comment #22
Anonymous (not verified) commentedThis functionality seems like it would be a common requirement. I'd really like to see it get into the standard Spaces distribution.
Currently, apart from this patch, the only approaches I know of are Domain Access and the Sites module.
Domain Access is fundamentally The Wrong Thing (it overloads access control to do something it wasn't intended for). Among other things, that means it is mainly incompatible with actual access control.
The Sites module appears to be abandoned. Someone has stepped up offering to be comaintainer: #1572136: Offering to become (co)maintainer of the Sites module - abandoned projects. So this may be a workable alternative in future. Still, Spaces has functionality that Sites lacks.
I'm wondering what it would take to get this patch into the Drupal 7 version. I can potentially do testing, documentation, maybe some coding; but I'd want to know that eventually it's going to be accepted into the standard distribution.
Thanks!
Comment #23
lukio commentedsammys, do u have the patch to drupal 7 already? Because I need it to build a site that Im working.
Thanks!
Comment #24
sammys commentedHi @lukio,
Unfortunately the management pulled the plug on development and we took a different route for that build. As I mentioned in my previous post, the code I had built was a proof of concept and was neither development, build nor production ready. It would not be useful to anyone wishing to use the functionality within a couple days.
Comment #25
lukio commentedFinnally, after a great work I could port the patch from drupal-6 to drupal-7. The patch applies against 7.x-3.0-alpha1.
I also add the views taxonomy filter patch.
http://drupal.org/files/spaces-current_taxonomy-1683722-1.patch
Please test it!
Comment #25.0
lukio commentedMaking issue link work
Comment #26
brunorios1 commented#25 doesn't apply to 7.x-3.x-dev.
Comment #27
brunorios1 commentedComment #28
guilopes commentedAfter apply the patch #25 I have erros in my homepage
Notice: Undefined property: stdClass::$field_industry in _spaces_taxonomy_get_terms_object() (line 274 of
This patch solved my problem.
Comment #29
guilopes commentedI updated the patch
Comment #30
ciss commentedComment #31
ciss commentedOn second thought guilopes uploaded a separate patch. #26 is probably still the latest status. Setting back to Needs Work.
Comment #32
ciss commented(Forgot the status update. Sorry for the noise.)