How to create tabs within groups with friendly URLs
I've had several folks ask about how I created group home pages that included tabbed content. I had several threads on the Drupal forums that discussed how to accomplish this but I had always intended to follow up with an actual tutorial.
Modules used in this tutorial
The following are the main modules I'll be discussing, however several of these modules depend on other contrib modules like token.
- Organic Groups (og)
- Path Auto
- Sub-path URL Aliasing
- Requires: URL Alter
- Rules (optional -- see step 4 caveat)
Step 1 - Planning
Planning is important so let's make note of what we want and what we're expecting to see. To begin with let's assume that we're going to have two types of groups:
Social - This is a generic group for members to create and socialize with the community.
Team - This is a generic group for members to work together as a team.
Now it's time to decide what type of content can be posted to a group. For this tutorial we're going to go with two content types (News, Photos). Assumption is that the reader has basic knowledge of creating photos/images as nodes. We are going to want a tab for each of these content types.
So what we're going to end up with is three tabs (View, News, Photos).
Context & Friendly URLs
When viewing a group it's possible to have a different layout, theme, blocks, etc. When viewing content within a group we want to maintain that feeling for the user. We also want our URLs to be friendly and make sense. Here are the target URLs we're shooting for:
Social: mysite.com/groups/social/<group name>
Team: mysite.com/groups/team/<team name>
News List: <group url>/news
News Item: <group url>/news/<news title>
Photo Gallery: <group url>/photos
Photo Item: <group url>/photos/<photo title>
Oh... and we want all this to happen without admin intervention.
Step 2 - Basic Installation
Install Drupal and the modules listed above. I'm assuming some basic knowledge of installing and configuring drupal and modules. The default configurations for the contrib modules should suffice for now.
Step 3 - Creating Content Types
A default Drupal installation comes with the Story and Page content types. We will create a few more and at least one content type to act as the group.
Group Content Types
Let's first create our content type that will act as our group. Head on over to Administer > Content management / Content types > add content type (/admin/content/types/add). Provide the name and type of the new content type. Make sure to scroll down to the Organic Groups Usage section and select Group Node.
Repeat that step for both the social and team group type.
Posting Content Types
We'll follow the same steps as above to create our News and Photo except that instead we'll select the Organic Group Usage to be Standard Group Post.
Step 4 - Configuring Automated URL Alias Settings
Head on over to Administer > Site building > URL aliases > Automated URL Settings (/admin/build/path/pathauto) and make sure you're viewing the Automated Alias Settings tab. Then expand the Node Path Settings section and you'll find where you can configure automated path aliases for each content type.
For each group type enter the following pattern: groups/[type]/[title-raw]
For each of the posting content types enter the following pattern: [ogalias]/[type]/[title-raw]
You can vary those patterns but the key piece is the [ogalias] token. The way that will work is if content is posted to a group then it will create an alias that beings with the groups alias. If a piece of content is not posted to a group then that token is left blank.
Caveat (a big one)
There is one issue with this particular method. If content is posted to multiple groups then we run into an issue with the [ogalias] token in the path. Only one alias is created. If we were to use the Rules module to create multiple aliases I believe the system will still pull the first alias that links to the node. If the particular group post is marked as publicly viewable then that isn't too big of an issue even though we lose group context. What will be a bigger issue is if the content is marked private. In this case we get an access permission error if the user does not belong to the group for which the alias is pulled.
If we remove the [ogalias] from the pattern then this is a non-issue.
This particular issue luckily wasn't a deal breaker for the particular site I was creating so I continued on with the [ogalias] token. What I ended up with was restricting most content to a single group. And for the few cases where select users can post to multiple groups, I used the rules module to enforce that the post was publicly viewable.
There are probably other methods around this caveat, however this tutorial will walk through my implementation. I would love to hear of other solutions.
So on that note... let's continue.
Step 5 - Enabling the Group Details Block
The Group Details Block will provide a list of content that can be posted to a group. This is the primary starting point for most of my users to create content.
The OG module provides the Group Details Block, however it is not assigned to any region by default. To enable this block navigate to Administrator > Site Building > Blocks (/admin/build/block). Locate the block and assign it to a region.
Step 6 - Moving the Create Content Menu (optional)
The reason this step is optional is due to the Rules module I use later on in this tutorial.
By default the Create Content link appears in the Navigation block. Most of my users will not need to post content outside of their groups. So what I did was create a new menu (/admin/build/menu/add) and then move the Create Content tree to the new menu.
To move the Create Content simply open up the Navigation menu and click edit next to the Create Content item. Scroll down to the Parent Item drop-down and choose your new menu.
Now we want to provide this menu as a block to users of a certain profile. Head on back to your block listing page and you'll find a block for the new menu you created. Simply assign it to a region and then click on configure. Scroll on down to the Role Specific Visibility Settings and select the roles that can post content outside of groups.
Caveat: This doesn't actually stop a knowledgeable user from manually typing in the URL to the node add pages, however my users are not familiar with Drupal and I've also used the Rules module as noted up top to help catch issues.
Step 7 - Configuring Organic Groups (optional)
The reason this step is optional is due to the Rules module I use later on in this tutorial.
Most of the OG configuration can be setup however you like, however there is a particular setting I use that restricts users from posting to multiple groups when using the add content links in the Group Details block. To find this setting navigate to Administer > Organic Groups > Organic Groups Configuration (/admin/og/og) and scroll down to the Group Details section. Here you'll find the Audience Checkboxes option. I've unchecked this option so that a user will not have the option to post to multiple groups when using the links in the Group Details block.
Step 8 - Configuring the Rules Module
The Rules module is a pretty powerful module, however it can be confusing at first. Without getting too deep into the different aspects of triggered rules, rule sets, etc. I'll just walk through the rule I created.
What we're essentially doing here is creating several triggers, one for each posting content type, that will call a rule-set.
8.1) Enable Rules Modules
The first thing we'll need to do is make sure the proper sub-modules for rules are enabled as shown by this screenshot.
8.2) Identify Forms to Trigger Events
Navigate to Administer > Rules > Form events (/admin/rules/forms) then select the checkbox Enable event activation message on forms and hit save. This will give us the option to enable triggers on forms but we'll have to choose which forms to handle this on.
8.3) Activate Events on Content Forms
Navigate to each form that we want to trigger off of. In our case we want to trigger off of the News and Photos create content forms.
There will be a message similar to the one below with a link to activate events for the form. There may be several messages if multiple forms exist. Make sure to click only on the link for the content type form we're interested in. Confirm the activation by clicking the activate button.
8.4) Create Triggers for each Content Type Form
Navigate to Administer > Rules > Triggered Rules (/admin/rules/trigger) and select to Add a new rule. Complete the form similar to the image below. The important piece is the Event field which is outlined in red. Save the trigger.
After saving your changes you'll be given the option to add conditions and actions. We will not be doing that part just yet. Instead, repeat this step for each posting content type (News, Photos).
8.5) Create Rule Set
Navigate to Administer > Rules > Rule Sets > Add a New Rule Set (/admin/rules/rule_sets/add) and complete the form similar to the image below. The key piece is outlined in red.
8.6) Add Rule to Rule Set
Open up the rule set we just created and select to Add a new rule. Give it a label and category but do not change the rule set drop-down option. Save your changes.
8.7) Add Condition to Check for Multiple Groups
Select to add a condition for the rule we just created. The condition we're going to add is Execute custom PHP code. Select next and complete the form similar to the image below. The key pieces are outlined in red. Save the condition.
PHP Code (copy/paste): return (count($form[og_nodeapi]['#post'][og_groups]) > 1);
8.8) Add Action to Set Form Error
Select to add an action for this same rule. The action we're going to add is Set a form error. Select next and complete the form similar to the image below. The key pieces are outlined in red. Save the action.
Form element ID (copy/paste): $form[og_nodeapi]['#post'][og_groups]
8.9) Add Rule Set to Triggers
Now that we've created the rule set, we need to return to all of the triggers we created earlier and add the rule set as an action. The resulting trigger rule should like the image below.
Step 9 - Adding Views Tabs
I'm going to assume some basic knowledge of views for this step, however I will highlight the key components of the view that will bring all of this together to give you tabs on your group nodes.
Navigate to Administer > Site Building > Views (/admin/build/views) and add a new node view. Within that view create a page display. Setup that page display similar to the image below. The key aspects are outlined in red.
Page Settings -> Path
What is important to understand about the path setting is that we begin with node/%. What follows (e.g. news) can vary based on the content type, however node/% ties us into the group node.
Page Settings -> Menu
Setup the menu similar to the image below. The key component is outlined in red.
Setup the argument similar to the image below. The key components are outlined in red.
Step 10 - Drink a Beer!!
Congrats! You made it to the end of this tutorial. Phew... now go get yourself a cold one.
- (step 4) - [ogalias] token is powerful but also limiting if content can be posted to multiple groups.
- (step 8) - A rule can trigger off of a form and stop it prior to saving if multiple groups are selected and the post is not marked as public.
- (step 9) - The correct views settings can make just about any page view act as a tab.
I hope you enjoyed my first tutorial. I need another beer simply for writing this tutorial. :-)