Theme support

Posted on Sat Jul 28 @ 21:50:20

Today I managed to implement a simple theme support for my blog. The result is that now the site has a new look and feel.

The implementation was simple. First I overwritten the template_path class method of ActionController::Base class in my ApplicationController like so:


    class ApplicationController < ActionController::Base
        def self.template_root
          theme = Preference.get('site_theme')
          if theme.size > 0
            "#{RAILS_ROOT}/themes/#{theme}" 
          else
            "#{RAILS_ROOT}/app/views" 
          end
        end
    end

After that I also wrote two helpers that compute the correct path to javascripts and stylesheets for the selected theme. In app/helpers/application_helper.rb I wrote these two methods:


    def theme_stylesheet_link_tag(*styles)
      theme = Preference.get('site_theme')
      if theme.size > 0
        styles.collect do |style|
          source = compute_public_path(style, 
                    "themes/#{theme}/stylesheets", 'css')
          tag("link", {"rel" => 'stylesheet', 
              "type" => 'text/css', 
              "media" => 'screen', "href" => source})
        end
      else
        styles.collect do |style|
          stylesheet_link_tag style
        end
      end
    end

    def theme_javascript_include_tag(*scripts)
      theme = Preference.get('site_theme')
      if theme.size > 0
        scripts.collect do |script|
          source = compute_public_path(script,
                   "themes/#{theme}/javascripts", 'js')
          content_tag("script", "", { "type" => "text/javascript",
                      "src" => source})
        end
      else
        scripts.collect do |script|
          javascript_include_tag script
        end
      end
    end

The Preference.get(‘site_theme’) is a simple implementation of preferences I found looking through the simplelog code. That part of the code can be made more general but for this site it sufficed.

And that was it. Now you can add theme views and layouts in #{RAILS_ROOT}/themes/#{theme} folder and assets in #{RAILS_ROOT}/public/themes/#{theme} folder.

I was aware of theme_support plugin but it needed to be patched to work with rails 1.2.3 and I needed a simpler solution.

I hope someone will find this helpful. I will make a plugin out of this and make it available to the general public.

One last thing. When you change the theme you need to restart your rails application.

Enjoy!

Posted in Rails, 2 Comments Comments

Capistrano deployment on litespeed

Posted on Sun Jul 08 @ 13:37:47

The other day a friend of mine recommended me litespeed web server for rails application instead of the apache, mongrel cluster combination I’ve used. So I listened to him an installed litespeed following these instructions written by PickledOnion.

After the installation I needed to customize my previous capistrano deployment script. I use capistrano 2 for deployment. Here is the code of the script:


    set :application, "munitic.com.hr" 
    set :repository,  "svn://munitic.com.hr/#{application}/trunk" 
    set :deploy_to, "/home/ivica/public_html/#{application}" 
    set :svn_username, 'ivica'

    role :app, "www.munitic.com.hr" 
    role :web, "www.munitic.com.hr" 
    role :db,  "www.munitic.com.hr", :primary => true

    namespace :deploy do
      desc "Restart litespeed web server" 
      task :restart, :roles => :app do
        sudo "/opt/lsws/bin/lswsctrl restart" 
      end

      desc "Start litespeed web server" 
      task :start, :roles => :app do
        sudo "/opt/lsws/bin/lswsctrl start" 
      end

      desc "Stop litespeed server" 
      task :stop, :roles => :app do
        sudo "/opt/lsws/bin/lswsctrl stop" 
      end

      task :after_update, :roles => :app do
        run "ln -s #{shared_path}/photos #{current_path}/public/photos" 
        run "ln -s #{shared_path}/munitic.com.hr.xml 
                   #{current_path}/config/munitic.com.hr.xml" 
        run "ln -s #{shared_path}/.httpasswd 
                   #{current_path}/config/.httpasswd" 
        sudo "chmod -R 2770 /home/ivica/public_html" 
        sudo "chgrp -R www-data /home/ivica/public_html" 
        run "chmod 600 #{current_path}/.msmtprc" 
      end
    end

The main part of the script are the restart, stop, and start tasks. They as their name says restart, stop and start litespeed. I have one additional task called after_update which I use to do some of my custom stuff like linking my gallery photos to /public/photos folder of my application, or linking the configuration file of the litespeed virtual host (munitic.com.hr.xml) and linking the .httpasswd file which is used to enable authorization for awstats. The chmod and chgrp commands are used to ensure that litespeed will have enough permissions to serve my application. The last chmod is to ensure that msmtp program (used to send exception mail via gmails smtp server) which demands that its configuration file (.msmtprc) has 600 permissions has them.

One last thing. To make deploy:web:enable and deploy:web:disable tasks work login into your litespeed administration web site, on the “Configurations” menu choose “Virtual hosts” and click on the virtual host you want to edit. Now click on the Rewrite tab and then click on the “edit” link for Rewrite Control and set Enable Rewrite to yes. Click “save”. After that click “edit” for Rewrite Rules and add these lines:


    RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
    RewriteCond %{SCRIPT_FILENAME} !maintenance.html
    RewriteRule ^.*$ /system/maintenance.html [L]

Click “save”. Now apply the changes and restart the server.

Enjoy!

Posted in Rails, 3 Comments Comments

ActsAsCommentable plugin

