GithubHelp home page GithubHelp logo

Comments (33)

sstephenson avatar sstephenson commented on August 28, 2024 110

Thanks for the feature request, but I don’t think we’ll be adding this to Trix. If you need to add a target attribute to links, I’d suggest post-processing the HTML when you render it in your application.

from trix.

fsamir avatar fsamir commented on August 28, 2024 43

IMO, Workaround suggest to post-process is poor. I might want to create links to external content and internal content.

from trix.

javan avatar javan commented on August 28, 2024 33

You could also handle this client side instead of post-processing your HTML:

// Open all external links in a new window
addEventListener("click", function(event) {
  var el = event.target

  if (el.tagName === "A" && !el.isContentEditable && el.host !== window.location.host) {
    el.setAttribute("target", "_blank")
  }
}, true)

from trix.

ryan-kimber avatar ryan-kimber commented on August 28, 2024 23

This would be a great, and trivial feature to add, while adding post-processing to any application that would like this feature is definitely more complex.

Would you reconsider?

from trix.

jmz-b avatar jmz-b commented on August 28, 2024 11

+1

from trix.

JoshCheek avatar JoshCheek commented on August 28, 2024 11

@RicottaZhang's solution didn't work for me b/c in some places, our content gets put on the page by JavaScript, so it isn't there when the page loads.

This is the best I've come up with:

# file: app/helpers/trix_helper.rb
module TrixHelper
  SCRUBBER = Loofah::Scrubber.new do |node|
    node[:target] = '_blank' if node.name == 'a'
  end

  # Overriding https://github.com/rails/rails/blob/da795a678b341adc8031c4d9cf0b5ef2176e2a5a/actiontext/app/helpers/action_text/content_helper.rb#L17
  def sanitize_action_text_content(content)
    original_scrubber, self.scrubber = self.scrubber, SCRUBBER
    super
  ensure
    self.scrubber = original_scrubber
  end
end

from trix.

ksarna avatar ksarna commented on August 28, 2024 7

If anyone is looking for a quick way to fix this in rails. Here's what you can do:
(needs nokogiri)

module TrixHelper
  # found at stack overflow: https://stackoverflow.com/a/41557234/244089
  def change_a_target(body)
    doc = Nokogiri::HTML(body)
    doc.css('a').each do |link|
      link['target'] = '_blank'
      # To avoid window.opener attack when target blank is used
      # https://mathiasbynens.github.io/rel-noopener/
      link['rel'] = 'noopener'
    end
    doc.to_s
  end

  def sanitize_trix_html(html)
    sanitize(change_a_target(html), tags: %w(strong a), attributes: %w(href target rel))
  end
end

Then in your view you can:
<%= sanitize_trix_html(@post.body_html) %>

from trix.

RicottaZhang avatar RicottaZhang commented on August 28, 2024 7

FYI, at last I add it works for editor and show trix content.

$(document).ready(function() {
    $(".trix-content a").click(function(e) {
        $(this).attr("target","_blank");
    });

  // For those content inject by javascript, use an event handler for your trix container may be better.
  $(YourTrixContainerSelector).on('click', '.trix-content a', function(e) {
        $(this).attr("target","_blank");
   });
});

P.S. I prefer stick the solution to Javascript. So it can turn on case by case for each view.

from trix.

siax84 avatar siax84 commented on August 28, 2024 7

It is very hard to believe this is not an option on a per-link basis and is not even considered after people suggest it.

from trix.

adamschwartz avatar adamschwartz commented on August 28, 2024 5

@codeclown I’m guessing @Quirksmode means an option in the editor to add target="_blank" to a link.

from trix.

spaquet avatar spaquet commented on August 28, 2024 5

For those of you wondering if there is a Stimulus approach to this problem I found the following answer on StackOverflow:

  1. Add a Stimulus controller richtext_controller.js (rails g stimulus richtext)
import { Controller } from "stimulus"

export default class extends Controller {
  connect() {
    this.element.querySelectorAll('a').forEach(function(link) {
      if (link.host !== window.location.host) {
        link.target = "_blank"
      }
    })
  }
}

And wrap your rich text display as follow:

<div data-controller="richtext">
  <%= post.rich_text_content %>
</div>

Source: https://stackoverflow.com/questions/65985735/how-to-open-action-text-trix-attachments-or-links-in-new-window-target-blank

from trix.

elsurudo avatar elsurudo commented on August 28, 2024 4

