<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>source.mihelac.org - Home</title>
  <id>tag:source.mihelac.org,2008:mephisto/</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://source.mihelac.org/feed/articles.xml" rel="self" type="application/atom+xml"/>
  <link href="http://source.mihelac.org/" rel="alternate" type="text/html"/>
  <updated>2008-07-01T13:15:48Z</updated>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2008-07-01:3541</id>
    <published>2008-07-01T13:15:00Z</published>
    <updated>2008-07-01T13:15:48Z</updated>
    <link href="http://source.mihelac.org/2008/7/1/programmable-screencasts" rel="alternate" type="text/html"/>
    <title>Programmable screencasts</title>
<content type="html">
            &lt;p&gt;Here is screencast, how &lt;a href=&quot;http://drupal.org/project/gmaplocation&quot;&gt;Gmaplocation&lt;/a&gt; Drupal module looks and feels on one website:&lt;/p&gt;


&amp;lt;object type=&quot;application/x-shockwave-flash&quot; height=&quot;309&quot; data=&quot;http://web.mojgost.com/video/player_flv_maxi.swf&quot; width=&quot;490&quot;&gt;
&amp;lt;param name=&quot;movie&quot; value=&quot;/video/player_flv_maxi.swf&quot; /&gt;
&amp;lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot; /&gt;
&amp;lt;param name=&quot;FlashVars&quot; value=&quot;flv=http://web.mojgost.com/video/update_google_map_location.mov.flv&#38;showplayer=1&#38;showfullscreen=1&#38;autoload=1&#38;width=490&#38;height=309&#38;&quot; /&gt;
&amp;lt;/object&gt;

	&lt;p&gt;The video is created with &lt;a href=&quot;http://gadgets.inventivelabs.com.au/castanaut&quot;&gt;Castanut&lt;/a&gt;, tool that allows one to write script that will move mouse, open webpages, enter text and record all this into the screencast. Castanaut scripts are written in &lt;a href=&quot;http://www.ruby-lang.org/en/&quot;&gt;Ruby&lt;/a&gt; and commands are scripts are relatively easy to write.&lt;/p&gt;


	&lt;p&gt;Here is excerpt of the script:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#!/usr/bin/env castanaut
ishowu_start_recording
move to_element('a[title=&quot;Adjust basic site configuration options.&quot;]')
click
pause PageLoadTime
move to_element('a[title=&quot;Configure Google Maps location.&quot;]')
click
pause PageLoadTime
move to_element('[id=&quot;edit-gmaplocation-address&quot;]')
click
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Please note, that it is MacOSX Leopard only tool (there is a fork on GitHub that allows it to be used with 10.4 thought).&lt;/p&gt;


	&lt;p&gt;I had some problems with dissapearing mouse cursor using Snapz Pro X capture tool and it draws up that Snapz Pro X is currently not ready to be used together with scripting yet. Guys in &lt;a href=&quot;http://www.ambrosiasw.com/utilities/snapzprox/&quot;&gt;Ambrosia Software&lt;/a&gt; are working on the next generation and it would probably allow Snapz Pro X to be used with Castanaut . On the end of the day I bought &lt;a href=&quot;http://www.shinywhitebox.com/home/home.html&quot;&gt;iShowU&lt;/a&gt; which did not had any problems.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2008-06-05:3518</id>
    <published>2008-06-05T09:44:00Z</published>
    <updated>2008-06-18T14:46:07Z</updated>
    <link href="http://source.mihelac.org/2008/6/5/gmaplocation-drupal-module-for-geographic-location-via-google-maps" rel="alternate" type="text/html"/>
    <title>gmaplocation - Drupal module for geographic location via Google Maps</title>
<summary type="html">&lt;p&gt;The gmaplocation is Drupal 5.7 module that allow displaying of your geographic location via Google Maps. It has following features:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;show Google Maps with marker on your location&lt;/li&gt;
		&lt;li&gt;editor can drag marker to fine-tune position in case when geolocating from address is not accurate&lt;/li&gt;
		&lt;li&gt;creates a block with static image of map and link to gmaplocationpage&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Here are some screenshoots of gmaplocation in action:&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/source.mihelac.org/2008/6/5/gmaplocation.png&quot; alt=&quot;&quot; /&gt;
