<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>munitic.com.hr blog</title>
  <link href="http://www.munitic.com.hr/syndication/feeds/posts" rel="self"/>
  <link href="http://www.munitic.com.hr/articles" rel="alternate"/>
  <id>http://www.munitic.com.hr/articles</id>
  <updated>2007-07-05T20:41:07Z</updated>
  <author>
    <name>Ivica Munitic</name>
  </author>
  <entry>
    <title>MetaWeblog API, Exception Notifier</title>
    <link href="http://www.munitic.com.hr/2007/4/29/metaweblog-api-exception-notifier" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/4/29/metaweblog-api-exception-notifier</id>
    <updated>2007-07-05T20:41:07Z</updated>
    <author>
      <name/>
    </author>
    <summary>MetaWeblog API, Exception Notifier</summary>
    <content type="html">
&lt;p&gt;Just today I implemented the MetaWeblog &lt;span class="caps"&gt;API&lt;/span&gt; for this blog and this post was published using &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1730"&gt;ScribeFire&lt;/a&gt; plugin for Firefox. I followed the instructions from this &lt;a href="http://blogs.thewehners.net/josh/view/250"&gt;blog&lt;/a&gt; post. It was really easy to follow the instructions and implement it into my custom blog. The only problem I&amp;#8217;ve had was that I have a model named Category and because of that I had to change the Category ActionWebService::Struct name (I&amp;#8217;ve used AWSCategory :).&lt;/p&gt;


	&lt;p&gt;A week or so ago I also implemented exception notification. Now every time an exception is raised inside my blog a mail is sent to me with the remote ip, user agent, url and the exception backtrace. Because of this I was able to fix some url bugs I didn&amp;#8217;t noticed at first.&lt;/p&gt;


	&lt;p&gt;As for my injury I&amp;#8217;m now fine and my foot has recovered. I still feel some small pain but the doctor said it will pass in a couple of days. For now I will not play any football or cageball, but I will do cycling if the weather permits it.&lt;/p&gt;


&lt;strong&gt;Update:&lt;/strong&gt;
	&lt;p&gt;I&amp;#8217;ve replaced acts_as_attachment plugin with &lt;a href="http://svn.techno-weenie.net/projects/plugins/attachment_fu/"&gt;attachment_fu&lt;/a&gt;. I only needed to replace &lt;em&gt;acts_as_attachment&lt;/em&gt; with &lt;em&gt;has_attachment&lt;/em&gt; in the model and move the &lt;em&gt;public/#{table_name}/#{photo.id}&lt;/em&gt; folders to &lt;em&gt;public/#{table_name}/0000/00#{photo.id}/&lt;/em&gt; folders because of some changes in the attachment_fu namely this from &lt;em&gt;file_system_backend.rb:36&lt;/em&gt; in the backends folder of the attachment_fu plugin:&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;
    def partitioned_path(*args)
        ("%08d" % attachment_path_id).scan(/..../) + args
    end
&lt;/code&gt;
&lt;/pre&gt;    </content>
  </entry>
  <entry>
    <title>Comments feed, looking for ideas</title>
    <link href="http://www.munitic.com.hr/2007/5/17/comments-feed-looking-for-ideas" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/5/17/comments-feed-looking-for-ideas</id>
    <updated>2007-07-28T16:49:34Z</updated>
    <author>
      <name/>
    </author>
    <summary>Comments feed, looking for ideas</summary>
    <content type="html">
