There are modules like relation that can provide a similar functionality out of the box. However, we are aiming for a more flexible workflow that we could modify easily with a few clicks and that provides much more granular permissions.
First of all, we need to install Drupal 7 with the modules we need:
- Views (using version 3.7)
- Flag (version 3.4)
- CTools (required by Views, version 1.4)
- Entity API (required by Flag, version 1.3)
My personal preference is to do it with drush but you can do it however you like.
drush qd --db-url=mysql://mysqluser:password@localhost/test --profile=minimal testsite entity ctools flag views
This command will launch a standalone server (no XAMPP, MAMP, or WAMP needed) and will install a Drupal using the minimal profile and installing the modules we specify.
We will also need to install Views UI to be able to edit views.
drush -y en views_ui
The next step is to create a new flag that is going to represent one user following the other (remember this is a one way relathionship).
Inside Admin -> Structure -> Flags -> Add flag.
- Flag type: Users (Users flag other users)
- Flag name: Follow This is not a global flag because each user will have his own 'status' no matter the relathionship with other user.
- Flag link text: Follow [user:name]. The use of tokens allows us to customize this text
- Flagged message: Following [user:name]
- Unflag link text: Stop following [user:name] . Because "Unfollow" is a sad action
- Unflagged message: stopped following [user:name] The permissions by default establish that only authenticated users may follow between them.
- Users may not flag themselves.
Once we save our new flag, we'll be able to see the "Follow" action link in other users profiles (don't forget to add permissions to view profiles).
Now is time to deal with the views to create listings of users following a given one. Let's go to Admin -> Structure -> Views
Note that the flag project includes an example flag called "bookmark" as submodule. It comes with a views example that is interesting to review. As we need to list users, we'll start a new view from scratch.
We're creating a new view called "Following" that lists unsorted users. In the same step we're also adding a page and setting the path to user/%/following to display this list in separate tab in the user profile.
The '%' works as a substitution for the user ID (a number) that we are viewing.
Let's leave the display format as table for now and click on "Continue and edit" to be presented with the rest of options.
Right now our live preview (bottom of the view edit page) is listing the user names of every user in the site. Our goal is to list only those that are followed by the user id we provide with contextual filters. When we have the view in place that user id is going to be filled automatically with the URL.
Under the "Advanced" section we can see another subsection for "Relationships". Think about relationships as a way to bring new information to the view. At this point, we only have information about the user, but we want to know about what this user has flagged so we add a new relationship for User flag.
- Include only flagged content: yes, if you are not followed by this user we don't want you in this view
- Use our "Follow" flag
- By: Any user, because Current user means the user who is logged in. Who is "Any user" we'll provide it later with contextual filters
Now our live preview will show users who are being followed, no matter who is doing it. We need to add a second relationship in order to bring information about the user who followed those that we want listed in our view.
They all have one thing in common, they have been flagged by the same account. By adding the first relationship we can add now new relationships, so now we'll add "Flags: user" relationship.
Additionally, we are going to check the "Require this relationship" checkbox because we are only interested in the items that have this kind of data filled (otherwise might cause duplicates).
It is time to add contextual filters to feed our view with the user id that comes from the '%' in the path /user/%/following.
The new contextual filter is an uid (User id). We are presented with some options, being the first one the origin relationship for this information. We select the "Flag user" relationship that we defined before.
The filter value is going to be always in the URL but just in case someone forges the URL we are going to give them a "Page not found".
Same for validation, instead of giving an empty view, we will validate the user id. Also allow both numeric UIDs and string usernames and show a "Page not found" in case it doesn't validate.
That's the whole configuration for the contextual filter, so we can save it.
Now the view is fully working as we wanted. We can use the live preview for testing usernames or user ids and verify that we get a list of followed people.
Our next step is to show this listing as a tab in the user profile page. Views provides with an option to modify the menu settings and set the menu as a tab with a name.
Now we can add some interesting fields for the list such as a follow link so other users watching the profile can follow the ones on the list. It's as simple as adding the flag link in the list of fields.
For the second listing we can create a new page display. It's really important to override every option that is different for the master display (The display we've just created) so we don't modify it with our new display. We're changing:
Clear and override fields, relationships and contextual filters (you can see the title in italics when a field is overriden).
In this case we want users that have flagged this one. Our first relationship is going to be "User's Flaggings" because we only want users who have flagged certain content.
Right now our live preview shows users that used the Follow flag at least once.
Now we can add the contextual filter that is going to narrow the query to only those users who had flagged the user coming from the URL. We can achieve this by adding the "Flags: Content ID" contextual filter. Select the same behaviour as the previous display for managing the cases when the value is not in the URL and validation. Note that the relationship we just defined is preselected.
With this contextual link, we're good to go! Our view is finished and we can test on the preview area.
Now we can add any field we'd like to the list of fields displayed, including the "Follow" link we described above for the previous display.
When saving the view we'll see now the two tabs in the user profile.
We're exploring this feature in further posts. Flag would allows us to react on events, such "A user started to follow you" and trigger notifications using the Rules module. We'll cover this and more examples in future posts.
I'm always learning new stuff about views so please use the comments below if you've got suggestions on how to improve this example!