2013-04-23 29 views
0

我从果园​​代币提供商那里得到一个头痛,任何帮助将是一件幸事。 我一直在复制评论标记。果园代币 - >

目标是发送“问题”内容项目时发送的电子邮件。

这里是我的内容类型“问题”的解决方案:

public interface ITokenProvider : IEventHandler 
{ 
    void Describe(dynamic context); 
    void Evaluate(dynamic context); 
} 

public class QuestionTokens : ITokenProvider 

{ 
    public QuestionTokens() 
    { 
     T = NullLocalizer.Instance; 
    } 
public Localizer T { get; set; } 

public void Describe(dynamic context) 
{ 
    //presume this is correct 
    context.For("Content", T("Content Items"), T("Content Items")) 
     .Token("QuestionText", T("Question Text"), T("Text of the question")) 
     .Token("QuestionAuthor", T("Question Author"), T("Author of the question")); 
    //presume this is incorrect? correct for the content type? 
    context.For("Question", T("Questions"), T("Questions from users")) 
     .Token("QuestionText", T("Question Text"), T("Text of the question")) 
     .Token("QuestionAuthor", T("Question Author"), T("Author of the question")); 
} 

public void Evaluate(dynamic context) 
{ 

    Func<IContent, object> questionTextAccessorFromContent = (content) => { 
     var part = content.As<QuestionPart>(); 
     return part.QuestionText; 
    }; 

    Func<QuestionPart, object> questionTextAccessor = (part) => 
    { 
     return part.QuestionText; 
    }; 

    Func<IContent, object> authorAccessorFromContent = (content) => { 
     var part = content.As<QuestionPart>(); 
     return part.Author; 
    }; 

    Func<QuestionPart, object> authorAccessor = (part) => 
    { 
     return part.Author; 
    }; 

    //doesnt work 
    context.For<IContent>("Content") 
     .Token("QuestionText", (Func<IContent, object>) 
    (content => content.As<QuestionPart>().Record.QuestionText)) 
     .Token("QuestionAuthor", (Func<IContent, object>) 
    (content => content.As<QuestionPart>().Record.Author)); 
    //doesnt work 
    context.For<IContent>("Question") 
     .Token("QuestionText", (Func<IContent, object>) 
    (content => content.As<QuestionPart>().Record.QuestionText)) 
     .Token("QuestionAuthor", (Func<IContent, object>) 
    (content => content.As<QuestionPart>().Record.Author)); 
    //doesnt work 
    context.For<QuestionPart>("Question") 
     .Token("QuestionText", (Func<QuestionPart, object>) 
    (content => content.Record.QuestionText)) 
     .Token("Author", (Func<QuestionPart, object>) 
    (content => content.Record.Author)); ; 
} 

private static string QuestionText(IContent question) 
{ 
    var questionPart = question.As<QuestionPart>(); 
    return questionPart.QuestionText; 
} 

private static string Author(IContent question) 
{ 
    var questionPart = question.As<QuestionPart>(); 
    return questionPart.Author; 
} 

}

这是Action(当问题被出版),它发送一个电子邮件正文: (更新为测试Medeiros的建议)

<p>A question has been created by: {Content.QuestionAuthor}</p> 
<p>A question has been created by: {Content.QuestionAuthor.Text}</p> 
<p>A question has been created by: {Content.QuestionAuthor.Value}</p> 
<p>A question has been created by: {Question.QuestionAuthor}</p> 
<p>A question has been created by: {Question.QuestionAuthor.Text}</p> 
<p>A question has been created by: {Question.QuestionAuthor.Value}</p> 
<p>Message: {Content.QuestionText}</p> 
<p>Message: {Content.QuestionText.Text}</p> 
<p>Message: {Content.QuestionText.Value}</p> 
<p>Message: {Question.QuestionText}</p> 
<p>Message: {Question.QuestionText.Text}</p> 
<p>Message: {Question.QuestionText.Value}</p> 

所有'我'的标记被替换为空白文本。其他令牌,如:{Content.ContentType} {User.Email}工作得很好。任何人注意到的任何错误或暗示都将非常有用。

谢谢,马特

回答

1

IVe中重新编写的令牌供应商,它的工作原理有点...(现在的工作完全)

public class QuestionTokens : Orchard.Tokens.ITokenProvider 
{ 
    private readonly IContentManager contentManager; 
    private readonly IWorkContextAccessor workContextAccessor; 

    public QuestionTokens(IContentManager contentManager, IWorkContextAccessor workContextAccessor) 
    { 
     this.workContextAccessor = workContextAccessor; 
     this.contentManager = contentManager; 
     T = NullLocalizer.Instance; 
    } 

    public Localizer T { get; set; } 