gmaplocation page and static block in right sidebar&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;The gmaplocation is Drupal 5.7 module that allow displaying of your geographic location via Google Maps. It has following features:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;show Google Maps with marker on your location&lt;/li&gt;
		&lt;li&gt;editor can drag marker to fine-tune position in case when geolocating from address is not accurate&lt;/li&gt;
		&lt;li&gt;creates a block with static image of map and link to gmaplocationpage&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Here are some screenshoots of gmaplocation in action:&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/source.mihelac.org/2008/6/5/gmaplocation.png&quot; alt=&quot;&quot; /&gt;
gmaplocation page and static block in right sidebar&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/source.mihelac.org/2008/6/5/gmaplocation_admin.png&quot; alt=&quot;&quot; /&gt;
gmaplocation admin page&lt;/p&gt;


	&lt;p&gt;&lt;img src=&quot;/assets/source.mihelac.org/2008/6/5/gmaplocation_finetune.png&quot; alt=&quot;&quot; /&gt;
fine tuning location with drag and drop&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://drupal.org/project/gmaplocation&quot;&gt;Module page on Drupal.org&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2008-05-13:3495</id>
    <published>2008-05-13T04:45:00Z</published>
    <updated>2008-05-13T06:57:41Z</updated>
    <link href="http://source.mihelac.org/2008/5/13/static-variables-and-unset" rel="alternate" type="text/html"/>
    <title>Static variables and unset()</title>
<content type="html">
            &lt;p&gt;In Drupal many things are cached with static variables and this is often main source of headache. I just submitted small patch for bug where &lt;a href=&quot;http://drupal.org/node/257787&quot;&gt;static cache does not work as it should&lt;/a&gt;. Bug report and this example shows that unset() should not be used with static variables:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;&amp;lt;?php
function locale_supported_languages($reset = FALSE, $val = array()) {
  static $all = NULL;

  if ($reset) {
    // If a static variable is unset() inside of a function, unset() destroys the variable only in the context of the rest of a function. Following calls will restore the previous value of a variable.
    unset($all); // this would not work
    //$all = NULL; // this would work
  }

  if (is_null($all)) {
    $all = array();
    foreach ($val as $key =&amp;gt; $value) {
      $all[$key] = $value;
    }
  }
  return $all;  
}

echo &quot;\narray should have 'cached' element (PASS):&quot;;
print_r(locale_supported_languages(FALSE, array(&quot;first&quot; =&amp;gt; &quot;cached&quot;)));

echo &quot;\narray should have 'new' element (PASS):&quot;;
print_r(locale_supported_languages(TRUE, array(&quot;first&quot; =&amp;gt; &quot;new&quot;)));

echo &quot;\narray should have 'new' element but have 'cached' (FAILS):&quot;;
print_r(locale_supported_languages(FALSE));&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2008-05-08:3492</id>
    <published>2008-05-08T07:39:00Z</published>
    <updated>2008-05-08T07:44:13Z</updated>
    <link href="http://source.mihelac.org/2008/5/8/drupal-replace-colors-in-buttons-with-color-module" rel="alternate" type="text/html"/>
    <title>Drupal - replace colors in buttons with color.module</title>
<summary type="html">&lt;p&gt;&lt;img src=&quot;/assets/2008/5/8/color-module-example_2.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;Drupal Color.module allows the admin to change the color scheme of a theme completely. 
Color module basically fill viewport with 5 choosen colors, layout transparent &lt;span class=&quot;caps&quot;&gt;PNG&lt;/span&gt; on it and then makes image slices and update &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; with this colors.&lt;/p&gt;


	&lt;p&gt;I would like to share some code that customize color.module further. After color scheme is choosen specified images would be copied and colors updated to reflect current color scheme. This is especially useful for creating buttons that should be color aware.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;&lt;img src=&quot;/assets/2008/5/8/color-module-example_2.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;Drupal Color.module allows the admin to change the color scheme of a theme completely. 
