views:

156

answers:

5

Basically, there are some keywords that i want to pick out and assign a link to them dynamically.

How should i go about in doing this?

Let's say i have something like this;

<p>ruby, rails, php, python, django and sinatra</p>

and i would like to assign links to keywords like ruby and python, so the end results should look like this;

<p><a href="http://www.ruby-lang.org"&gt;ruby&lt;/a&gt;, rails, php, <a href="http://www.python.org"&gt;python&lt;/a&gt;, django and sinatra</p>

Any help or suggestion would be much appreciated!

A: 

Simply use text replacement? Replace "ruby" with "<a href="http://ruby-lang.org">ruby&lt;/a>", and done. See the String.replace in the javascript reference .

CharlesLeaf
thanks, but i reckon to do it on the backend.
kim
+3  A: 

If you want to do it on the server side before the content is rendered to the browser then you can do it like

str = "<p>ruby, rails, php, python, django and sinatra scruby rubysd 12ruby'; ruby </p>"

link_hash = {'ruby' => "<a href = 'http://www.ruby-lang.org'&gt;ruby&lt;/a&gt;", 'python' => "<a href='http://www.python.org'&gt;python&lt;/a&gt;" }

link_hash.each_pair do |key, value|
  str = str.gsub(/\b#{key}\b/, value)
end

str #=> "<p><a href = 'http://www.ruby-lang.org'&gt;ruby&lt;/a&gt;, rails, php, <a href='http://www.python.org'&gt;python&lt;/a&gt;, django and sinatra scruby rubysd 12ruby'; <a href = 'http://www.ruby-lang.org'&gt;ruby&lt;/a&gt; </p>"
nas
This will insert links where the keywords appear within longer words as well, which might or might not be desired. Imagine one of the keywords being "C", for instance.
Lars Haugseth
@DJTripleThreat: Then you won't catch words at the start or end of the string, or with adjacent punctuation and linebreaks. Use \b to check for word boundaries in a regexp.
Lars Haugseth
@DJTripleThread @Lars Haugseth thanks for pointing that out. I have now modified my answer to include the word boundaries.
nas
A: 

If you wanted to be particularly fancy, I think you could use an after filter:

class MyController < ApplicationController
  after_filter :link_stuff

  protected

  def link_stuff
    # You'd want to do this more carefully, so as to only get "ruby"s in text, 
    # not in tags etc.
    response.body.gsub(/ruby/, "<a href = 'http://www.ruby-lang.org'&gt;ruby&lt;/a&gt;")
  end
end
Chris
+4  A: 

One way of doing it, assuming you only want to link whole words:

html = "<p>ruby, rails, php, python, django and sinatra</p>"

word_links = { "ruby"   => "http://www.ruby-lang.org",
               "python" => "http://www.python.org" }

html.gsub(/\w+/) do |word|
  word_links[word] ? "<a href=\"#{word_links[word]}\">#{word}</a>" : word
end

If the text you are operating on is rather large, but the list of words you want to link is pretty small, this may be optimized a little by doing substitution on matching words only:

html.gsub(/\b(#{word_links.keys.join('|')})\b/,
          "<a href=\"#{word_links[$1]}\">#{$1}</a>")

Just make sure you don't have any keywords that can appear inside an opening tag (like inside an attribute value for example, which would break completely with this solution.) For a truly robust solution you will have to use a proper HTML parser and just replace content text.

Lars Haugseth
+1 for dealing with whitespace. I could swear there was a gem that does this but I can't find it!
DJTripleThreat
@Lars Haugseth, thanks! I'm using this implementation but using each_pair instead of gsub.
kim
A: 

Hi

You can do like this

first get the values as an array (or list) Ex: ruby php python etc..

send this array to a helper

def link_builder(arr) html_string = ""

for element in arr

 check whether your word needs a wrapper. you might want to do a table check 

 if warpper_needed?

    html_string = html_string + <a href='link'>elment</a>
 else
    html_string = html_string + <p>element</p>
 end

end

html_string

end

Hope you got the idea, (this might not work as it is)

cheers, sameera

sameera207