Corregir digest_custom_html para que se trate como HTML (antes: Sobrescribir digest.html.erb)

TL;DR:

Estoy intentando añadir algunas cosas al resumen. Solía sobrescribir la plantilla, pero ahora no puedo hacerlo, por razones poco claras.

Debido a que sobrescribir plantillas es malo, hay algunos lugares en el resumen que se reemplazan con digest_custom_html, pero inserta el texto, por lo que necesitan que se les añada .html_safe. Al menos uno está en el lugar equivocado (tiene “above” en el nombre, pero en realidad está debajo).

Creo que tengo las habilidades para una PR en esto, a menos que, debido a que es tan simple, sea más fácil que lo haga otra persona.

La historia más larga y dolorosa.

Lo hice aquí: GitHub - pfaffman/discourse-add-to-summary: Add text to summary before and after title pero eso parece haber dejado de funcionar.

Creo que lo que quiero hacer, sin cambios en el núcleo, es sobrescribir la plantilla digest.html.erb. Solía poder hacerlo poniendo el archivo en app/views/user_notifications/digest.html.erb y ese archivo se procesaría en lugar del del núcleo. Eso ya no parece funcionar.

Ahora, tenemos algo genial como digest_custom_html como esto:

El lector perspicaz notará que los temas populares comienzan alrededor de la línea 78, mucho antes de la línea 277. No estoy seguro de cuánto tiempo perdí pensando que no estaba pasando nada porque estaba mirando en el lugar equivocado. Pero me desvío.

Logré hacer esto en plugin.rb after_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

Y de hecho está añadiendo texto en el lugar donde esperaría que se cambiara en la plantilla.

Por desgracia, no se trata como HTML, sino como texto. Así que. . . .

Miré en all_the_plugins y no encontré ejemplos de nadie usando este código.

¿Sería una PR-welcome si cambiara las líneas como

        <%= digest_custom_html("below_popular_topics") %>

y las reemplazara con

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

Y, ya que estoy en ello, ¿quizás asegurarme de que los nombres de las position_key se parezcan más a su posición?

1 me gusta

Hice un PR:

2 Me gusta

Decidí que digest_custom_html no produce HTML que pueda ser analizado es un error, así que estoy reclasificando.

1 me gusta

@martin, disculpa que te mencione, pero fuiste la última persona en tocar digest.html.erb (hace dos años). ¿Te importaría echarle un vistazo a esta PR?

1 me gusta

Este plugin ha sido desplegado y probablemente lo olvidaré muy pronto, así que si alguien quiere usar estos campos digest_custom_html según lo previsto, puede agregar código como este a su app.yml para parchear el código fuente. Fui demasiado perezoso para crear una expresión regular que los reemplazara a todos y, en cambio, solo hice la que estaba usando. Modifique según corresponda para su caso de uso.

Creé una plantilla en el plugin que luego se puede incluir en el app.yml. Eso lo hace un poquito más fácil que lidiar con un bloque completo de 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 me gusta

¿ Tiene sentido tener una etiqueta para ayudar a alertar al equipo para abrir PRs?

1 me gusta

Hola @david. Voy a intentarlo una vez más para ver si a alguien le interesa esta PR. Como se describió anteriormente; el código claramente no está funcionando como se esperaba, pero a nadie le ha importado. He hecho una solución alternativa y he implementado el código con una corrección para parchear la plantilla en el despliegue, pero no es una solución elegante.

1 me gusta

¿Podrías añadir .html_safe al resultado de tu anulación de método? No creo que haya ninguna razón por la que deba estar en la plantilla erb.

El objetivo general, tanto en Rails como en Ember, es colocar la indicación “esta cadena es html safe” lo más cerca posible del punto de creación/generación, para que quede muy claro a los desarrolladores que deben asegurarse de que el HTML sea realmente seguro (es decir, que cualquier entrada del usuario esté escapada).

Lo que estás haciendo está bien (siempre que se pruebe), pero no es el uso “previsto” para estos métodos. Si fuera una API de plugin intencionada, estaría en plugin/instance.rb con los demás.

El uso previsto para este método es poner markdown en la clave de traducción correspondiente:

(También ten en cuenta el html_safe ahí; esa es la misma técnica que necesitarías usar en cualquier anulación).

2 Me gusta

O.M.G. Aparentemente . . . ¡¡¡¡¡puedo!!! Nunca se me habría ocurrido que pudiera ponerlo ahí y no hasta arriba en la plantilla donde (al menos en mi cabeza) se renderiza.

Ahora veo y entiendo que digest_custom y que está llamando a .html_safe, muy bien, en código que miré y traté de entender, pero es confuso (para mí) que esté usando esa sintaxis sin paréntesis. (O tal vez nunca lo habría visto).

Bueno, veo los valores en las locales, pero en comparación con sobrescribir la plantilla como lo estaba haciendo antes, esta es una solución mucho menos arriesgada.

¡Muchas gracias por ponerme en el camino correcto!

Aquí hay otra cosa que estoy haciendo y que me parece tonta. Mi digest_custom_html necesita el usuario para el que se renderiza, así que lo que estoy haciendo es sobrescribir digest para establecer @user para que mi digets_custom_html pueda tener acceso al usuario para el que es el digest. ¿Hay alguna manera súper fácil de evitar hacer eso?

after_initialize do
  # Código que debería ejecutarse después de que Rails haya terminado de arrancar

  # 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 Me gusta

No veo nada más en la plantilla/métodos que utilice una variable user, así que sí, lo que has hecho es probablemente la mejor manera de hacerlo.

Pero aun así, este tipo de anulaciones no pueden ser “soportadas” y pueden romperse en cualquier momento. Asegúrate de tener algunas pruebas para detectar eso cuando finalmente suceda.

1 me gusta

¡Gracias por la confirmación! Aprecio tu tiempo.

Entendido. Esto sigue siendo mucho mejor que anular toda la plantilla, que fue mi solución anterior para un plugin similar.

Y sí, debería haber pruebas. :wink:

1 me gusta

Este tema se cerró automáticamente 30 días después de la última respuesta. Ya no se permiten nuevas respuestas.