On my blog I have a series of posts on a common subject that I'd like to link together with a common navigation block, so that readers can easily jump forwards or backwards through the series.
I've used NodeQueue to collect all the blog entries together in sequence. Putting the associated block in my sidebar gives me the navigation that I want BUT the block appears on every page of my site.
What I want to do is limit the visibility of the block so that it only appears on pages that are included in the queue. How can I do this?
I know that NodeQueue creates it's blocks using Views, so I guess the answer might be more to do with using Views than NodeQueue. If there's a module that does what I need, that'd be great. If the answer requires PHP (say, for configuring block visibility) then I'll need some handholding.
The blog is running on Drupal 6.19 and I do have a test instance I can try things out on before touching the live site.
Block visibility has nothing to do with it's content. If you wanted to display a static block for the nodes in the queue, it would be equally hard.
I see to possible solutions.
- Manually typing in the nodes in the block visibility setting and select on show on listed pages
- create a PHP snippet to test if the user is seeing a node, the query the db to see if it's in the queue. (I don't like this approach)
The first gives more management, but the last can easily break anyways and I don't like storing code in the database.
Ok this is a slightly lengthly though I think elegant solution. I hope it doesn't scare you off -- Its really not complex but unlike code its difficult to explain in text. It was fun figuring this out. This answer works in Views version 2 or higher. Essentially the solution combines two modules
- Views attach ( http://drupal.org/project/views_attach )
- Nodequeue (Most specifically Taxonomy Queue)
Please read about Views attach before proceeding further. Views attach is best explained by this video http://mustardseedmedia.com/podcast/episode37
A Taxonomy Queue is nothing but a Nodequeue that is automatically created for each taxonomy term in a vocabulary. Let say we have a taxonomy nodequeue called My Lists
. Lets say you have a Vocabulary called Series
and it has 3 terms: Apache Solr Tutorial Series
, CSS Tips and Techniques Series
, Drupal Views Tips Series
. And if My Lists
uses the Series
as its taxonomy source then 3 sub-queues will be created -- one for each term.
On your blog you will have multiple series of articles (you call it articles with a "common subject"). Each series will be independent from another series. Each series will contain lists of 2 or more blogs. It is important to note that in my proposed solution it will only be possible for a blog to be part of 1 series -- I hope that is ok. We are using a Nodequeue based solution because of your requirement that order of listing of the blogs in the series is important and has to be preserved.
First you will need to create a vocabulary (lets say we call it Series
). Every time you create a new series of blogs you will create a new taxonomy term e.g. Apache Solr Tutorials Series
, CSS Tips and Techniques Series
etc. Make sure that the Series
vocabulary is applicable to your blog
content type.
You now need to create taxonomy queue. Simply enable Smartqueue Taxonomy
in the modules list. It comes with standard Nodequeue module. Click on Content Management > Nodequeue > taxonomy queue. Name the queue My Lists
. Make sure you select Series
as the Vocabulary. You can leave the length of the queue to be 0
(unlimited) because each series of blogs can have any number of blogs in it. Now:
Link "add to queue" text:
put Add to %subqueue
Link "remove from" queue text:
put Remove from %subqueue
This is sort a convenience thing. It will give you links at the bottom of each blog
node to add or remove from the appropriate taxonomy queue. So if a blog article has got the taxonomy term CSS Tips and Techniques
it will get a link at the bottom of the full node page (or even teaser view) so it can be added it to the CSS Tips and Techniques
subqueue in the My Lists
nodequeue.
This completes the setup for taxonomy queues.
Now we get to Views attach. Please enable the views attach module before proceeding. Essentially Views attach
attaches a view at the end of the node. In our case our view will be a listing of other articles in the series (only if the blog is part of a series).
We will essentially need to "pass" the taxonomy term of the node to the view. This taxonomy term will select the appropriate subqueue in the My Lists
nodequeue. All items in that subqueue will be shown in the exact order as specified by you (via the standard Nodequeue interface).
Steps to make the view.
- Lets call the view
display_other_blogs_in_series
.
- Add a display of type
Node Content
(available after enabling Views attach). This is a display just like block and page displays but with special ability of attaching itself to the node.
Make the following settings in the Node Content Display
Node content settings
Node types: blog
Build modes: Teaser, Full node
Arguments: token
Show title: No
You should select Use tokens from the node the view is attached to
under Arguments. Let the token be [term-id]
This is the "ID of top taxonomy term". This is very important!! Essentially you are going to be passing the taxonomy term of the blog node from the Series
vocabulary (e.g. CSS Tips and Techniques) as an argument to the view. For this to happen the Series
vocabulary must have the lowest weight. (See http://groups.drupal.org/node/11788#comment-38332). If it has the lowest weight, the taxonomy vocabulary will be the first vocabulary in the taxonomy section of your node edit form.
Now we need to tell our View to take items only from the My Lists
queue. Add a relationship Nodequeue: Queue
. Make sure [x] Require this relationship
is selected. Make sure [x] Limit to one or more queues
is selected with My list
as the queue.
Add an argument Nodequeue: Subqueue Reference
. Make sure the Relationship is queue
i.e. the relationship we defined above. This argument is going to be the taxonomy term from the Series
vocabulary. This argument will cause the correct subqueue to be selected.
Add the fields you are interested in e.g. Node: Title
. Make sure the Node: Title
is made into a hyperlink by ticking Link this field to its Node
Add Nodequeue: Position
as the sort criteria. Make sure the sort order is ascending and make sure the relationship queue
is used.
In filters, make sure you add Node: Type = blog
as your filter.
So what this view is going to do is:
- Take the taxonomy term from the
Series
vocabulary in the Node that is currently being viewed
- Pass that as argument to the view
display_other_blogs_in_series
- The view will use that argument to select the appropriate subqueue in the
My Lists
queue
- The items in the subqueue will be listed one by one exactly in the order you have specified
- This will appear correctly in every blog that is part of a particular series
Thats it!
Postscript:
If you're using Views 3 (currently at alpha3 at the time of writing) and you want a block (right now the related articles come at the end of node body) you can do it in the following fashion:
- Forget about views attach... its not required
- Add a block view. It should contain the same arguments, relationships, fields and filters as the instructions above for the
Node Content
display.
- You need to modify the settings for the argument
Nodequeue: Subqueue Reference
just slightly: Under Action to take if argument is not present:
choose [x] Provide Default Argument
. Choose [x] Taxonomy Term ID from URL
. Now make sure [] Load default argument from term page
is unselected and [x] Load default argument from node page, thats good for related taxonomy blocks.
Also [x]Limit terms by vocabulary
and choose the Series
vocabulary.
- Make sure you name the block and put it in the appropriate region.
I haven't actually played with NodeQueue, but based on your description, this sounds like something you should be able to do using views. A couple of thoughts.
If you are using a distinct content type only for blog entries, then you should be able to add that content type as a filter on the view. That would probably be simplest.
If you cannot do that, then I would look to see whether you can add a filter for NodeQueue as that should also work.
If neither of the above work, I would look to see if you can add a relationship to NodeQueue. Doing that will likely make it so you can add a filter for NodeQueue.
Finally, if you do not get a satisfactory answer here, I would suggest that you post your question on Drupal.org as that is where a lot of drupal experts answer questions.