    /// <summary> 
    /// Describes the specified context. 
    /// </summary> 
    /// <param name="context">The context.</param> 
    public void Describe(DescribeContext context) 
    { 
     context.For("Content", T("Content Items"), T("Content Items")) 
      .Token("QuestionText", T("Question Text"), T("Text of the question")) 
      .Token("QuestionAuthor", T("Question Author"), T("Author of the question")); 
    } 

    /// <summary> 
    /// Evaluates the specified context. 
    /// </summary> 
    /// <param name="context">The context.</param> 
    public void Evaluate(EvaluateContext context) 
    { 
     context.For<IContent>("Content") 
      .Token("QuestionText", content => QuestionText(content, context)) 
      .Token("QuestionAuthor", content => Author(content, context)); 
    } 

    private string QuestionText(IContent question, EvaluateContext context) 
    { 
     var questionPart = question.As<QuestionPart>(); 
     return questionPart.QuestionText; 
    } 

    private string Author(IContent question, EvaluateContext context) 
    { 
     var questionPart = question.As<QuestionPart>(); 
     return questionPart.Author; 
    } 

} 

我现在可以调试至少在私人QuestionText和作者方法的代码。由于在控制器中触发此行时发布的事件触发,检索到的值为'null': services.ContentManager.Create(“Question”);

因此,内容项目尚未填充,并且“已发布”事件在其生命开始之前就已触发。时间玩它的内容类型设置了一下,看看是否有所作为...

最后所有工作根据需要。事件部分“发布”事件仍然在发生,当我不期望它,所以我改变了内容的生活。

从控制器:(一些代码,删除服务,所以我没有发布更多的代码)

var item = services.ContentManager.New<Models.QuestionPart>("Question"); 
this.TryUpdateModel(item); 
services.ContentManager.Create(item.ContentItem); //where the event is firing 
Services.ContentManager.Publish(item.ContentItem); //where i expected the event to fire :) 

最初它是创建,更新和保存。但事件限制了这一点。所以现在它的新,更新和创建。 至于代币。他们只是: {Content.QuestionAuthor}和{Content.QuestionText}。当一切正常时,一切都是正确的,这很好,很简单。

0

马修,尝试添加一个.value的为:{Content.QuestionAuthor.Value}

如果这不起作用,尝试。文本。

希望这会有所帮助。

+0

没有运气无论是价值还是在最后文本。好的提示虽然。我会尝试更新我的消息。我曾尝试过像注释那样的静态方法,但它永远不会到达该代码块。所以我想知道它的描述部分是错的...? – Matthew 2013-04-24 11:52:17

0

原始问题中的代码看起来准确。您遵循正确的Orchard Events总线惯例创建从IEventHandler继承的接口link

您在控制器代码中的更改可能是您获取值的原因。我调试代码的经验是,它取决于你的规则订阅什么事件。例如,类型为“Content Created”的事件在Evaluate方法中触发调试器,但所有自定义零件属性均为null。但是,“提交自定义表单时”击中并填充了值。

我花了整整一天的故障排除我的代码看起来类似你上面,这是直到我开始测试在我的规则其他事件类型,它有居住在私有函数数据。

这里是我的代码:

public interface ITokenProvider : IEventHandler 
{ 
    void Describe(dynamic context); 
    void Evaluate(dynamic context); 
} 

public class PersonTokens : ITokenProvider 
{ 
    private readonly IContentManager _contentManager; 

    public Localizer T { get; set; } 

    public PersonTokens(IContentManager contentManager) 
    { 
    _contentManager = contentManager; 
    T = NullLocalizer.Instance; 
    } 
    public void Describe(dynamic context) 
    { 
    context.For("Content", T("Content Items"), T("Content Items")) 
     .Token("FirstName", T("First Name"), T("The Person's First Name")) 
     .Token("LastName", T("Last Name"), T("The Person's Last Name")) 
     .Token("EmailAddress", T("Email Address"), T("The Person's Email Address")) 
     .Token("PhoneNumber", T("Phone Number"), T("The Person's Phone Number")); 
    } 

    public void Evaluate(dynamic context) 
    { 
    // Orchard.Tokens.Implementation.TokenManager.EvaluateContextImpl 
    context.For<IContent>("Content") 
     .Token("FirstName", (Func<IContent, object>)FirstName) 
     .Token("LastName", (Func<IContent, object>)(content => content.As<PersonPart>().Record.LastName)) 
     .Token("EmailAddress", (Func<IContent, object>)(content => content.As<PersonPart>().EmailAddress)) 
     .Token("PhoneNumber", (Func<IContent, object>)PhoneNumber); // left the PhoneNumber out of sample 
    } 

    private string FirstName(IContent person) 
    { 
    var personPart = person.As<PersonPart>(); 
    return personPart.Record.FirstName; 
    } 
}