+1 on this one... it's a very common use-case, and doing this outside the editor (post-processing) seems like a hack. It seems a a strange decision to reject it outright like this.

from trix.

lewaabahmad avatar lewaabahmad commented on August 28, 2024 4

+1

Is there a philosophical reason this is not to be developed? As in, if a PR were to come in for this, would it be rejected?

from trix.

asecondwill avatar asecondwill commented on August 28, 2024 2

For some use cases (all the time for me), the user needs to be able to choose new window. Post processing with ruby or js to open in new window for all links or for external links is to broad brush. needs option to choose.

If I make my own button to add links (simple enough) how can I stop trix stripping my target=_blank ?

from trix.

Quirksmode avatar Quirksmode commented on August 28, 2024 1

That's correct @adamschwartz, whilst I don't agree it's best practice, I am yet to meet a client who doesn't want the ability to open their links in a new window. A simple checkbox below the input where you add the url would suffice :-)

from trix.

PQALAB avatar PQALAB commented on August 28, 2024 1

I was able to easily serialize my data coming from ActionText to accomplish this. Maybe it'll help someone else out

app/serializers/blah_serializer.rb
def content
    unless object.content.body.links.empty?
      html = Nokogiri.parse(object.content.body.to_html)
      html.css('a').each do |link|
        link["target"] = "_blank"
        link['rel'] = 'noopener'
      end
      html.to_s
    else
      object.content.to_s
    end
  end

from trix.

SebSwan avatar SebSwan commented on August 28, 2024 1

+1

from trix.

wawer77 avatar wawer77 commented on August 28, 2024 1

Rather pointless, but anyway - I'd like to emphasise that proposed post processing solutions work only for internally rendered links. It would be much cleaner to hold Rich Text with everything we need, so it can be reused and rendered elsewhere.

EDIT:
Actually, I have found a more generic workaround for Rails app. Based on this article.

Create a config/initializers/action_text.rb file and allow target attribute

ActionText::ContentHelper.allowed_attributes += ['target']

Then in your model, which has_rich_text :attribute create a callback before saving, which will add the attribute:

content.gsub('<a href', '<a target="_blank" href')

from trix.

jromainkrupa avatar jromainkrupa commented on August 28, 2024 1

A mix of @wawer77 and @PQALAB approaches with a concern to include in your model. adding a before_save on all has_rich_text attributes of the class.

# 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

from trix.

codeclown avatar codeclown commented on August 28, 2024

In the context menu? Shows up for me in Safari 8.0.8.

Edit: I'm not a smart person.

from trix.

adamschwartz avatar adamschwartz commented on August 28, 2024

@Quirksmode Absolutely I think it’s a very reasonable suggestion. 👍

from trix.

hrishimittal avatar hrishimittal commented on August 28, 2024

Yes please!

from trix.

bostondevin avatar bostondevin commented on August 28, 2024

+1 yeah - i'll need this one too

from trix.

goravbhootra avatar goravbhootra commented on August 28, 2024

as the usage is growing, I am facing limitations with trix and this is one of them. The other one is inability to set constraints like required for the input boxes.

from trix.

crimson-knight avatar crimson-knight commented on August 28, 2024

Adding my +1 to make this feature part of Trix.

from trix.

RicottaZhang avatar RicottaZhang commented on August 28, 2024

+1

Post process only handle trix html after, we also need it to target blank when editing.

from trix.

yshmarov avatar yshmarov commented on August 28, 2024

@RicottaZhang this workaround works well. Thank you. All Trix links are opened in a new tab.

from trix.

garytaylor avatar garytaylor commented on August 28, 2024

Adding a +1 - this is a requirement for my project too. Whilst I can do a workaround for now, I can see that we will need to ask as part of the link dialog as to whether the link should open in a new window or not

from trix.

marcelosantos89 avatar marcelosantos89 commented on August 28, 2024

+1

from trix.

crespire avatar crespire commented on August 28, 2024

Yeah, I ended up taking the stimulus approach as well, but what a poor thing to have to do for such a basic feature.

from trix.

StanBarrows avatar StanBarrows commented on August 28, 2024

+1

from trix.

binarygit avatar binarygit commented on August 28, 2024

Thank You @spaquet for the snippet but it is disappointing that we need to use a hack for such a basic thing.

from trix.

cheesegrits avatar cheesegrits commented on August 28, 2024

Another +1 for this feature. Hard to believe it was simply dismissed out of hand back in 2015, and never reconsidered. Literally every project I work on, the client want to be able to optionally open embedded links in a new tab.

from trix.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.