Over a million developers have joined DZone.

Simplistic Texteditor For Your Next Ruby On Rails Webapplication

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

Do you want to come to the metaparty? Okay it is not a party tool it is a political site in German where the party member itself create the party platform. The vision is: if you vote for metapartei you will get representative candidates which supports the oppinion of the nation - not of a specific lobby. As a member of Metapartei you can create concepts (ideas) and vote for them. At some day the set of all voted concepts will be our party platform.

Metapartei.de was written entirely with rails and with the help NetBeans as IDE (I could displace aptana ;-)). It is and it was really fun. Especially the database migrations in rails are fantastic for production! Okay sometimes ruby wasn’t that much fun. For example the following passes (very strange!):

assert_equal 2, "ÄÄa__".mb_chars.index("a", 4) 

 

In the meanwhile we have to decide how the user can input some more than only text. If you would allow pure html then you would introduce a big security hole! For example someone could then insert any javascript function he likes with e.g. the <script> tag. So we need a rich text editor. But which one? There are a lot of editors out to allow the user to mark up the text. See the appendix for some we had evaluated. But we finally choose

Control.TextArea

from Ryan Johnson, because it is very small and highly customizable. See here for a life example. The small trade-off we had to pay was that we had to implement the conversation from wiki text to html. But this was relative easy. See The ruby code (under public domain) for the WikiText class, which implements the following behaviour:

  • ”bold” to bold
  • ”’italic”’ to italic
  • line breaks to <br />
  • and links like [http://www.metapartei.de Metapartei - a great idea] to Metapartei - a great idea

You can simply add other things (just let me know if you implement lists ;-)). But how you can embed the javascript with ruby? Here is the answer:

TextArea within Rails

Get the textarea.js from the TextArea bundle and put it under public/javascripts. Then create a file textarea_init.js from the code in the The javascript codesection. Then insert

<%= javascript_include_tag 'textarea' %> 

 

into app/views/layouts/application.html.erb (<head>HERE</head>). Then directly before the closing </body> tag write:

<%= javascript_include_tag 'textarea_init' %>

Additionally you have to add a mark_down specific css file get it from the TextArea project too.

Now you can use it where you like. E.g. in the new template of the comments controller. Within new.html.erb add the following line as the very last:

<div id="markdown_formatted"></div>

But be sure that you specify at least one id for the text content (e.g. like we did: comment_content). See the javascript code section.

That’s it. Hope you enjoy it!

The ruby code 

class WikiText
def initialize(str)
# process umlaute correctly
@text = str.mb_chars
end

def to_html
str, ii = process_sub_tag(nil, 0)
str
end

# returns the resulting string and the processed characters
def process_sub_tag(until_tag_name, from_index)
ii = from_index
if(until_tag_name != nil)
found_tag_index = @text.index(until_tag_name, from_index)
if(found_tag_index != nil)
until_index = found_tag_index + until_tag_name.length
else
return "", 0
end
end
until_index = @text.length if until_index == nil

result = ""
while(ii < until_index)
# F... ruby: '\n' != "\n"
if (@text.at(ii) == "\n")
result << "\n<br />"
ii += 1

elsif check_chars(ii, "'''")
ii += 3
if(until_tag_name == "'''")
break
end
str, p_chars = process_sub_tag("'''", ii)
result << "<b>" + str + "</b>"
ii += p_chars

elsif check_chars(ii, "''")
ii += 2
# closing tag
if(until_tag_name == "''")
break
end
last_index = @text.index("''", ii)
if(last_index != nil)
str, p_chars = process_sub_tag("''", ii)
result << "<i>" + str + "</i>"
ii += p_chars
end

elsif check_chars(ii, "]")
ii += 1
break;

elsif check_chars(ii, "[")
ii += 1
last_index = @text.index("]", ii)
if(last_index != nil)
res = @text[ii, last_index-1].split(' ')
if(res.length > 1 && !res[1].blank?)
ii += res[0].length+1
str, p_chars = process_sub_tag("]", ii)
result << '<a target="_blank" href="'+ res[0]+'">'+str+"</a>"
ii += p_chars
end
end
else
result << @text.at(ii)
ii += 1
end
end
return result, ii - from_index
end

# returns true if the specified chars match directly from the current position
def check_chars(index, chars)
len = chars.length
#if (index > 0 && @text[index-1, 1] == chars.at(0) ||
# index + len < @text.length && @text[index+len, 1] == chars.at(0))
# return false
#end
@text[index, len] == chars
end
end

# WARNING: with unicode it will not work 100%. See the strange assertion at the beginning of the blog post

The JavaScript code


/**
* @author Ryan Johnson <http://saucytiger.com/>
* @copyright 2008 PersonalGrid Corporation <http://personalgrid.com/>
* @package LivePipe UI
* @license MIT
* @url http://livepipe.net/control/textarea
* @require prototype.js, livepipe.js, textarea.js
*/

if(typeof(Control.TextArea) == "undefined")
throw "Initialization requires Control.TextArea to be loaded.";

var idOfComponent = 'comment_content';
if($(idOfComponent) == null) {
idOfComponent = 'concept_content';
}

if($(idOfComponent) != null) {
var textarea = new Control.TextArea(idOfComponent);

var toolbar = new Control.TextArea.ToolBar(textarea);

//for css styles
toolbar.container.id = 'markdown_toolbar';

//buttons
toolbar.addButton('Italics',function(){
this.wrapSelection("''","''");
},{
id: 'markdown_italics_button'
});

toolbar.addButton('Bold',function(){
this.wrapSelection("'''","'''");
},{
id: 'markdown_bold_button'
});

toolbar.addButton('Link',function(){
var selection = this.getSelection();
var response = prompt('Enter Link URL','');
if(response == null)
return;
this.replaceSelection('[' + (response == '' ? 'http://link_url/' : response).
replace(/^(?!(f|ht)tps?:\/\/)/,'http://') + ' ' + (selection == '' ? 'Link Text' : selection) + ']');
},{
id: 'markdown_link_button'
});

toolbar.addButton('Help',function(){
window.open('/documents/wiki_text');
},{
id: 'markdown_help_button'
});
}

Appendix

  • http://www.fckeditor.net/ GPL or MPL or LGPL (image uploading possible) -> http://www.underpantsgnome.com/projects/fckeditor-on-rails/
  • http://dojotoolkit.org/book/dojo-book-0-9/part-2-dijit/advanced-editing-and-display/editor-rich-text BSD or AFL
  • http://www.deveiate.org/projects/BlueCloth text to html
  • http://www.cdolivet.net/editarea/ LGPL
  • http://tinymce.moxiecode.com/ LGPL wordpress uses this. See http://johnwulff.com/articles/2006/05/31/tinymce-with-ruby-on-rails

For more editors look here.

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:

Published at DZone with permission of Peter Karussell. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}