Color module basically fill viewport with 5 choosen colors, layout transparent &lt;span class=&quot;caps&quot;&gt;PNG&lt;/span&gt; on it and then makes image slices and update &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt; with this colors.&lt;/p&gt;


	&lt;p&gt;I would like to share some code that customize color.module further. After color scheme is choosen specified images would be copied and colors updated to reflect current color scheme. This is especially useful for creating buttons that should be color aware.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/**
  * Form alter hook
  */
function mycolormodule_form_alter($form_id, &#38;$form) { 
  if ($form_id == 'system_theme_settings') {
    $form['#submit']['mycolormodule_system_theme_settings'] = array();
  }
} 

/**
 * Copy PNG images and change color in images with color from palette. 
 * 
 * Settings in color.inc $info array:
 *
 *     'change_color' =&amp;gt; array(
 *        'images/form_buttons.png' =&amp;gt; array(&quot;#3CC6F5&quot; =&amp;gt; &quot;bottom&quot;), // Color #3CC6F5 will be updated with color of &quot;header bottom&quot; 
 *    ),
 */
function mycolormodule_system_theme_settings($form_id, $values) {

  $theme = $values['theme'];
  $target = variable_get('color_'. $theme .'_stylesheet', NULL);
  if (!$target) return;
  $files = variable_get('color_'. $theme .'_files', array());
  $target = dirname($target) . &quot;/&quot;;
  $info = $values['info'];
  $source = drupal_get_path('theme', $theme) .'/';
  foreach ($info['change_color'] as $file =&amp;gt; $replace_array) {
    $base = basename($file);
    $source = $source . $file;
    // NOTE: change color
    $im = imagecreatefrompng($source);
    foreach ($replace_array as $old =&amp;gt; $new) {
      $old_arr = _color_unpack($old);
      $index = imagecolorexact($im, $old_arr[0], $old_arr[1], $old_arr[2]);
      $new_arr = _color_unpack($values['palette'][$new]);
      imagecolorset($im, $index ,$new_arr[0], $new_arr[1], $new_arr[2]);
      $files[] = $target . $base;
    }
    imagepng($im, $target . $base);
  }
  variable_set('color_'. $theme .'_files', $files);
}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Buttons from above image are based on &lt;a href=&quot;http://www.hedgerwow.com/360/dhtml/css-round-button/demo.php&quot;&gt;Wii buttons demo&lt;/a&gt;.
Using color.module is described in details &lt;a href=&quot;http://drupal.org/node/108459&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2008-04-22:3485</id>
    <published>2008-04-22T17:25:00Z</published>
    <updated>2008-04-23T13:15:23Z</updated>
    <link href="http://source.mihelac.org/2008/4/22/drupal-forms-first-argument-is-expected-to-be-a-valid-callback" rel="alternate" type="text/html"/>
    <title>Drupal Forms - First argument is expected to be a valid callback</title>
<content type="html">
            &lt;p&gt;While creating an installation profile for Drupal based websites I lost a day tracking what should look like a small error. This seems to be often error and it seems there are many possiblities why this and similiar errors can occur:&lt;/p&gt;


