views:

98

answers:

4

I'm trying to build a simple wiki system in Rails.

What i would like to do is to turn words within double brackets into links, automatically.

E.g. if i have a word written like this [[example]]

Rails automatically generates a link like:

/notes/show/example

Any ideas of how i could do this?

Many thanks

A: 

I would use a regular expression to check user input (when someone edits the page) then on save convert those found matches into links.

reg = Regexp.new('\[{2}[a-z]+\]{2}')
reg.match(page.content) do |match|
  #your code here
end

See http://www.regular-expressions.info/ruby.html

On your "Page" model I would have a field to store the converted text and have a virtual attribute which contains unfiltered text. The "set" method of this virtual attribute then provides all the conversion logic.

For added bonus points, I'd first check whether the wiki page exists.

dreinavarro
wouldn't gsub be better? - needs replacement of string rather than just matching it. Adding virtual attributes and such seems like smashing a fly with a lump hammer, especially since this kind of is logic that should belong in the view, possibly inside a helper method.
Omar Qureshi
A: 

I am guessing you want to provide a text editor to the user through which he/she will enter the text. In that case its recommended to use Javascript WYSIWYG editors like textile, markdown, TinyMCE or YUI.

If not, you can write a regular expression while parsing the user input:

pattern = Regexp.new('\[\[([a-zA-Z]+)\]\]') # Replace [a-zA-Z]+ with your choice of text match
link_converted_text = entered_text.gsub(pattern) {|match| link_generator_function(match[1]) }

Link to gsub method of String class

Swanand
A: 

I would use a Model callback to generate the html upon saving the Note:

class Note < ActiveRecord::Base
  before_save :generate_html

  # ...other stuff...

  def generate_html
    # 'html' is a field whose value is a HTML version of the 'content' field
    self.html = self.content.gsub(/\[{2}([a-z]*?)\]{2}/) { |match| link_to $1, "/notes/show/#{$1}" }

    # generate other html...
  end
end

In order to actually view the Note at a URL like /notes/show/something you need to tell Rails how to accept it (Rails 'show' routes usually expect the ID of the record you are showing). In your Notes model, enter something like this (I am assuming that you have a field called url that is a URL-friendly title):

def Note.find_by_id_or_url id
  Note.find :first, :conditions => ['id = ? or url = ?', id, id]
end

And then in the Notes controller, add something like this for the show action:

@note = Note.find_by_id_or_url(params[:id])

Personally, I would recommend not writing your own syntax parser and just using something like Markdown.

Nathan
A: 

I don't like solving every problem with a plugin but perhaps 'wikicloth', an implementation of the MediaWiki markup language would help you out?

hopeless