Posted on Thu Jul 05 @ 00:56:37

ActsAsCommentable

ActsAsCommentable is an acts_as plugin that is used to enable commenting on your ActiveRecord models. The plugin is intentionally simple because I wanted this plugin to be as customizable as possible without the user ever touching the plugins code.

Installation


    script/plugin install http://svn.munitic.com.hr/plugins/acts_as_commentable

Usage

In the model you want to be commentable add acts_as_commentable


    class Post < ActiveRecord::Base
        acts_as_commentable
        # or if you want to add some methods to the comments association
        # acts_as_commentable do
        #     def find_by_date(date, options = {})
        #         with_scope :find => options do
        #             # CODE GOES HERE
        #         end
        #     end
        # end
        ...
    end

Create the comments table. The only requirement are the commentable_type and commentable_id fields. On my blog I have something like this


  create_table "comments", :force => true do |t|
    t.column "author_name",      :string
    t.column "comment",          :text
    t.column "ip_address",       :string
    t.column "is_spam",          :boolean,  :default => false
    t.column "commentable_type", :string
    t.column "commentable_id",   :integer
    t.column "created_on",       :datetime
  end

If you want to add methods to the comment model you can do this using mixins. Here is what I use:


    module Mixins; module Comment; end; end;
    module Mixins::Comment::Spamable
      def self.included(base)
        base.extend(ClassMethods)
      end

      module ClassMethods
        def count_by_spam(spam)
          count :all, :conditions => ['is_spam = ?', spam]
        end

        def count_by_spam_and_commentable(spam, type, id)
          count :all, :conditions => ['is_spam = ? and 
               commentable_type = ? and commentable_id = ?', 
                   spam, type, id]
        end

        def find_for_post_comments_feed(options = {})
          with_scope :find => options do
            find :all, :conditions => ['is_spam = ? and 
                 commentable_type = ?', false, Post.class_name], 
                 :order => 'created_on DESC'
          end
        end
      end
    end
    Comment.send :include, Mixins::Comment::Spamable
    # If you want to add validation you can do that like this:
    Comment.send :validates_presence_of, :author_name, :comment

I have this code in lib/mixins/spammable.rb and i require it in the config/environment.rb file. After that i have these methods in the comment model.

UPDATE: I’ve moved the code to google. So now you can get the latest version with:


    script/plugin install http://acts-as-commentable.googlecode.com/svn/trunk

Enjoy!

Posted in Rails, 0 Comments Comments

HighlightFu syntax highlighting plugin

Posted on Thu Jul 05 @ 00:27:56

HighlightFu

HighlightFu is a syntax highlighting plugin that adds helper methods to your views. It searches for a <pre lang=”[lang]>[code]</pre> html tag and replaces it with the syntax highlighting code. The syntax highlighting is done using dp.SyntaxHighlighter. I’ve developed HighlightFu because I was not satisfied with the previous syntax highlighting plugin I made.

Installation instructions


    script/plugin install http://svn.munitic.com.hr/plugins/highlight_fu

Usage

  1. run rake highlight_fu:install (this installs all necessary javascripts and stylesheets)
  2. include stylesheets and javascripts with
    <%= highlight_stylesheet_link_tag -%>
    and
    <%= highlight_javascript_include_tag -%>
  3. for the text you want to highlight call the highlight helper
    <%= highlight @post.body -%>
  4. IMPORTANT – at the bottom of the page put the following
    <%= highlight_initialize -%>

UPDATE: I refactored the plugin, especially the private make_options function and merged stylesheet and javascript helper into one called highlight_include_assets. The result is that the code is cleaner and the plugin is easier to use. Now step 2 in the usage paragraph is just one line of code and that is:

<%= highlight_include_assets -%>

UPDATE2: I’ve moved the code to google. So now you can get the latest version with:


    script/plugin install http://highlightfu.googlecode.com/svn/trunk

Posted in Rails, 0 Comments Comments

Syntax highlight plugin using CodeRay

Posted on Sun Jul 01 @ 15:10:45

A couple of days ago I’ve implemented a simple syntax highlighting plugin using CodeRay. It is implemented as an after filter. Here is how you use it. In the controller add the after filter using highlight_coderay.


       class PostController < ApplicationController
           #highlight_with_coderay :only => ['show']
           highlight_with_coderay :except =>
               ['posts_feed','comments_feed',
                'comment_report_spam',
                'add_comment', 'delete_comment']

            ...
        end

After that when you add your content in the html just add <pre lang=”[language]”>[code]</pre> and your done. The after filter will replace this pre tag with the correct highlighting.

You can also customize the style coderay uses by adding this line of code to config/environment.rb:



    SyntaxHighlight::Filters::CodeRay.stylesheet = :bright


There are three styles you can use and they are cycnus, murphy which are part of coderay or bright which is part of the plugin. Also included is a javascript scanner i found here,

Installlation


     script/plugin install http://svn.munitic.com.hr/plugins/syntax_highlight

Enjoy!

UPDATE: I now added helper methods too. So now you can choose if you want to use the after filter or the view helpers. The view helpers are:



    <%= coderay_stylesheet_tag :bright %>


This prints out the stylesheet coderay uses.



    <%= highlight_with_coderay post.body %>


This actually does the highlighting

Posted in Rails, 1 Comments Comments