&lt;p&gt;Today I managed to implement &lt;a href="http://www.munitic.com.hr/syndication/feeds/comments"&gt;comments feed&lt;/a&gt; for the blog in about 5 minutes including deployment and mongrel cluster restart :) Now I&amp;#8217;m looking for ideas what to implement next. If you have any suggestions please do drop a comment.&lt;/p&gt;


	&lt;p&gt;This adventure of learning rails by coding my own blog is really going well. Any comments are welcomed. I&amp;#8217;m quite happy with the results so far. I&amp;#8217;m also satisfied with the ease of development using rails and the wealth of plugins it has.&lt;/p&gt;


	&lt;p&gt;Now it would be really nice if I could use it on the job, but that wont happen simply because my firm is M$ only. Well thats life. It sucks I know :) Rails is so much more fun to code with. Testing with rails is simpler and better integrated than in &lt;span class="caps"&gt;ASP&lt;/span&gt;.NET. Also the code is shorter and more to the point and beautiful. All in all it as pure joy to code this blog engine of mine and I&amp;#8217;ll continue to do so until I run out of ideas :)&lt;/p&gt;


	&lt;p&gt;As I said before, any comments, ideas are welcomed.&lt;/p&gt;&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Finally capistrano deployment</title>
    <link href="http://www.munitic.com.hr/2007/6/21/finally-capistrano-deployment" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/6/21/finally-capistrano-deployment</id>
    <updated>2007-07-05T20:35:45Z</updated>
    <author>
      <name/>
    </author>
    <summary>Finally capistrano deployment</summary>
    <content type="html">
&lt;p&gt;Today I managed to get capistrano deployment finished. I&amp;#8217;ve never used capistrano before and it took me a few hours to set it up but at the end I managed it. :)&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;m using &lt;a href="http://baazar-vcs.org"&gt;bzr&lt;/a&gt; as my &lt;span class="caps"&gt;VCS&lt;/span&gt; and &lt;a href="http://mongrel.rubyforge.org/docs/mongrel_cluster.html"&gt;mongrel_cluster&lt;/a&gt; behind &lt;a href="http://nginx.net"&gt;nginx&lt;/a&gt; as web server so I had to customize the config/deploy.rb script. Also I&amp;#8217;m using capistrano 2.0. Here is my config/deploy.rb:&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;
    set :application, "munitic.com.hr" 
    set :repository,  "/opt/repo_mirror/#{application}" 
    set :deploy_to, "/var/www/apps/#{application}" 
    set :scm, :bzr
    set :checkout, "branch" 

    role :app, "www.munitic.com.hr" 
    role :web, "www.munitic.com.hr" 
    role :db,  "www.munitic.com.hr", :primary =&amp;gt; true

    namespace :deploy do
      desc "Restart mongrel cluster" 
      task :restart, :roles =&amp;gt; :app do
        run &amp;lt;&amp;lt;-CMD
          cd #{current_path} &amp;#38;&amp;#38;
          mongrel_rails cluster::restart
        CMD
      end

      task :start, :roles =&amp;gt; :app do
        run &amp;lt;&amp;lt;-CMD
          cd #{current_path} &amp;#38;&amp;#38;
          mongrel_rails cluster::start
        CMD
      end

      task :stop, :roles =&amp;gt; :app do
        run &amp;lt;&amp;lt;-CMD
          cd #{current_path} &amp;#38;&amp;#38;
          mongrel_rails cluster::stop
        CMD
      end
      task :before_update_code do
        `bzr push sftp://munitic.com.hr/opt/repo_mirror/#{application}`
      end

      task :after_update, :roles =&amp;gt; :app do
        run "ln -s /var/www/apps/#{application}/shared/photos 
              #{current_path}/public/photos" 
      end
    end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;I&amp;#8217;ve used tips from &lt;a href="http://times.usefulinc.com/2006/09/29-rails-bzr"&gt;here&lt;/a&gt;. I hope this helps someone!&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Syntax highlight plugin using CodeRay</title>
    <link href="http://www.munitic.com.hr/2007/7/1/syntax-highlight-plugin-using-coderay" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/7/1/syntax-highlight-plugin-using-coderay</id>
    <updated>2007-11-24T13:50:04Z</updated>
    <author>
      <name/>
    </author>
    <summary>Syntax highlight plugin using CodeRay</summary>
    <content type="html">
&lt;p&gt;A couple of days ago I&amp;#8217;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.&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;
       class PostController &amp;lt; ApplicationController
           #highlight_with_coderay :only =&amp;gt; ['show']
           highlight_with_coderay :except =&amp;gt;
               ['posts_feed','comments_feed',
                'comment_report_spam',
                'add_comment', 'delete_comment']

            ...
        end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;After that when you add your content in the html just add &lt;em&gt;&amp;lt;pre lang=&amp;#8221;[language]&amp;#8221;&amp;gt;[code]&amp;lt;/pre&amp;gt;&lt;/em&gt; and your done. The after filter will replace this pre tag with the correct highlighting.&lt;/p&gt;


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


