Is it possible to create an orchard autoroute usin

2019-07-13 10:43发布

问题:

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.