17 Mar
Posted by dan as Javascript, Ruby on Rails
I discovered Xinha a couple of days ago after coming across this blog post and I was quite impressed with it. After playing around with it a little, I noticed it does not have the same issues with pre tags that both TinyMCE and FCKeditor exhibit variations of. This makes it a good choice if you are displaying a lot of code. The issues deal with replacing new line characters with br tags within pre tags and leads to some display and formatting problems. I wrote about my attempt to wrangle TinyMCE in a previous post. Xinha has not exhibited these issues and the supplied skins look great too.
After my initial testing of Xinha, I decided it would be a good time to finally create a plugin. I started with the TinyMCE plugin and adapted the code to work with Xinha. Since this is my first plugin and some cargo culting was involved, let me quickly remind you that there will most likely be bugs or errors at this point and that not everything is working correctly. That being said, the basics are working and unless you want to use some of the plugins mentioned below, you should not run into too many problems (key words being ’should not’).
To get started, install the plugin and run the rake task with
script/plugin install \
svn://rubyforge.org/var/svn/xinha/trunk
rake xinha:scripts:install
Next thing to do is let your controller know you want to use Xinha. Xinha has some initial setup options and the defaults are set to ‘/javascripts/xinha/’, ‘en’ and ‘blue-look’. If you need to change any of them, they are changed through the setup hash and not through the options hash. The javascript requires _editor_ at the beginning of those variables, but you should not use :_editor_skin to change the skin, just use :skin.
The options hash is where you can change all the other configuration options. Except for the editors and plugins options, the name (hash key) of the option should be the same as the xinha_config.option name but with ruby naming conventions (lowercase and an underscore instead of a space). The value of both the editors and plugins options are an array of strings. Although not technically required, if you don’t specify anything for editors, nothing will happen. Here is an example of what the code in your controller might look like.
uses_xinha(:setup => {
:skin => 'silva' },
:options => {
:editors => ['post_body'],
:plugins => ['Equation','FindReplace','GenericPlugin','GetHtml','HorizontalRule','InsertAnchor','InsertSmiley','SaveSubmit'],
:height => '500px' },
:only => [:new, :edit])
From here, the last thing to do is add the appropriate code to your layout. It couldn’t be simpler, just add
<%= include_xinha_if_used %>
inside the head element. The above snippets load up the editor only for the new and edit actions of my example imaginary post scaffolding. Nothing happens with any of the other actions. All of the javascript, images and css are only loaded when necessary.
I have not had the time to test all of the Xinha plugins. I did uncover a few bugs so I want to mention them briefly. If you load all of the plugins, including the legacy htmlArea plugins, one of them, not sure exactly which one, is nice enough to wrap your text with <html> <head> </head> <body spellcheck=”false” > … </body> </html>. It would appear to be related to spellChecker, but removing that plugin did not appear to fix the problem. Removing all the legacy plugins prevents this from happening and some other random issues. Because of this, I am going to recommend you only use the Xinha specific plugins. If you need to use one of the legacy plugins and get it to work, play nicely and let us know what you did to make it work.
Some of the plugins also utilize php code. The good ole webrick server that loads with script/server does not do so well with those plugins and they are lacking functionality. These plugins are
That list includes some useful plugins and I hope to get at least a few of them working using ruby instead of php. Please don’t hold your breath though, I have no idea how long it will be until I can get any or all of them working. If you would like to help, it would be much appreciated. I set up a rubyforge project for this plugin here. If you find any bugs or have any suggestions, feel free to leave a comment here or use rubyforge.
Another thing to keep in mind, the initial release is at best considered an alpha release and I know there are several things that need to be added before this plugin creates a fully functional Xinha editor for Rails. Unfortunately, if I waited until I figured everything out, this may never have been released period and which is why it is available now for you to try out. This also is my first attempt at a plugin, so if a rookie mistake has been made somewhere along the line, let me know so I can fix it and not look like a noob. Either way, creating a Rails plugin has been a good learning experience and I hope you find it useful, even if not all of it works right away.
It feels like I’m never going to stop writing about restful_authentication. This post is a combination of the previous two (here and here)with the addition of openid. I won’t display any code snippets this time, but just discuss what to expect from the demo app.
First of all, I wanted to add openid support this time around. The railscast is very helpful, but openid has changed to version 2 since then. After looking around, I started my app with this. Since it doesn’t use the acts_as_stateful plugin, I added support for that into the app.
One thing that is not complete, is what happens with the first user. Currently, the first user to sign up will have the role of subscriber, but there are also moderator and administrator roles. I have just been manually editing the db to change the role to administrator. I have looked at a few different ways of accomplishing changing the initial user to an administrator, but have not decided which way I like best and as such, not added that ability just yet. When you are an administrator, you can edit users roles and states through the admin section of the site.
There are a few things to keep in mind about user registration. Users who sign up without an openid, will still sign in initially, but once they sign out, they will have to confirm their account with the activation code that was sent to them. Openid users do not have to activate. Once they sign up, they are active users.
As far as passwords go, users can reset their password if they forget it, and change it when they are logged in. I did not put the code for changing passwords in a settings controller as I did previously, but kept the typical restful form of /users/:id/edit.
There is an administrator section along with the public site. I based the design of the site on this simpla theme and the admin section on this glazed theme. I found this great article and changed all the buttons to look similarly. Unfortunately, it does not use the standard submit_tag. The forms for the site are all styled after uni-forms. Although, not all the color and styling is applied. Overall, it gives the basic site a nice clean look. I might have got carried away with the visuals though, since they are most likely going to change for each person, but for now, it makes it look nicer and easier to work with.
I feel like I’m forgetting to mention a few pieces of pertinent information. When and if I do, I’ll update accordingly. Until then, have fun messing around with restful_authentication and openid. Don’t forget, please let me know of any issues you might run into.
Downloads are available at
Update 3-17-08: my_restful3.17 fixed a few small bugs dealing with the reset_password action and the admin/users view. Thanks for pointing that out Tom. I really need to get svn setup for this….5 minutes later… Damn, just downloaded and tried to setup the app only to fail on the very first step, rake db:migrate. 3.18 removes the add_index :users, [:identity_url] from the users migration and the migration now works
28 Feb
Posted by dan as Ruby on Rails
If your rails apps are placed in one directory and you use a symbolic link to the public folder from your public directory, this info is for you. A hosting company, for example, might have you do this and my host is one of them.
The issue is, after creating the symbolic link, the url just displays a directory listing. I do remember reading about a user having a similar issue, although I have forgotten exactly where, so I decided to write a post about it. If you are in your public_html folder and would like your app to be at the url, example.com/my_app/, when using the command,
ln -s /path/to/my/project/app/public my_app
you need to make sure that the folder, my_app, does not already exist. Otherwise, you will just see a directory listing.
28 Feb
Posted by dan as Javascript, Ruby on Rails
As I went about figuring out how to get some syntax highlighting for my rails apps, I did not think it would turn out to be such a process. I’m not saying the available syntax highlighters are of inferior quality. I just ran into a few problems combining all the pieces I wanted to use.
When I started this out, I wasn’t ( still not really) sure of the best way to get syntax highlighting working with my rails apps. What follows is a quick overview of the hoops I went through to accomplish this and the solution ( or hack might be a better word) I finished with.
The Wordpress editor is a good example of what I wanted to end up with. Server side highlighting via GeSHi or Syntax could be nice, but using them with a text editor for a rails app seems a bit out of reach for me at this point. This left the available Javascript solutions as a better route.
SyntaxHighlighter appeared to be the early winner. With Worpress, its easy, you just press the code button, create the needed pre tags with name=”code” class=”xlang.” For my rails app, I installed the tiny_mce plugin and then realized that the code tab in Wordpress actually switches the editor to a quicktags editor. I set about creating the needed buttons and found the source of the switchEditor function here. After the better part of a day, I finally managed to get the button to work by specifying the exact text area as opposed to the generic textareas option within the uses_tiny_mce options hash in my controller.
Shortly after that, I realized the plugin was using TinyMCE 2.0.8 instead of the latest stable TinyMCE, 3.0.1 as of this writing. Consequently, I never finished with the 2.0 version and moved to running 3.0. Once running, I discovered, the functionality I wanted to implement was already there, albeit in a slightly different fashion. It came in the form of the html source code editor button. This brought about another issue.
SyntaxHighlighter hightlights pre tags based on the name attribute, and the name attribute is not a valid pre tag attribute. Since TinyMCE strips out invalid attributes, my code was not getting highlighted. Keeping everything valid is a priority, so SyntaxHighlighter wasn’t going to work in its current state.
After some investigative work into SyntaxHighlighter, I decided it was not worth the effort to change it to work without the name tag.
Chili steps into the equation for two reasons now, it was really easy to change it to highlight pre tags, and it is a jQuery plugin. All I did was change the ChiliBook.automaticSelector value to “pre” and it seems to do the trick. So far, I haven’t noticed any issues that could be caused by this.
I thought I would be done now, but I was wrong yet again. TinyMCE replaces the new line characters within pre tags with br tags. After Chili completes highlighting code with br tags, what results is one long line of highlighted code. Not exactly usable. The substitution seems to occur when the editor opens up a previously saved record. I did not determine exactly where this was occurring.
Upon consulting the TinyMCE wiki, there appeared to be several configuration options that would do the trick. After going through each of these options, I was still in the same state of displaying incorrectly formatted code. I looked at cleanup_on_startup, convert_newlines_to_brs, remove_linebreaks as well as others. With names like that, you would think one would stop the substitution of new lines to br tags. Eventually, the save_callback method appeared as a way to fix the problem. It did not actually stop the substitution, but it allowed my pages to correctly display code. My save_callback simply calls a replace(/<br\s\/>/g, “\n”) on the returned text. What this means is, my code will now format and display correctly to end users because the brs no longer conflict with Chili. After you have pasted a snippet of code, you never really need to edit the code through the html source code viewer anymore and the brs become an ignorable issue now. The TinyMCE init script end up as the one below.
<script language="javascript" type="text/javascript">
function replace_brs_with_n(element_id, html, body) {
html = html.replace(/
/g, “\n”);
return html;
}
tinyMCE.init({
theme : “advanced”,
mode : “textareas”,
save_callback : “replace_brs_with_n”,
plugins : “visualchars,xhtmlxtras”,
// Theme options
theme_advanced_buttons1 : “bold,italic,underline,strikethrough,|,justifyleft,justifycenter,justifyright,justifyfull,|,styleselect,formatselect,fontselect,fontsizeselect”,
theme_advanced_buttons2 : “bullist,numlist,|,outdent,indent,blockquote,|,undo,redo,|,link,unlink,anchor,image,cleanup,code,|,forecolor,backcolor,|,cite,del,ins,sub,sup”,
theme_advanced_buttons3 : “”,
theme_advanced_buttons4 : “”,
theme_advanced_toolbar_location : “top”,
theme_advanced_toolbar_align : “left”,
theme_advanced_statusbar_location : “bottom”,
theme_advanced_resizing : true,
});
</script>
With the resolution of that issue, the only thing left to do was create the recipes for Chili to highlight both ruby and rails code. My regex skills are lacking as of this point, but I managed to put together some regular expressions and they appear to be doing a decent job. The regular expressions were generated with the help of GeSHi and SyntaxHighlighter.
The way to get syntax highlighted code is to click the html button and manually type in <pre class=”supported language you want”></pre> and paste your code in between. If you save the record and come back later to edit and you use the html editor, you will notice the new lines have been replaced with br tags. Fortunately, most editing can be done from the main editor window just fine. As long as you have included the correct Javascript and css files, your code should be nice and highlighted when being displayed. Please leave any comments, ideas or suggestions below.
24 Feb
Posted by dan as Ruby on Rails, SVN, Shell Scripting
The Deploying Rails Applications book is a good read and if you are new to deploying rails apps, I highly suggest you read it. One of the first things explained is how to correctly setup your rails app and your svn repository. While I have known for awhile that certain files are not supposed to be included within your repositories, I never took the time to really figure out the best way to do it. Thanks to this book, I now know.
I decided to attempt some bash scripting and automate the process. This is one of my first shell scripts and may not be entirely correct. Any feedback would be greatly appreciated. If you have no idea how to create shell scripts, take a look at this, it helped me get started.
Correct usage is ./rails_with_svn.sh svn_repo_path rails_project_path. Since I’m also a wordpress noob, you’ll have to just copy and paste what is below into a file with a .sh extension. I named mine rails_with_svn.sh.
#!/bin/bash # rails_with_svn.sh # This script creates an svn repository at location of first argument # and a rails project at location of second argument # correct usage is ./rails_with_svn.sh svn_repo_path rails_project_path # please report any problems or ideas for improvement to dan@morebs.com # this is one of my first attempts at shell scripting # and I am not responsibly for anything bad that happens if you use it # and I cannot guarantee the correctness of it # Created with the help of # Deploying Rails Applications: A Stet-by-Step Guide by # Ezra Zygmuntowicz and Bruce Tate with Geoffrey Grosenbach # a book available at http://www.pragprog.com/ SUCCESS=0 E_NOARGS=65 if [ -z "$1" ] then echo "Please supply a repository path" exit $E_NOARGS fi if [ -z "$2" ] then echo "Please supply a project path" exit $E_NOARGS fi echo echo "Creating a repository at $1 and rails project at $2" svnadmin create $1 svn mkdir file://$1/trunk file://$1/tags file://$1/branches -m "initial project layout" rails $2 svn checkout file://$1/trunk $2 cd $2 svn add test app tmp log Rakefile script db config doc lib vendor README public svn revert log/* svn propset svn:ignore "*.log" log svn revert config/database.yml mv config/database.yml config/database.yml.sample svn add config/database.yml.sample svn propset svn:ignore "database.yml" config cp config/database.yml.sample config/database.yml svn propset svn:ignore "schema.rb" db svn propset svn:ignore "*" tmp svn propset svn:ignore "*doc" doc svn propset svn:executable "*" `find script -type f | grep -v '.svn'` svn propset svn:executable "*" `find public/dispatch.* script -type f | grep -v '.svn'` svn propset svn:eol-style native public/dispatch.* svn revert public/index.html rm public/index.html svn commit -m "initial project config and checkin" echo "Successfully created your" echo "repository at $1 and" echo "rails project at $2" exit 0
As mentioned above, I can’t guarantee the correctness and am not responsibly for anything bad that might happen because of your use of the script. Of course, any help for improvement would be greatly appreciated.
Technorati Profile Technorati made me do it
I always seem to overlook testing. For one reason or another, it is really easy to forget about. But before getting too far into a project, it is a good idea to make sure you have some tests and that they are passing. Getting the initial tests to pass will be the focus of this post. The problem I have run into with restful_authentication is that the tests have not been updated for rails 2.0. Updating those tests to pass will be the subject of this post.
If you haven’t already, add the line ‘include AuthenticatedTestHelper’ to the bottom of the test/test_helper.rb file.
Before moving on, lets see where we stand with the current test cases. Here are my results
rake
...
...
1) Failure:
test_should_initialize_activation_code_upon_creation(UserTest) [./test/unit/user_test.rb:18]:
24 tests, 42 assertions, 1 failures, 0 errors
Not a bad start. In my first post about restful_authentication, I changed what happens when users create accounts. This tests makes sure there is an activation code after creation, but is not needed now. To solve this, I’m just going to comment out that particular test and create a test that passes when the activation code is nil after creation. The test is almost identical and looks like this
def test_should_not_initialize_activation_code_upon_creation user = create_user assert_nil user.reload.activation_code end
All tests now pass, but we are not finished. Lets add the admin_required filter to the articles controller except for the show and index actions and rerun the tests.
class ArticlesController < ApplicationController before_filter :admin_required, :except => [:index, :show]
rake
...
...
1) Failure:
test_should_create_article(ArticlesControllerTest)
<3> expected but was
<2>.
2) Failure:
test_should_destroy_article(ArticlesControllerTest)
<1> expected but was
<2>.
3) Failure:
test_should_get_edit(ArticlesControllerTest)
Expected response to be a <:success>, but was <302>
4) Failure:
test_should_get_new(ArticlesControllerTest)
Expected response to be a <:success>, but was <302>
5) Failure:
test_should_update_article(ArticlesControllerTest)
expected a redirect to <{"action"=>"index", "controller"=>"articles"}>, found one to <{"action"=>"new", "controller"=>"sessions"}>, a difference of <{"action"=>"new", "controller"=>"sessions"}>
26 tests, 43 assertions, 5 failures, 0 errors
The unit tests still pass, but the functional tests now get 5 failures
From here, the next thing to do is change the restful_authentication test code to the rails 2.0 way. Open up your users fixture and change it to this
quentin: login: quentin email: quentin@example.com salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test created_at: <%= 5.days.ago.to_s :db %> activated_at: <%= 5.days.ago.to_s :db %> state: active role: administrator aaron: login: aaron email: aaron@example.com salt: 7e3041ebc2fc05a40c60028e2c4901a81035d3cd crypted_password: 00742970dc9e6319f8019fd54864d3ea740f04b1 # test created_at: <%= 1.days.ago.to_s :db %> activated_at: <%= 1.days.ago.to_s :db %> state: active role: subscriber
All I did was delete the id and activation code. Next thing to do is modify the sessions and users controller test files. The tests themselves to not need to be changed, just the top portion. Posted below is what your edited files will look like through the first test. As you can see, all the stuff that rails now does automatically has been removed and the controller tests changed from Test::Unit::TestCase to ActionController::TestCase.
# test/functional/users_controller_test.rb
require File.dirname(__FILE__) + '/../test_helper'
class UsersControllerTest < ActionController::TestCase
def test_should_allow_signup
assert_difference 'User.count' do
create_user
assert_response :redirect
end
end
# test/functional/sessions_controller_test.rb
require File.dirname(__FILE__) + '/../test_helper'
class SessionsControllerTest < ActionController::TestCase
def test_should_login_and_redirect
post :create, :login => 'quentin', :password => 'test'
assert session[:user_id]
assert_response :redirect
end
For our articles tests, we now need to login_as :quentin for the tests that require admin privileges. Add that line to the top of the five test cases that require admin privileges and all those tests pass. The only test that fails now is the the test_should_activate_user(UsersControllerTest), but like the first test failure, is not needed anymore.
It might also be a good idea to add in the tests that make sure users can’t do things without the required privileges. Here are the five I added to make sure only authorized users can create and edit articles
def test_should_not_get_new
get :new
assert_redirected_to login_path
end
def test_should_not_create_article
assert_difference('Article.count', 0) do
post :create, :article => { :title => "title one", :body => "body one" }
end
end
def test_should_not_get_edit
get :edit, :id => articles(:one).id
assert_redirected_to login_path
end
def test_should_not_update_article
put :update, :id => articles(:one).id, :article => {:title => "this is the new title"}
assert_redirected_to login_path
end
def test_should_not_destroy_article
assert_difference('Article.count', 0) do
delete :destroy, :id => articles(:one).id
end
assert_redirected_to login_path
end
Of course, it is a good idea to make sure only admins can create and edit articles and that subscribers cannot. That will be left for you when you to complete.
Since I’ve been trying to keep this discussion to restful_authentication, I haven’t really touched on the articles model. I just want to mention though, I am making the assumption that an article model will always need a title and body. Because of this, I added the validates_presence_of :title, :body line to my model.
That should be enough to get your tests passing. Eventually, this info will be obsolete, but until then, this should help.