&lt;pre&gt;warning: call_user_func_array() [&amp;lt;a href='function.call-user-func-array'&amp;gt;function.call-user-func-array&amp;lt;/a&amp;gt;]: First argument is expected to be a valid callback, 'page_node_form' was given in /Users/bmihelac/Sites/drupal/tsitedemo/includes/form.inc on line 221.&lt;/pre&gt;

	&lt;p&gt;This error occure in &lt;a href=&quot;http://api.drupal.org/api/function/drupal_retrieve_form/5&quot; title=&quot;$form_id&quot;&gt;drupal_retrieve_form&lt;/a&gt; function of form.inc and means that Drupal did not found &lt;em&gt;callback_function&lt;/em&gt; for creating &lt;em&gt;$form_id&lt;/em&gt; form.&lt;/p&gt;


	&lt;h3&gt;How Drupal retrieves form:&lt;/h3&gt;


	&lt;ol&gt;
	&lt;li&gt;&lt;em&gt;drupal_retrieve_form&lt;/em&gt; function invokes &lt;em&gt;hook_forms&lt;/em&gt; on all modules and statically cache returned forms&lt;/li&gt;
		&lt;li&gt;it execute &lt;em&gt;callback&lt;/em&gt; for given &lt;em&gt;$form_id&lt;/em&gt; is it exists, if &lt;em&gt;callback&lt;/em&gt; does not exists &lt;em&gt;drupal_retrieve_form&lt;/em&gt; calls function named &lt;em&gt;$form_id&lt;/em&gt;&lt;/li&gt;
		&lt;li&gt;&lt;em&gt;node.module&lt;/em&gt; defines &lt;em&gt;hook_forms&lt;/em&gt; so every content type has form_id in format &lt;em&gt;&lt;span class=&quot;caps&quot;&gt;CONTENT&lt;/span&gt;-TYPE_node_form&lt;/em&gt; (page_node_type for example). Callback for all node forms is same and it is &lt;em&gt;node_form&lt;/em&gt;. It is important to know that &lt;a href=&quot;http://api.drupal.org/api/function/node_forms/5&quot;&gt;node_forms&lt;/a&gt; calls &lt;a href=&quot;http://api.drupal.org/api/function/node_get_types/5&quot;&gt;node_get_types&lt;/a&gt; to obtain available node types and this function statically cashes node types.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;h3&gt;Possible solutions&lt;/h3&gt;


	&lt;p&gt;In my case the error occured because I created custom node type and wanted to create nodes via drupal_execute_macro in same script. &lt;a href=&quot;http://api.drupal.org/api/function/node_get_types/5&quot;&gt;node_get_types&lt;/a&gt; returned caches node types and custom node was not in it. That also explains while same code worked if it was split in two scripts. Once the problem is found, solution is easy as reloading node types:&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://api.drupal.org/api/function/node_get_types/5&quot;&gt;node_get_types(&#8216;types&#8217;, &lt;span class=&quot;caps&quot;&gt;NULL&lt;/span&gt;, TRUE);&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;If you have similiar problems you can:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;check if you can retrieve form with &lt;em&gt;drupal_retrieve_form($form_id)&lt;/em&gt;&lt;/li&gt;
		&lt;li&gt;check if $form_id is created in &lt;em&gt;module_invoke_all(&#8216;forms&#8217;)&lt;/em&gt;&lt;/li&gt;
		&lt;li&gt;check if module that should create form is loaded with &lt;em&gt;module_list(FALSE, &lt;span class=&quot;caps&quot;&gt;TRUE&lt;/span&gt;, FALSE)&lt;/em&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Thanks for reading and hope this will save you some time.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class=&quot;caps&quot;&gt;UPDATE&lt;/span&gt;:&lt;/strong&gt; I noticed that some other functions statically cache variables so similiar problems occured when creating multilanguage nodes. The best solution for now seems to create content types, blocks, etc in installation profile and create content in other script.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2008-02-16:1822</id>
    <published>2008-02-16T20:40:00Z</published>
    <updated>2008-02-16T21:07:58Z</updated>
    <link href="http://source.mihelac.org/2008/2/16/breaking-the-silence" rel="alternate" type="text/html"/>
    <title>Breaking the silence</title>
<content type="html">
            &lt;p&gt;Visited &lt;a href=&quot;http://barcamp.ini.hr/&quot;&gt;BarCamp Zagreb&lt;/a&gt; in december and I really liked it.&lt;/p&gt;


	&lt;p&gt;I like seeing new local ruby groups arise, we have &lt;a href=&quot;http://groups.google.com/group/ruby-hr&quot;&gt;Ruby Hrvatska&lt;/a&gt; and &lt;a href=&quot;http://groups.google.com/group/ruby-slovenija&quot;&gt;Ruby Slovenija&lt;/a&gt; groups.&lt;/p&gt;


	&lt;p&gt;We plan to do some unconference in Ljubljana or Maribor in march to exchange ruby knowledge, socialize and drink few beers. I plan to make short presentation about ruby/rails testing techniques in everyday work. If you are interested check us at &lt;a href=&quot;http://ruby.meetup.com/126/boards/thread/4192845&quot;&gt;Ruby Meetup&lt;/a&gt;.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2007-09-07:372</id>
    <published>2007-09-07T22:05:00Z</published>
    <updated>2007-09-07T22:09:52Z</updated>
    <link href="http://source.mihelac.org/2007/9/7/railsconf-berlin" rel="alternate" type="text/html"/>
    <title>RailsConf Berlin</title>
<content type="html">
            &lt;p&gt;&lt;img src=&quot;http://www.railsconfeurope.com/images/railseurope2007/layout/railseuro_logo.jpg&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;See ya there, friends!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2007-08-14:254</id>
    <published>2007-08-14T15:56:00Z</published>
    <updated>2007-08-14T16:00:54Z</updated>
    <link href="http://source.mihelac.org/2007/8/14/punbb-to-beast-converter" rel="alternate" type="text/html"/>
    <title>PunBB to Beast converter</title>
<content type="html">
            &lt;p&gt;&lt;img src=&quot;http://source.mihelac.org/assets/2007/8/14/punbb_to_beast2.gif&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;


	&lt;p&gt;Rails plugin punbb_to_beast would convert &lt;a href=&quot;http://www.punbb.org&quot;&gt;PunBB&lt;/a&gt; to &lt;a href=&quot;http://beast.caboo.se/&quot;&gt;Beast&lt;/a&gt; forum data.&lt;/p&gt;


	&lt;p&gt;Repository is here:&lt;/p&gt;


	&lt;p&gt;&lt;a href=&quot;http://site-express.biz/svn/svn_r/plugins/punbb_to_beast/&quot;&gt;http://site-express.biz/svn/svn_r/plugins/punbb_to_beast/&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;To install and run assuming beast and punbb are in same database and punbb tables are prefixed with /punbb/:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;ruby script/plugin install -x http://site-express.biz/svn/svn_r/plugins/punbb_to_beast/
rake punbb_to_beast:import SRC_PREFIX=punbb
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;See &lt;a href=&quot;http://site-express.biz/svn/svn_r/plugins/punbb_to_beast/README&quot;&gt;readme&lt;/a&gt; for more info.&lt;/p&gt;


	&lt;p&gt;This plugin is work in progress.  It work for me and I tested it with latest clean PunBB installation but didn&#8217;t had time to test it throughly (so backup db before). Let me know if it works for you.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2007-08-08:221</id>
    <published>2007-08-08T06:19:00Z</published>
    <updated>2007-08-08T06:23:55Z</updated>
    <link href="http://source.mihelac.org/2007/8/8/gettext-to-gibberish-rake-task" rel="alternate" type="text/html"/>
    <title>GetText to Gibberish rake task</title>
<content type="html">
            &lt;p&gt;Here is a rake task to update your models and controllers to use Gibberish instead of GetText. 
It would change _s(&#8220;Title|MyTitle&#8221;) to &#8220;MyTitle&#8221;[] . It would use GetText default translation so if Title|MyTitle is translated to &#8220;My Beautiful Title&#8221; it would add this instead.&lt;/p&gt;


	&lt;p&gt;&lt;ins&gt;to_gibberish&lt;/ins&gt; would overwrite files so backup files before.&lt;/p&gt;


	&lt;h3&gt;Usage:&lt;/h3&gt;


	&lt;p&gt;rake to_gibberish &lt;span class=&quot;caps&quot;&gt;FILES&lt;/span&gt;=app/views/controller/index.rhtml
rake to_gibberish &lt;span class=&quot;caps&quot;&gt;FILES&lt;/span&gt;=app/views/&lt;strong&gt;*/&lt;/strong&gt;.rhtml&lt;/p&gt;


	&lt;h3&gt;Code&lt;/h3&gt;


&lt;pre&gt;&lt;code&gt;
desc &quot;Simple script to migrate gettext default lang to gibberish.&quot; 
task :to_gibberish do
  require 'rubygems'
  require 'gettext'
  GetText.bindtextdomain('myapp', :path =&amp;gt; '/home/rails/myapp/locale')
  Dir.glob(ENV[&quot;FILES&quot;]).each do |filename|
    str = File.open(filename) {|f| f.read }
    str = str.gsub(/s?_\([&quot;']((?:[^\|&quot;']+\|)*([^&quot;']+))[&quot;']\)/) { |s|
      '&quot;' + GetText.s_($2) + '&quot;[]'
    }
    File.open(filename, &quot;w&quot;) {|f| f.write(str) }
  end
end
&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2007-08-08:220</id>
    <published>2007-08-08T05:57:00Z</published>
    <updated>2007-08-08T06:18:51Z</updated>
    <link href="http://source.mihelac.org/2007/8/8/gettext-to-gibberish" rel="alternate" type="text/html"/>
    <title>Gettext to Gibberish</title>
<content type="html">
            &lt;p&gt;For upgrade of old Rails project I decide to use Gibberish instead of GetText. Reasons are:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Gibberish seems very light and &lt;strong&gt;pure ruby&lt;/strong&gt;. Installing GetText is not a problem with rubygems but it&#8217;s easier to install Gibberish. Especially If you have to ask administrator to update / reinstall GetText.&lt;/li&gt;
		&lt;li&gt;work with all PO, MO files and directories made me tired many times, rake updatepo, rake makemo, restart &lt;/li&gt;
		&lt;li&gt;few times, I jumped on Rails Edge and left out with GetText as thse two were not compatible in the moment &#8211; with GetText being compiled I couldn&#8217;t help but wait to be fixed&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;While GetText seems unmatched for translating standard aplications I am not sure if it is best fit for today web applications developed and changed rapidly.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2007-07-06:159</id>
    <published>2007-07-06T09:28:00Z</published>
    <updated>2007-07-06T09:28:31Z</updated>
    <link href="http://source.mihelac.org/2007/7/6/rails-in-practice-compare-records" rel="alternate" type="text/html"/>
    <title>Rails in practice - Compare records</title>
<content type="html">
            &lt;p&gt;We have &lt;em&gt;Travel&lt;/em&gt; object which defines &lt;em&gt;travel_on&lt;/em&gt; attribute. Now, when I want to compare &lt;em&gt;Travel&lt;/em&gt; objects, I can use:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;raise &quot;Cannot come before you leave&quot; unless departure.travel_on &amp;gt; arrival.tavel_on
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Or sort travel array with:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;journeys.sort {|a,b| a.travel_on&amp;lt;=&amp;gt;b.travel_on}
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This would work, but it is not very readable and &lt;span class=&quot;caps&quot;&gt;DRY&lt;/span&gt;. If we include  &lt;em&gt;Comparable&lt;/em&gt;  mixin in &lt;em&gt;Travel&lt;/em&gt; , and define &lt;em&gt;&amp;lt;=&amp;gt;&lt;/em&gt; operator we would get conventional comparison operators (&amp;lt;, &amp;lt;=, ==, &amp;gt;=, and &amp;gt;) including the method between? for free. Our code would now look:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;class Travel &amp;lt; ActiveRecord::Base
  include Comparable

  def &amp;lt;=&amp;gt;(other)
    self.travel_on&amp;lt;=&amp;gt;other.travel_on
  end  
end
...
raise &quot;Cannot come before you leave&quot; unless departure &amp;gt; arrival
...
journeys.sort
...
some_other_travel.between?(arrival, departure)
&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2007-06-20:122</id>
    <published>2007-06-20T09:05:00Z</published>
    <updated>2007-06-20T09:35:55Z</updated>
    <link href="http://source.mihelac.org/2007/6/20/now-on-mephisto" rel="alternate" type="text/html"/>
    <title>Now on Mephisto</title>
<content type="html">
            &lt;p&gt;Hello! Blog was down for almost a week. Sorry for that. Spam comments flooded all over the blog and I have to delete up to 50 comments a day.  Suddenly blog stopped working, I am not sure what was the reason, nothing in rails log file, nothing in fast cgi log. It seemed to much work just to get it back on shared server, so I decided to host blog on &lt;span class=&quot;caps&quot;&gt;VPS&lt;/span&gt;  and to convert it from Typo to &lt;a href=&quot;http://mephistoblog.com&quot;&gt;Mephisto&lt;/a&gt; engine with modified Lighter theme (thanks &lt;a href=&quot;http://opensoul.org&quot;&gt;Brandon&lt;/a&gt;).&lt;/p&gt;


	&lt;p&gt;From the whole story I got few answers I was looking for some time:&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Can Rails web site be hosted on shared server?&lt;/strong&gt;
No, even the smallest one or at least without a problems now and / or in the future. You need &lt;span class=&quot;caps&quot;&gt;VPS&lt;/span&gt; and you need at least 30-40 MB per web site. If you want Apache, MySql and e-mail, by my experience &lt;span class=&quot;caps&quot;&gt;VPS&lt;/span&gt; with 160 MB is minimum. &lt;span class=&quot;caps&quot;&gt;VPS&lt;/span&gt;&#8217;s come without Cpanel / Plesk (if you are spare with memory and money at least), so you would need to learn some sysadmin as well. Webmin can surely make things easier.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Is it easy to migrate from Typo to Mephisto? Can Mephisto host multiple blogs?&lt;/strong&gt;
Yes and yes, very easy. I had two blogs, one running on Mephisto and one on Typo. I converted Typo blog to Mephisto and imported in same database in just few commands. Adding new theme to converted blog was easy too.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2007-05-12:35</id>
    <published>2007-05-12T04:12:00Z</published>
    <updated>2007-06-15T12:06:14Z</updated>
    <link href="http://source.mihelac.org/2007/5/12/rails-in-practice-group-records-by-condition" rel="alternate" type="text/html"/>
    <title>Rails in practice - Group records by condition</title>
<content type="html">
            &lt;p&gt;Often, when it comes to views I have to group records and present it to the user grouped by some condition. For example, I would like to list all news articles grouped by year.&lt;/p&gt;


	&lt;p&gt;To accomplish this, I find it easiest that records are grouped in a &lt;em&gt;hash&lt;/em&gt;, key should be &lt;em&gt;year&lt;/em&gt; when article is published and value would be array of objects matching published on these year.&lt;/p&gt;


	&lt;p&gt;Before, I used custom function that would walk throught all elements of array calling custom block for each member and creating new hash with result value of the block as key and array of elements as value.&lt;/p&gt;


	&lt;p&gt;Today I discover &lt;em&gt;classify&lt;/em&gt; method in &lt;em&gt;Set&lt;/em&gt; class that would do just what I need (thanks to &lt;a href=&quot;http://www.amazon.com/Cookbook-Cookbooks-OReilly-Lucas-Carlson/dp/0596523696&quot;&gt;Ruby Cookbook&lt;/a&gt; for that).&lt;/p&gt;


	&lt;p&gt;So, the code to group all news articles by year published is:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;@groups = NewsArticle.find(:all).to_set.classify {
  |article| article.published_on.year}&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;and view would be something like these:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;&amp;lt;%@groups.each do |year, articles|%&amp;gt;
  &amp;lt;h1&amp;gt;&amp;lt;%=year%&amp;gt;&amp;lt;/h1&amp;gt;
  &amp;lt;%=articles.collect {|a| \&quot;&amp;lt;p&amp;gt;a.name&amp;lt;/p&amp;gt;\&quot;}.join%&amp;gt;
&amp;lt;%end%&amp;gt;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Short and sweet. Same method can be used to group anything, names by first letter, products by price range, etc.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2007-04-28:34</id>
    <published>2007-04-28T15:02:00Z</published>
    <updated>2007-06-15T12:06:14Z</updated>
    <link href="http://source.mihelac.org/2007/4/28/create-url-s-outside-of-controllers-and-views" rel="alternate" type="text/html"/>
    <title>Create URL's outside of controllers and views</title>
<content type="html">
            &lt;p&gt;If you have a need to create &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;&#8217;s outside of controllers and views include UrlWriter helper and set default_url_options.&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;include ActionController::UrlWriter
default_url_options = &quot;www.example.com&quot;&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;This way, you can create &lt;span class=&quot;caps&quot;&gt;URL&lt;/span&gt;&#8217;s and use named routes from mailers, migrations, import scripts, etc. More info on &lt;a href=&quot;http://api.rubyonrails.org/classes/ActionController/UrlWriter.html#M000090&quot;&gt;Rails Framework Documentation&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://source.mihelac.org/">
    <author>
      <name>bmihelac</name>
    </author>
    <id>tag:source.mihelac.org,2007-03-27:33</id>
    <published>2007-03-27T15:25:00Z</published>
    <updated>2007-06-15T12:06:14Z</updated>
    <link href="http://source.mihelac.org/2007/3/27/customized-mongrel-startup-script" rel="alternate" type="text/html"/>
    <title>Customized Mongrel Startup Script</title>
<summary type="html">&lt;p&gt;This shell script allows to start and stop bunch of &lt;a href=&quot;http://www.rubyonrails.com&quot;&gt;Rails&lt;/a&gt; application on &lt;a href=&quot;http://mongrel.rubyforge.org/&quot;&gt;Mongrel&lt;/a&gt; webserver. This is &lt;a href=&quot;http://timmorgan.org/&quot;&gt;Tim Morgan&#8217;s&lt;/a&gt; script, while I added ability to customize port, rails environment and directory for every app while respecting default values.&lt;/p&gt;</summary><content type="html">
            &lt;p&gt;This shell script allows to start and stop bunch of &lt;a href=&quot;http://www.rubyonrails.com&quot;&gt;Rails&lt;/a&gt; application on &lt;a href=&quot;http://mongrel.rubyforge.org/&quot;&gt;Mongrel&lt;/a&gt; webserver. This is &lt;a href=&quot;http://timmorgan.org/&quot;&gt;Tim Morgan&#8217;s&lt;/a&gt; script, while I added ability to customize port, rails environment and directory for every app while respecting default values.&lt;/p&gt;
&lt;p&gt;I use it on linux development machine where there is no need for mongrel_cluster and I do not want to make extra configuration.&lt;/p&gt;


	&lt;p&gt;We can save this script as &lt;strong&gt;/etc/init.d/mongrel&lt;/strong&gt; and start|restart|stop all mongrels with &lt;strong&gt;/etc/init.d/mongrel start&lt;/strong&gt; (or stop|restart). And to configure for startup we can use:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;# redhat
sudo /sbin/chkconfig --level 345 mongrel on
#debian/ubuntu
sudo /usr/sbin/update-rc.d -f mongrel defaults
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;And here is script:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;#!/usr/bin/env ruby
#
# mongrel Startup script for Mongrel by Tim Morgan, modified by bmihelac
#
# chkconfig: - 85 15
# description: mongrel manages Mongrel
#

# this would add one mongrels for these two apps on 
# ports 8000 and 8001, mephisto would be started in production
apps = [
  {:app =&amp;gt; 'myapp'},
  {:app =&amp;gt; 'mephisto', :environment =&amp;gt; 'production'},
]

default_port = 8000
default_options = {
  :app_dir =&amp;gt; '/home/rails',
  :environment =&amp;gt; 'production'
}

if ['stop', 'restart'].include? ARGV.first
  apps.each do |app|
    options = default_options.merge(app)
    path = File.join options[:app_dir], options[:app]
    puts &quot;Stopping #{path}...&quot; 
    `mongrel_rails stop -c #{path} -P log/mongrel.pid`
  end
end

if ['start', 'restart'].include? ARGV.first
  apps.each do |app|
    options = default_options.merge(app)
    path = File.join options[:app_dir], options[:app]
    port = options[:port] || default_port
    puts &quot;Starting #{options[:app]} on #{port}...&quot; 
    `mongrel_rails start -d -p #{port} -e #{options[:environment]} -c #{path} -P log/mongrel.pid`
    default_port = port + 1
  end
end

unless ['start', 'stop', 'restart'].include? ARGV.first
    puts &quot;Usage: mongrel {start|stop|restart}&quot; 
    exit
end

&lt;/code&gt;&lt;/pre&gt;
          </content>  </entry>
</feed>
