Utilisation des aides (ou de rendre partiels) à partir de balises personnalisées RedCloth
-
29-10-2019 - |
Question
J'essaie d'appeler un assistant de vue à partir d'une balise Redcloth personnalisée et je n'ai absolument aucune chance. Tous les exemples que je peux trouver ont la méthode de balise personnalisée créer et renvoyer une chaîne littérale sans appeler une autre méthode du tout.
J'essaie de créer une balise RedCloth personnalisée pour produire un calendrier hebdomadaire; dont le code a déjà été écrit dans un assistant car il est également utilisé dans d'autres domaines de l'application.
Voici donc le code (massivement réduit) auquel mon problème se résume:
app / vues / page / show.html.erb:
<%= raw redcloth @page.content %
app / houstants / pages_helper.rb:
module PagesHelper
def redcloth(content)
r = RedCloth.new content
r.extend ScheduleTag
r.to_html
end
end
app / helters / calendrier_tag.rb:
module ScheduleTag
include ScheduleHelper
def schedule(options)
build_schedule
end
end
app / houstants / calendrier_helper.rb:
module ScheduleHelper
def build_schedule
content_tag :div do
content_tag :span,
"Why won't my helper just work by magic like the rest of " \
"rails seems to?"
end
end
end
Lorsqu'il est exécuté, Rails revendique ce qui suit:
TypeError in Pages#show
Showing /blah/blah/blah/app/views/pages/show.html.erb where line #1 raised:
can't convert Symbol into Integer
Extracted source (around line #1):
1: <%= raw redcloth @page.content %>
Rails.root: /blah/blah/blah
Application Trace | Framework Trace | Full Trace
app/helpers/schedule_helper.rb:3:in `build_schedule'
app/helpers/schedule_tag.rb:42:in `schedule'
app/helpers/pages_helper.rb:22:in `redcloth'
app/views/pages/show.html.erb:1:in _app_views_pages_show_html_erb___756530284_81829440__535015588'
app/controllers/pages_controller.rb:23:in `show'
Je peux faire un peu de progrès en passant de l'utilisation d'un aide à une classe, mais cette classe a toujours des problèmes en utilisant les aides standard:
/app/helpers/schedule_builder.rb:
class ScheduleBuilder
extend ActionView::Helpers::TagHelper
def self.build_schedule
content_tag :div do
content_tag :span,
"Why won't my helper just work by magic like the rest of " \
"rails seems to?"
end
end
end
Et Rails dit:
NoMethodError in Pages#show
Showing /blah/blah/blah/app/views/pages/show.html.erb where line #1 raised:
undefined method `output_buffer=' for ScheduleBuilder:Class
Extracted source (around line #1):
1: <%= raw redcloth @page.content %>
Rails.root: /blah/blah/blah
Application Trace | Framework Trace | Full Trace
app/helpers/schedule_builder.rb:5:in `build_schedule'
app/helpers/schedule_tag.rb:42:in `schedule'
app/helpers/pages_helper.rb:22:in `redcloth'
app/views/pages/show.html.erb:1:in `_app_views_pages_show_html_erb___756530284_81708830__535015588'
app/controllers/pages_controller.rb:23:in `show'
Alors que dois-je faire? Est-ce que je manque quelque chose de complètement évident et devrais enterrer la tête de honte, ou n'est-il tout simplement pas possible d'appeler des aides de n'importe où des fantaisies? Dois-je simplement le sucer et obtenir la balise personnalisée pour dupliquer tout le code dans mon module ScheduleHelper?
Toute aide serait grandement appréciée.
La solution
D'accord, donc je suis moi-même venue à une solution acceptable. Je serai donc un bon petit garçon et je partagerai.
Au lieu d'une aide, je vais utiliser une classe qui rend un partiel, donc la question devrait vraiment devenir: "Appeler partiels à partir de balises RedCloth personnalisées".
(Je n'ai pas commenté le code, il devrait être assez autonome)
app / helters / calendrier_tag.rb:
module ScheduleTag
def schedule(options)
Schedule.new.render Date.today.monday
end
end
App / Aiders / Schedule.rb:
class Schedule < ActionView::Base
include ActionView::Helpers::TagHelper
include Rails.application.routes.url_helpers
def render week
self.view_paths = "app/views"
super :partial => "schedule/schedule",
:locals => { :week => week,
:schedule => ScheduledClass.get_schedule(week) }
end
end
app / vu / calendrier / _schedule.html.erb:
<table id="schedule">
<tbody>
<tr>
<td>Hoop-dee-doo, it works!</td>
<%= content_tag :td do %>
<%= link_to "so do tag & route helpers", happy_monkey_path(:happy => "very") %>
<% end %>
</tr>
</tbody>
</table>
En dehors de côté, si vous deviez essayer ceci, vous pouvez tomber sur le problème de Redcloth échappant à votre chaîne d'options. Joignez simplement les options à l'intérieur ==
est de le faire passer littéralement les options. par exemple schedule. =={"weeks":["this","next"]}==
. Cela peut être un peu du côté dangereux, alors assurez-vous de vérifier la désintérité.