digest_custom_html を HTML として扱われるように修正 (元: digest.html.erb のオーバーライド)

TL;DR:
要約:
ダイジェストにいくつか項目を追加しようとしています。以前はテンプレートをオーバーライドしていましたが、理由は不明ですが、今はそれができません。

テンプレートのオーバーライドは悪いことなので、ダイジェストには digest_custom_html で置き換えられる箇所がいくつかありますが、テキストが挿入されるため、それらには .html_safe を追加する必要があります。少なくとも1つは間違った場所にあります(名前に「above」とありますが、実際は下にあります)。

この件については、PRを作成できるスキルがあると思いますが、非常に簡単なため、他の人にやってもらう方が簡単なかもしれません。

長くて、より苦痛な話。

ここでやりました:GitHub - pfaffman/discourse-add-to-summary: Add text to summary before and after title しかし、それは機能しなくなったようです。

コアに変更を加えることなくやりたいことは、digest.html.erb テンプレートをオーバーライドすることだと思います。以前は、app/views/user_notifications/digest.html.erb に配置することでそれが可能でしたが、そのファイルがコアのファイルではなく処理されるようになりました。しかし、それはもはや機能しないようです。

現在、次のようなクールな digest_custom_html があります。

賢い読者は、人気トピックが78行あたりから始まり、277行よりもずっと前に始まることに気づくでしょう。私は、間違った場所に目を向けていたために、何も起こっていないと考えて失った時間について確信がありません。しかし、話がそれました。

plugin.rbafter_initialize でこれを管理しました。

  require_dependency "user_notifications"
  module ::UserNotificationsHelperOverride
    def digest_custom_html(position_key)
      puts "doing improved the digest: #{position_key}"
      if position_key == "below_popular_topics"
        puts "doing the custom html for above_popular_topics"

        # Custom HTML for the popular topics position
        "<div>MY COOOOOOOL TEXT</div>"
      else
        puts "doing the super for #{position_key}"
        super
      end
    end
  end

そして、それは確かにテンプレートで変更されると予想される場所にテキストを追加しています!

残念ながら、HTMLとしてではなく、テキストとして扱われています。それで。。。

all_the_plugins を調べましたが、このコードを使用している例は見つかりませんでした。

次のような行を変更した場合、PRは歓迎されますか?

        <%= digest_custom_html("below_popular_topics") %>

そして、次のように置き換えます。

        <%= digest_custom_html("below_popular_topics").html_safe %>

そして、ついでに、position_key の名前がその位置により似ていることを確認しますか?

「いいね!」 1

PRを作成しました。

「いいね!」 2

digest_custom_html が解析可能な HTML を生成しないのはバグだと判断したので、再分類します。

「いいね!」 1

@martin、名指しで申し訳ありませんが、digest.html.erb を最後に編集したのは(2年前の)あなたでした。このPRを確認していただけますか?

「いいね!」 1

このプラグインはデプロイされ、おそらくすぐに忘れてしまうでしょう。そのため、これらの digest_custom_html フィールドを意図したとおりに使用したい場合は、ソースをパッチするために app.yml に次のようなコードを追加できます。正規表現でそれらすべてを置き換えるのは面倒だったので、使用していたものだけを置き換えました。ユースケースに応じて変更してください。

プラグイン内にテンプレートを作成し、それを app.yml に含めることができます。これにより、YAMLブロック全体をいじるよりも少し簡単になります。

hooks:
  after_code:
    - replace:
        filename: "/var/www/discourse/app/views/user_notifications/digest.html.erb"
        from: 'digest_custom_html("above_footer") '
        to: 'digest_custom_html("above_footer").html_safe '
「いいね!」 1

PRを開くようチームに通知するためのタグを持つことは理にかなっているでしょうか?

「いいね!」 1

@davidさん、こんにちは。このPRに興味がある人がいるかどうか、もう一度試してみます。上記で説明したように、コードは意図したとおりに動作していませんが、誰も気にかけてくれませんでした。回避策を作成し、デプロイ時にテンプレートを修正する修正を加えてコードをデプロイしましたが、これはきれいな解決策ではありません。

「いいね!」 1

メソッドオーバーライドの結果に .html_safe を追加してもらえませんか?ERBテンプレート内にある必要はないと思います。

RailsとEmberの両方における一般的な目標は、「この文字列はHTMLとして安全である」ということを、作成/生成ポイントのできるだけ近くに配置することです。これにより、開発者はHTMLが実際に安全であることを確認する必要がある(つまり、ユーザー入力はエスケープされている)ことを明確に理解できます。

あなたがやっていることは問題ありません(テストされている限りは)。しかし、これらのメソッドの「意図された」使用方法ではありません。もしそれが意図的なプラグインAPIであれば、他のものと一緒に plugin/instance.rb にあるはずです。

このメソッドの意図された使用方法は、対応する翻訳キーにマークダウンを配置することです。

(そこにある html_safe にも注意してください。これは、オーバーライドで必要となるのと同じテクニックです。)

「いいね!」 2

オーマイガー。どうやらできるようです!!!そこにそれを置けるなんて思いもよりませんでした。テンプレートの一番上(少なくとも私の頭の中では)でレンダリングされるのではなく。
digest_customが、私が確認して理解しようとしたコードの中で、.html_safeを呼び出していることがわかりました。しかし、括弧のない奇妙な構文を使用しているのが(私には)混乱を招きます。(あるいは、それを見つけられなかったかもしれません。)

ロケールで値を確認できますが、以前行っていたテンプレートの上書きと比較すると、これははるかにリスクの低い解決策です。
正しい道を示していただき、本当にありがとうございます!

もう一つ、ばかげていると感じていることがあります。私のdigest_custom_htmlは、それがレンダリングされるユーザーを必要とするため、ダイジェストが対象とするユーザーにアクセスできるように、@userを設定するためにdigestをオーバーライドしています。それを避けるために、何か非常に簡単な方法がありますか?

after_initialize do
  # Code which should run after Rails has finished booting
  # Railsの起動完了後に実行されるコード

  # require_relative \"lib/discourse_add_jobs_to_digest/user_notifications_helper_override\"
  require_relative \"lib/discourse_add_jobs_to_digest/engine\"
  require_relative \"lib/discourse_add_jobs_to_digest/job_api\"

  require_dependency \"user_notifications\"
  module ::UserNotificationsHelperOverride
    def digest_custom_html(position_key)
      if position_key == "above_footer"
        DiscourseAddJobsToDigest::JobApi.get_jobs_html(@user).html_safe
      else
        super
      end
    end
  end

  UserNotificationsHelper.prepend(::UserNotificationsHelperOverride)

  module ::UserNotificationsOverride
    def digest(user, opts = {})
      @user = user
      super
    end
  end
  UserNotifications.prepend(::UserNotificationsOverride)
end
「いいね!」 2

テンプレート/メソッドで user 変数を使用している他のものは見当たらないため、あなたがやったことがおそらく最善の方法でしょう。

しかし、このようなオーバーライドは「サポート」できず、いつでも壊れる可能性があります。それが最終的に発生したときに、それを捕捉するテストを必ず実施してください。

「いいね!」 1

確認ありがとうございます!お時間をいただき感謝いたします。

承知いたしました。これは、以前私が似たようなプラグインで採用していた、テンプレート全体をオーバーライドするよりもはるかに良い方法です。

そして、テストは必要ですね。:wink:

「いいね!」 1

このトピックは最後の返信から30日後に自動的にクローズされました。新しい返信は許可されていません。