&lt;pre&gt;
&lt;code class="ruby"&gt;

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

&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;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 &lt;a href="http://pastie.textmate.org/50774"&gt;here&lt;/a&gt;,&lt;/p&gt;


	&lt;h4&gt;Installlation&lt;/h4&gt;


&lt;pre&gt;
&lt;code&gt;
     script/plugin install http://svn.munitic.com.hr/plugins/syntax_highlight
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Enjoy!&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt; 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:&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;

    &amp;lt;%= coderay_stylesheet_tag :bright %&amp;gt;

&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;This prints out the stylesheet coderay uses.&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;

    &amp;lt;%= highlight_with_coderay post.body %&amp;gt;

&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;This actually does the highlighting&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>HighlightFu syntax highlighting plugin</title>
    <link href="http://www.munitic.com.hr/2007/7/5/highlightfu-syntax-highlighting-plugin" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/7/5/highlightfu-syntax-highlighting-plugin</id>
    <updated>2007-11-24T13:49:39Z</updated>
    <author>
      <name/>
    </author>
    <summary>HighlightFu syntax highlighting plugin</summary>
    <content type="html">
&lt;h4&gt;HighlightFu&lt;/h4&gt;


	&lt;p&gt;HighlightFu is a syntax highlighting plugin that adds helper methods to your views. It searches for a &amp;lt;pre lang=&amp;#8221;[lang]&amp;gt;[code]&amp;lt;/pre&amp;gt; html tag and replaces it with the syntax highlighting code. The syntax highlighting is done using &lt;a href="http://code.google.com/p/syntaxhighlighter/"&gt;dp.SyntaxHighlighter&lt;/a&gt;. I&amp;#8217;ve developed HighlightFu because I was not satisfied with the previous syntax highlighting plugin I made.&lt;/p&gt;


	&lt;h4&gt;Installation instructions&lt;/h4&gt;


&lt;pre&gt;
&lt;code&gt;
    script/plugin install http://svn.munitic.com.hr/plugins/highlight_fu
&lt;/code&gt;
&lt;/pre&gt;

	&lt;h4&gt;Usage&lt;/h4&gt;


	&lt;ol&gt;
	&lt;li&gt;run rake highlight_fu:install (this installs all necessary javascripts and stylesheets)&lt;/li&gt;
		&lt;li&gt;include stylesheets and javascripts with &lt;pre&gt;&lt;code class="ruby"&gt;&amp;lt;%= highlight_stylesheet_link_tag -%&amp;gt;&lt;/code&gt;&lt;/pre&gt; and &lt;pre&gt;&lt;code class="ruby"&gt;&amp;lt;%= highlight_javascript_include_tag -%&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;for the text you want to highlight call the highlight helper &lt;pre&gt;&lt;code class="ruby"&gt;&amp;lt;%= highlight @post.body -%&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;&lt;span class="caps"&gt;IMPORTANT&lt;/span&gt;&lt;/strong&gt; &amp;#8211; at the bottom of the page put the following &lt;pre&gt;&lt;code class="ruby"&gt;&amp;lt;%= highlight_initialize -%&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt;
I refactored the plugin, especially the private &lt;em&gt;make_options&lt;/em&gt; function and merged stylesheet and javascript helper into one called &lt;em&gt;highlight_include_assets&lt;/em&gt;. 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: &lt;pre&gt;&lt;code class="ruby"&gt;&amp;lt;%= highlight_include_assets -%&amp;gt;&lt;/code&gt;&lt;/pre&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE2&lt;/span&gt;:&lt;/strong&gt;
I&amp;#8217;ve moved the code to google. So now you can get the latest version with:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
    script/plugin install http://highlightfu.googlecode.com/svn/trunk
