0

我从 Orchard Token Providers 那里得到了一些帮助,任何帮助都是一件好事。我大部分时间都在复制评论令牌。

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

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

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;
}

}

这是操作(当问题发布时),它会发送一封带有正文的电子邮件:(已更新以测试 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} 工作得很好。任何人注意到的任何错误或提示都将非常有用。

谢谢,马特

4

3 回答 3

1

我重新编写了令牌提供程序,它的工作方式有点......(现在完全工作)

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 和 Author 方法中调试代码。由于在控制器中触发此行时触发了已发布的事件,因此检索到的值为“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}。当一切正常并且一切正常时,一切都很好而且很简单。

于 2013-04-24T13:17:20.473 回答
0

马修,尝试为以下内容添加 .Value:{Content.QuestionAuthor.Value}

如果这不起作用,请尝试 .Text。

希望这可以帮助。

于 2013-04-23T20:15:38.657 回答
0

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

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

我花了一整天的时间对我的代码进行故障排除,该代码看起来与上面的代码相似,直到我开始测试我的规则中的其他事件类型,它才在私有函数中填充了数据。

这是我的代码:

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;
  }
}
于 2013-08-12T13:48:18.673 回答