Hey guys, is it possible to have multiple folders per blog piece? Or, having a blog with multiple keywords attached to it?
The 'virtual folders' in Couch have been purposefully modeled after the physical folders we have on file systems - the idea is to have their names appear in the page's URL and thus give an appearance of the page being contained within the folder (or an hierarchy of folders) just like physical files.
Because of this Couch does not allow a page being placed within multiple folders (exactly like a physical file cannot be in two folders at the same time).
We do realize that pages sometimes need to be categorized within multiple heads. This is what 'tags' are used for in other CMSes. The current version of Couch does not support tags but this feature is on the cards and the future version should have it in.
For now, we can 'simulate' the tags feature to a fair extent.
What we can do is, create an editable region of type 'text' and name it, say, 'tags' -
- Code: Select all
<cms:editable name='tags' label='Tags' desc='Use comma to separate multiple tags' type='text' />
The user can now enter freeform any number of tags he requires the page to be categorized into (separating multiple tags using comma).
To display the tags on the page, we could use the usual way (we first check if there are any tags associated with the page at all before outputting the label) -
- Code: Select all
<cms:if "<cms:not_empty tags />" >
<p>
<b>Tags: </b> <cms:show tags />
</p>
</cms:if>
However, this will simply yield a list of static terms.
To work like real tags, each of these terms should be linked to a 'list-view' page that should then list all pages of the template that have been tagged by that particular term.
We can do this linking like this -
- Code: Select all
<cms:if "<cms:not_empty tags />" >
<p>
<b>Tags: </b>
<cms:each tags sep=',' >
<a href="<cms:link k_template_name />?tag=<cms:show item />" ><cms:show item /></a>
</cms:each>
</p>
</cms:if>
What we are doing is linking each term to the 'list-view' of the same template and adding a 'tag=term' as querystring.
Thus if the template was 'blog.php' and the linked term was 'work' the link would be
- Code: Select all
http://www.yoursite.com/blog.php?tag=work
Now we need to tweak the list-view of blog.php to show only the pages with the tag name being passed in the querystring.
The existing code on the template handling the list-view should be something like this -
- Code: Select all
<cms:pages masterpage='blog.php' limit='10' paginate='1'>
<cms:show xxx /> // show values of page's fields
....
....
</cms:pages>
The 'pages' tag supports a parameter named 'custom_field' (more info at http://www.couchcms.com/docs/tags-reference/pages.html ) that can be used to fetch pages based on the values contained within any custom field.
We can use this parameter to query using the 'tags' field we have.
Thus if were to write -
- Code: Select all
<cms:pages masterpage='blog.php' limit='10' paginate='1' custom_field='tags=work'>
<cms:show xxx /> // show values of page's fields
....
....
</cms:pages>
only pages with the value 'work' anywhere within their 'tags' field will be fetched.
Instead of hard-coding the value of the 'custom_field' parameter ('tags=work'), we dynamically generate it using the value that we pass in the querystring.
Th Couch tag used to fetch values from querystring is 'gpc' (stands for GET, POST and COOKIES).
- Code: Select all
<cms:set my_tag="<cms:gpc 'tag' />" />
<cms:if my_tag >
<cms:set my_query="tags=<cms:show my_tag />" />
</cms:if>
In the code above, we first store the value passed within the querystring into a variable named 'my_tag'. Remember that 'blog.php' will be called in other views without the 'tag' parameter too, so we first check if we got back any value, and if we did we set another variable named 'my_query' to 'tags=value_we_got'.
Thus if the querystring was
http://www.yoursite.com/blog.php?tag=work
'my_query' will contain the value 'tags=work'.
Now it is simple to use this query with the 'pages' tag -
- Code: Select all
<cms:pages masterpage='blog.php' limit='10' paginate='1' custom_field=my_query>
<cms:show xxx /> // show values of page's fields
....
....
</cms:pages>
This change will now cause the 'pages' tag to fetch in only the pages with the value being passed in the querystring.
The complete code -
- Code: Select all
<cms:set my_tag="<cms:gpc 'tag' />" />
<cms:if my_tag >
<cms:set my_query="tags=<cms:show my_tag />" />
</cms:if>
<cms:pages masterpage='blog.php' limit='10' paginate='1' custom_field=my_query>
<cms:show xxx /> // show values of page's fields
....
....
</cms:pages>
This method does not mimic 'perfectly' the bonafide tagging feature because all our 'tags' are actually contained within a single field. If two tags were to be similar, for example - 'work and 'workaholic', searching for 'work' will bring up 'workaholic' too.
If you use discrete terms as tags, it should work very well though.
Please let me know it this helps.
Thanks.