&lt;/code&gt;
&lt;/pre&gt;    </content>
  </entry>
  <entry>
    <title>ActsAsCommentable plugin</title>
    <link href="http://www.munitic.com.hr/2007/7/5/actsascommentable-plugin" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/7/5/actsascommentable-plugin</id>
    <updated>2007-11-24T13:50:51Z</updated>
    <author>
      <name/>
    </author>
    <summary>ActsAsCommentable plugin</summary>
    <content type="html">
&lt;h4&gt;ActsAsCommentable&lt;/h4&gt;


	&lt;p&gt;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.&lt;/p&gt;


	&lt;h4&gt;Installation&lt;/h4&gt;


&lt;pre&gt;
&lt;code&gt;
    script/plugin install http://svn.munitic.com.hr/plugins/acts_as_commentable
&lt;/code&gt;
&lt;/pre&gt;

	&lt;h4&gt;Usage&lt;/h4&gt;


	&lt;p&gt;In the model you want to be commentable add acts_as_commentable&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;
    class Post &amp;lt; 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 =&amp;gt; options do
        #             # CODE GOES HERE
        #         end
        #     end
        # end
        ...
    end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Create the comments table. The only requirement are the commentable_type and commentable_id fields. On my blog I have something like this&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;
  create_table "comments", :force =&amp;gt; true do |t|
    t.column "author_name",      :string
    t.column "comment",          :text
    t.column "ip_address",       :string
    t.column "is_spam",          :boolean,  :default =&amp;gt; false
    t.column "commentable_type", :string
    t.column "commentable_id",   :integer
    t.column "created_on",       :datetime
  end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;If you want to add methods to the comment model you can do this using mixins. Here is what I use:&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;
    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 =&amp;gt; ['is_spam = ?', spam]
        end

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

        def find_for_post_comments_feed(options = {})
          with_scope :find =&amp;gt; options do
            find :all, :conditions =&amp;gt; ['is_spam = ? and 
                 commentable_type = ?', false, Post.class_name], 
                 :order =&amp;gt; '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
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;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.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt;
I&amp;#8217;ve moved the code to google. So now you can get the latest version with:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
    script/plugin install http://acts-as-commentable.googlecode.com/svn/trunk
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Enjoy!&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Capistrano deployment on litespeed</title>
    <link href="http://www.munitic.com.hr/2007/7/8/capistrano-deployment-on-litespeed" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/7/8/capistrano-deployment-on-litespeed</id>
    <updated>2007-07-28T16:32:36Z</updated>
    <author>
      <name/>
    </author>
    <summary>Capistrano deployment on litespeed</summary>
    <content type="html">
&lt;p&gt;The other day a friend of mine recommended me &lt;a href="http://litespeedtech.com/"&gt;litespeed&lt;/a&gt; web server for rails application instead
of the apache, mongrel cluster combination I&amp;#8217;ve used. So I listened to him an installed litespeed 
following &lt;a href="http://www.usefuljaja.com/litespeed"&gt;these&lt;/a&gt; instructions written by PickledOnion.&lt;/p&gt;


	&lt;p&gt;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:&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;
    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 =&amp;gt; true

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

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

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

      task :after_update, :roles =&amp;gt; :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
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;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.&lt;/p&gt;


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


&lt;pre&gt;
&lt;code&gt;
    RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f
    RewriteCond %{SCRIPT_FILENAME} !maintenance.html
    RewriteRule ^.*$ /system/maintenance.html [L]
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Click &amp;#8220;save&amp;#8221;. Now apply the changes and restart the server.&lt;/p&gt;


	&lt;p&gt;Enjoy!&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Theme support</title>
    <link href="http://www.munitic.com.hr/2007/7/28/theme-support" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/7/28/theme-support</id>
    <updated>2007-07-28T23:24:33Z</updated>
    <author>
      <name/>
    </author>
    <summary>Theme support</summary>
    <content type="html">
&lt;p&gt;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.&lt;/p&gt;


	&lt;p&gt;The implementation was simple. First I overwritten the template_path  class method of ActionController::Base class in my ApplicationController like so:&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;
    class ApplicationController &amp;lt; ActionController::Base
        def self.template_root
          theme = Preference.get('site_theme')
          if theme.size &amp;gt; 0
            "#{RAILS_ROOT}/themes/#{theme}" 
          else
            "#{RAILS_ROOT}/app/views" 
          end
        end
    end
&lt;/code&gt;
&lt;/pre&gt; 

	&lt;p&gt;After that I also wrote two helpers that compute the correct path to javascripts and stylesheets for the selected theme. In &lt;em&gt;&lt;strong&gt;app/helpers/application_helper.rb&lt;/strong&gt;&lt;/em&gt; I wrote these two methods:&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;
    def theme_stylesheet_link_tag(*styles)
      theme = Preference.get('site_theme')
      if theme.size &amp;gt; 0
        styles.collect do |style|
          source = compute_public_path(style, 
                    "themes/#{theme}/stylesheets", 'css')
          tag("link", {"rel" =&amp;gt; 'stylesheet', 
              "type" =&amp;gt; 'text/css', 
              "media" =&amp;gt; 'screen', "href" =&amp;gt; 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 &amp;gt; 0
        scripts.collect do |script|
          source = compute_public_path(script,
                   "themes/#{theme}/javascripts", 'js')
          content_tag("script", "", { "type" =&amp;gt; "text/javascript",
                      "src" =&amp;gt; source})
        end
      else
        scripts.collect do |script|
          javascript_include_tag script
        end
      end
    end
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;The &lt;strong&gt;&lt;em&gt;Preference.get(&amp;#8216;site_theme&amp;#8217;)&lt;/em&gt;&lt;/strong&gt; is a simple implementation of preferences I found looking through the &lt;a href="http://www.simplelog.net"&gt;simplelog code&lt;/a&gt;. That part of the code can be made more general but for this site it sufficed.&lt;/p&gt;


	&lt;p&gt;And that was it. Now you can add theme views and layouts in &lt;em&gt;&lt;strong&gt;#{RAILS_ROOT}/themes/#{theme}&lt;/strong&gt;&lt;/em&gt; folder and assets in  &lt;em&gt;&lt;strong&gt;#{RAILS_ROOT}/public/themes/#{theme}&lt;/strong&gt;&lt;/em&gt; folder.&lt;/p&gt;


	&lt;p&gt;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.&lt;/p&gt;


	&lt;p&gt;I hope someone will find this helpful. I will make a plugin out of this and make it available to the general public.&lt;/p&gt;


	&lt;p&gt;One last thing. When you change the theme you need to restart your rails application.&lt;/p&gt;


	&lt;p&gt;Enjoy!&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Book: Programming Erlang</title>
    <link href="http://www.munitic.com.hr/2007/8/21/book-programming-erlang" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/8/21/book-programming-erlang</id>
    <updated>2007-08-22T23:07:51Z</updated>
    <author>
      <name/>
    </author>
    <summary>Book: Programming Erlang</summary>
    <content type="html">
&lt;p&gt;I&amp;#8217;ve started reading the &lt;a href="http://www.pragmaticprogrammer.com/titles/jaerlang"&gt;Programming Erlang&lt;/a&gt; book by Joe Armstrong.
I&amp;#8217;ve learned about the existence of Erlang about a year or two ago when I was looking into learning a functional language.&lt;/p&gt;


	&lt;p&gt;I tried Haskell, Ocaml and Erlang (I didn&amp;#8217;t tried Lisp purely on aesthetics issues &amp;#8211; i don&amp;#8217;t like too many parenthesis :) ). After a while with those languages i choose Erlang as my functional language to learn. Haskell learning curve was too steep, and in Ocaml i didn&amp;#8217;t like the syntax.&lt;/p&gt;


	&lt;p&gt;So when the beta of the Erlang book was announced I bought it. And now after I have some spare time I started reading it. The book is really easy to read. Joe did a fantastic job of explaining Erlang in simple words. I recommend to all of you who have a desire to learn a functional language to give Erlang a try.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt;
The reasons for choosing Erlang are totally subjective and by no mean am I saying that either Haskell or Ocaml are bad languages. I&amp;#8217;m just saying that I liked Erlang more. The same goes for Lisp.&lt;/p&gt;


	&lt;p&gt;Enjoy!&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Life &amp; Erlang</title>
    <link href="http://www.munitic.com.hr/2007/10/5/life-erlang" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/10/5/life-erlang</id>
    <updated>2007-10-06T00:49:33Z</updated>
    <author>
      <name/>
    </author>
    <summary>Life &amp; Erlang</summary>
    <content type="html">
&lt;p&gt;This past month or two I was preoccupied with collecting necessary documents to raise a loan at the bank to buy a flat. I&amp;#8217;m planning to  go live with my girlfriend/future wife in a small town called Solin near Split (Croatia). So all my free time was spent collecting those documents . I only need to get one more document and then I&amp;#8217;m going to the bank for that loan.&lt;/p&gt;


	&lt;p&gt;I haven&amp;#8217;t had much time to program anything in my free time. I am  reading &amp;#8220;Programming Erlang&amp;#8221; very slowly though, half a chapter every 3 to 5 days. I must say I&amp;#8217;m enjoying it, and I already have some ideas about projects. One idea would be to develop a ejabberd module which integrates with &lt;a href="http://trac.edgewall.org/"&gt;trac&lt;/a&gt;. The integration would mean a developer could add, edit, list tickets, attach files to tickets and comment on tickets using his or hers IM client.&lt;/p&gt;


	&lt;p&gt;To enable this integration the IM client would need to know how to use it so I&amp;#8217;m planning to write a &lt;a href="http://www.pidgin.im/"&gt;pidgin&lt;/a&gt; plugin also. For now ejabberd and trac will need to live on the same machine because I intend to write a simple port program in python using trac &lt;span class="caps"&gt;API&lt;/span&gt;.&lt;/p&gt;


	&lt;p&gt;If you have any useful comments please do comment :)&lt;/p&gt;


	&lt;p&gt;Enjoy!&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Refactored comment management</title>
    <link href="http://www.munitic.com.hr/2007/11/10/refactored-comment-managment" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/11/10/refactored-comment-managment</id>
    <updated>2007-11-10T15:21:42Z</updated>
    <author>
      <name/>
    </author>
    <summary>Refactored comment management</summary>
    <content type="html">
&lt;p&gt;I&amp;#8217;ve finally got some time to work on my blog application. I always wanted to remove duplicate code for comment management from the post controller and photo controller. So today I sat down and extracted common code form both controllers and &amp;#8220;CommentController&amp;#8221; was born.&lt;/p&gt;


	&lt;p&gt;Here is the code if you are curious.&lt;/p&gt;


&lt;pre&gt;
&lt;code class="ruby"&gt;
class CommentController &amp;lt; ApplicationController
    include Akismet

    def add_comment
        if request.post?
           params[:comment][:ip_address] = request.remote_ip
           comment = Comment.new(params[:comment])
           commentable_type = find_commentable_type(
                                  comment.commentable_type, 
                                  comment.commentable_id)
           if comment.valid?
             params[:comment][:is_spam] = 
                      comment_is_spam?(comment)
             commentable_type.comments.create(params[:comment])
           end
        end

        count = comment.errors.count
        unless count == 0
         flash[:errors] = comment.errors.full_messages.join('|')
        end

        redirect_to_commentable_type(commentable_type)
    end

    def delete_comment
        if request.post?
            comment = Comment.find(params[:id])
            comment.destroy
        end
        redirect_to_commentable_type(
               find_commentable_type(comment.commentable_type,
                            params[:commentable_id].to_i))
    end

    def comment_report_spam
        comment = Comment.find(params[:id])
        comment.is_spam = true
        comment.save
        submit_spam(:comment_author =&amp;gt; comment.author_name,
                    :comment_content =&amp;gt; comment.comment,
                    :user_ip =&amp;gt; comment.ip_address,
                    :user_agent =&amp;gt; request.user_agent,
                    :referer =&amp;gt; request.env['HTTP_REFERER'])

        redirect_to_commentable_type(
              find_commentable_type(comment.commentable_type,
                                    comment.commentable_id))
    end

   protected
   def comment_is_spam?(comment)
     is_spam?(:comment_author =&amp;gt; comment.author_name,
              :comment_content =&amp;gt; comment.comment,
              :user_ip =&amp;gt; comment.ip_address,
              :user_agent =&amp;gt; request.user_agent,
              :referrer =&amp;gt; request.env['HTTP_REFERER'])
   end

    private
    def find_commentable_type(commentable_type, commentable_id)
        case commentable_type
        when Post.class_name
            result = Post.find(commentable_id)
        when Photo.class_name
            result = Photo.find(commentable_id)
        else
            throw "Wrong commentable type" 
        end
        result
    end

    def redirect_to_commentable_type(commentable_type)
        case commentable_type.class.class_name
        when Post.class_name
            redirect_to article_comments_url(commentable_type)
        when Photo.class_name
            redirect_to :action =&amp;gt; "show_comments", 
                        :controller =&amp;gt; "photo", 
                        :id =&amp;gt; commentable_type
        else
            throw "Wrong commentable type" 
        end
    end

    def article_comments_url(post)
        "#{article_url(:year =&amp;gt; post.created_on.year,
                       :month =&amp;gt; post.created_on.month, 
                       :day =&amp;gt; post.created_on.day,
                       :permalink =&amp;gt; post.permalink)
        }#comment_form" 
    end 
end
&lt;/code&gt; 
&lt;/pre&gt;    </content>
  </entry>
  <entry>
    <title>Windsor container</title>
    <link href="http://www.munitic.com.hr/2007/12/19/windosr-container" rel="alternate"/>
    <id>http://www.munitic.com.hr/2007/12/19/windosr-container</id>
    <updated>2007-12-19T23:39:28Z</updated>
    <author>
      <name/>
    </author>
    <summary>Windsor container</summary>
    <content type="html">
&lt;p&gt;At work I&amp;#8217;ve been looking at &lt;a href="http://www.castleproject.org/container/index.html"&gt;Windsor container&lt;/a&gt; and I must say it is a excellent peace of software. I don&amp;#8217;t know how was I able to do my work properly without it thus far. I&amp;#8217;m now preparing a series of 2 or 3 posts on my company &lt;a href="http://blog.netmedia.hr"&gt;blog site&lt;/a&gt; explaining how to use it and what are the benefits of using it.&lt;/p&gt;


	&lt;p&gt;I absolutely suggest to every .NET programmers out there to look at Windsor. It will save you time &amp;#38; money. Windsor helps you solve your object dependencies. If for example object A depends on object B (B is passed to A through the constructor) Windsor if properly configured can resolve that dependency when asking him to give you and instance of object A.&lt;/p&gt;


	&lt;p&gt;You can also configure him to give you a specific implementation of an interface. Then you can develop a different implementation of that interface (if your client asks) and replace the old implementation with the new one without ever recompiling the application. You just change the configuration to point to the new implementation.&lt;/p&gt;


	&lt;p&gt;There is a lot more to Windsor than this and because of that I invite you to read about it on the &lt;a href="http://www.castleproject.org/container/index.html"&gt;Windsor&lt;/a&gt; site.&lt;/p&gt;


	&lt;p&gt;Enjoy!&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Moved to webfaction</title>
    <link href="http://www.munitic.com.hr/2008/1/4/moved-to-webfaction" rel="alternate"/>
    <id>http://www.munitic.com.hr/2008/1/4/moved-to-webfaction</id>
    <updated>2008-01-04T16:09:00Z</updated>
    <author>
      <name/>
    </author>
    <summary>Moved to webfaction</summary>
    <content type="html">
&lt;p&gt;As of today my blog is now hosted on &lt;a href="http://www.webfaction.com"&gt;webfaction&lt;/a&gt;. I did this because I recently bought an apartment and now I don&amp;#8217;t have enough finances for a 38$ 512MB &lt;span class="caps"&gt;VPS&lt;/span&gt; :(. But I hope this is just temporary.&lt;/p&gt;


	&lt;p&gt;Still webfaction is an excellent shared hosting. You get a shell account and the control panel is awesome. Django, Rails, WordPress, Trac, Subversion, Zope, Plone, TurboGears setups are just a few clicks away for just 9.5$ a month.&lt;/p&gt;


	&lt;p&gt;Enjoy!&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>User group Rails 2.0 presentation</title>
    <link href="http://www.munitic.com.hr/2008/2/22/user-group-rails-2-0-presentation" rel="alternate"/>
    <id>http://www.munitic.com.hr/2008/2/22/user-group-rails-2-0-presentation</id>
    <updated>2008-02-22T06:50:45Z</updated>
    <author>
      <name/>
    </author>
    <summary>User group Rails 2.0 presentation</summary>
    <content type="html">
&lt;p&gt;Yesterday (21.02.2008) I&amp;#8217;ve gave a rather unusual talk about Rails 2.0 for the &lt;a href="http://softdevnet.blog.hr"&gt;SoftDevNet User Group&lt;/a&gt;. The event was held in a Irish pub called &lt;em&gt;&amp;#8220;Harpo&amp;#8221;&lt;/em&gt;. Beside us geeks the pub was full of people that had no interest in listening to a bunch of geeks talking gibberish.&lt;/p&gt;


	&lt;p&gt;The talk went good and I think people actually listening to what I was saying were satisfied. I just regret I wasn&amp;#8217;t able to finish the presentation with the testing &amp;#38; deployment demo because the laptop died suddenly (not mine and windows based) and it was already   11:30 PM.&lt;/p&gt;


	&lt;p&gt;All in all it was enjoyable!&lt;/p&gt;


	&lt;p&gt;Enjoy!&lt;/p&gt;    </content>
  </entry>
  <entry>
    <title>Painting the appartment, developing a new blog app for the site</title>
    <link href="http://www.munitic.com.hr/2008/4/1/painting-the-appartment-developing-new-blog" rel="alternate"/>
    <id>http://www.munitic.com.hr/2008/4/1/painting-the-appartment-developing-new-blog</id>
    <updated>2008-04-01T06:23:47Z</updated>
    <author>
      <name/>
    </author>
    <summary>Painting the appartment, developing a new blog app for the site</summary>
    <content type="html">
&lt;p&gt;I&amp;#8217;m in the middle of painting the walls of my kitchen at home and at the same time I&amp;#8217;m working on a new blog app for this site. Because I&amp;#8217;m now on a shared host the new blog app will be php based.I will use &lt;a href="http://www.cakephp.org"&gt;CakePHP&lt;/a&gt;. I also registered on &lt;a href="http://www.twitter.com"&gt;Twitter&lt;/a&gt; and my page is &lt;a href="http://twitter.com/imunitic"&gt;http://twitter.com/imunitic&lt;/a&gt;. You will also be able to see my twitts on the new blog when I deploy it. Comments on the new blog will be managed by &lt;a href="http://www.disqus.com"&gt;&lt;span class="caps"&gt;DISQUS&lt;/span&gt;&lt;/a&gt;. The about me sidebar on the new blog  uses &lt;a href="http://microformats.org/wiki/hcard"&gt;hCard&lt;/a&gt; micro format.&lt;/p&gt;


	&lt;p&gt;Now back to the painting part. It was really a fun job painting the kitchen in the middle of the night not knowing how will the color you just mixed look tomorrow morning when the sun hits the walls :)  When I and my girlfriend woke up this morning and looked at the kitchen walls we were happy. The color is orange and we like it how it looks.&lt;/p&gt;


	&lt;p&gt;I think this will be my last blog entry using the old system. I still have to come up with a way of importing the old blog posts into the new system. For the comments (which are not very numerous) I already decided that I won&amp;#8217;t import them into the new system.&lt;/p&gt;


	&lt;p&gt;That is it for now.&lt;/p&gt;


	&lt;p&gt;Enjoy!&lt;/p&gt;    </content>
  </entry>
</feed>
