#rails #rich_text #trix #concerns 🇬🇧
Add a target blank to link in rich text with ruby on rails
Jeanro Krupa
Jeanro Krupa
2 min read
When a user click on a link present in a rich_text it does not open in a new page... It is something very annoying for some of our users at Komin.io. We build a LMS and we are leveraging a lot of the RichText / Trix editor features. Unfortunately it is not a default in Rails and not present in the documentation either. The solution implemented has been inspired by this issue: https://github.com/basecamp/trix/issues/55
At Komin.io we have a lot of models that
At Komin.io we have a lot of models that
has_rich_text :something
. Some requirements- The name of the attribute is not always the same (:body, :text, :comment_body....)
- Sometimes we have many different rich_text elements for a single class...
- For one specific model we don't the target blank
We created a concern:
# app/models/concerns/rich_text_target_blank.rb module RichTextTargetBlank extend ActiveSupport::Concern class_methods do # Override has_rich_text to include target="_blank" functionality def has_rich_text(name) super(name) # Call the original has_rich_text to set up the rich text association # Define the before_save callback to modify the links before_save do rich_text_attribute = self.send(name) if rich_text_attribute.present? doc = Nokogiri::HTML::DocumentFragment.parse(rich_text_attribute.body.to_html) doc.css('a').each { |a| a['target'] = '_blank' } rich_text_attribute.body = doc.to_html end end end end end
The concept is to override the has_rich_text method to add a `before_save` callback.
In the callback we parse with Nokogori all the `<a>`html tags and add the attribute target="_blank" on it.
Then we simple have to include the concern inside our class.
In the callback we parse with Nokogori all the `<a>`html tags and add the attribute target="_blank" on it.
Then we simple have to include the concern inside our class.
class Comment < ApplicationRecord include RichTextTargetBlank has_rich_text :body end
The last thing to do if you want to modify the existing RichText attachments that you may have in production is to call .save on all the instances.
Comment.all.map(&:save)
We could also had a no follow attribute but not required in our case because our pages are not indexed by the browsers.