Refer to https://orchard.codeplex.com/workitem/20215 on updates regarding this feature.
Edit 11/11/2013:
Since writing this article I've discovered a better method which allows a full taxonomy term path to be slugified and returned into a token result: http://sheltonial.blogspot.com.au/2013/11/orchard-cms-taxonomy-term-autoroute.html
Recently (as of 17/10/2013) the Orchard CMS team has fixed a bug which was preventing taxonomy tokens from returning a value.
Currently I am working off changeset a62f0281ebdac780a1d3a583dbc5821ca8fbc6ce on version 1.7.1 and can confirm that this is working.
An example of an autoroute pattern that works is {Content.Fields.BlogPost.Category.Terms:0}, where [BlogPost] is the name of your content type, and [Category] is the name of the field within our content type, not the taxonomy or term.
This means we can start injecting taxonomy terms into our autoroute patterns and enjoy structuring a url hierarchy based on taxonomy terms and being able to interact with this new url data within queries and layer rules. This is fine if your taxonomy is a single word containing no spaces or special characters, but once you introduce other characters these are also injected into the URL.
The following code adds a new token called TermSlug which allows a taxonomy term to be slugified:
- File to modify: \src\Orchard.Web\Modules\Orchard.Taxonomies\Tokens\TaxonomyTokens.cs
- Usage: {Content.Fields.BlogPost.Category.TermsSlug:0} (refer to example above)
// Comment
using System;
using System.Linq;
using Orchard.Taxonomies.Fields;
using Orchard.Localization;
using Orchard.Tokens;
using Orchard.Autoroute.Services;
namespace Orchard.Taxonomies.Tokens {
public class TaxonomyTokens : ITokenProvider {
private readonly ISlugService _slugService;
public TaxonomyTokens(ISlugService slugService)
{
T = NullLocalizer.Instance;
_slugService = slugService;
}
public Localizer T { get; set; }
public void Describe(DescribeContext context) {
// Usage:
// Content.Fields.Article.Categories.Terms -> 'Science, Sports, Arts'
// Content.Fields.Article.Categories.Terms:0 -> 'Science'
// When used with an indexer, it can be chained with Content tokens
// Content.Fields.Article.Categories.Terms:0.DisplayUrl -> http://...
context.For("TaxonomyField", T("Taxonomy Field"), T("Tokens for Taxonomy Fields"))
.Token("Terms", T("Terms"), T("The terms (Content) associated with field."))
.Token("Terms[:*]", T("Terms"), T("A term by its index. Can be chained with Content tokens."))
.Token("TermsSlug[:*]", T("Terms"), T("A term slug by its index. Can be chained with Content tokens."))
;
}
public void Evaluate(EvaluateContext context) {
context.For("TaxonomyField")
.Token("Terms", field => String.Join(", ", field.Terms.Select(t => t.Name).ToArray()))
.Token(
token => token.StartsWith("Terms:", StringComparison.OrdinalIgnoreCase) ? token.Substring("Terms:".Length) : null,
(token, t) => {
var index = Convert.ToInt32(token);
return index + 1 > t.Terms.Count() ? null : t.Terms.ElementAt(index).Name;
})
.Token(
token => token.StartsWith("TermsSlug:", StringComparison.OrdinalIgnoreCase) ? token.Substring("TermsSlug:".Length) : null,
(token, t) =>
{
var index = Convert.ToInt32(token);
return index + 1 > t.Terms.Count() ? null : _slugService.Slugify(t.Terms.ElementAt(index).Name);
})
// todo: extend Chain() in order to accept a filter like in Token() so that we can chain on an expression
.Chain("Terms:0", "Content", t => t.Terms.ElementAt(0))
.Chain("Terms:1", "Content", t => t.Terms.ElementAt(1))
.Chain("Terms:2", "Content", t => t.Terms.ElementAt(2))
.Chain("Terms:3", "Content", t => t.Terms.ElementAt(3))
;
}
}
}
Hope this helps!
No comments:
Post a Comment