问题
I have an Orchard cms module with some additional Content types set up and have added an AutoRoute component via code. Everything works perfectly, however I am not happy with the default permalink pattern.
What I am trying to do is add a custom pattern and use one of the public properties in my content type. In my case the custom type has a public property called ClubName and I would like that to be used (It makes more sense from a routing perspective).
The Orchard part class name is called TrackPart
.
I have tried {Content.TrackPart.ClubName}
, {Content.Track.ClubName}
, {ContentItem.TrackPart.ClubName}
,{Content.TrackPart.ClubName}
and various other variations but nothing seems to be working.
I am really new to Orchard so there is a high chance I am missing something simple.
Any help would be greatly appreciated.
In response to feedback from @Bertrand-le-roy I created my own token by copying an example token. I can now get see the token in the drop down menu and select it. However the route pattern is still not working.
I can only assume that I have misunderstood the Evaluate() function's context.For
usage. It looks like I am not getting the data I need
Here is what I have so far.
public class TrackPartTokens : ITokenProvider {
private readonly IContentManager _contentManager;
public TrackPartTokens(IContentManager contentManager) {
_contentManager = contentManager;
}
public Localizer T { get; set; }
public void Describe(dynamic context) {
context.For("Track", T("Track"), T("Tokens for Track"))
.Token("ClubName", T("ClubName"), T("The name of the club."))
;
}
public void Evaluate(dynamic context) {
context.For<TrackPart>("Track")
.Token("ClubName", (Func<TrackPart, object>)(field => field.ClubName))
.Chain("ClubName", "ClubName", (Func<TrackPart, object>)(field =>field.ClubName))
;
}</code>
The above code was based on the DateTimeField token inside the Orchard.Fields module.
context.For("DateTimeField") .Token("Date", (Func)(field => field.DateTime)) .Chain("Date", "Date", (Func)(field => field.DateTime));
回答1:
You'll have to make your own token. It's really easy. Copy a working example.
回答2:
I had the same issue.
After some troubleshooting I managed to get the autoroute working by changing my implementaion to the following (adapted to your example, note that your setup might require some changes to the linq-function):
In your tokens-class:
- First add a using System.Linq statement.
Then change your Evaluate implementation to the following:
context.For<IContent>("Content") .Token("ClubName", (Func<IContent>, object>)(content => content.ContentItem.Parts.OfType<TrackPart>().First().ClubName));
Make sure your AutoroutePart settings in Migrations.cs uses the Content-prefix. Like:
.WithPart("AutoroutePart", partBuilder => partBuilder .WithSetting("AutorouteSettings.AllowCustomPattern", "true") .WithSetting("AutorouteSettings.AutomaticAdjustmentOnEdit", "false") .WithSetting("AutorouteSettings.PatternDefinitions", @"[{Name:'Track', Pattern:'{Content.ClubName}', Description:'Your description'}]") .WithSetting("AutorouteSettings.DefaultPatternIndex", "0"))
There seems to be some problems with the TokenManager-class in Orchard source that only allows the target-parameter to equal "Content" in order for the call: _data.TryGetValue(target, out value) to work (TokenManager.cs, line 67). I have tried a number of different setups but the _data-dictionary always only contain the "Content" key.
来源:https://stackoverflow.com/questions/11716230/is-it-possible-to-create-an-orchard-autoroute-using-contents-of-a-custom-type-pr