tag:blogger.com,1999:blog-37762535462343119642024-03-13T03:22:17.777-07:00Moki Systems BlogInsights from Moki Systems into our products and servicesBrethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.comBlogger33125tag:blogger.com,1999:blog-3776253546234311964.post-91103104273412715902013-04-05T17:37:00.001-07:002013-04-05T17:37:07.074-07:00Restoring MySQL Databases<br />
<div class="post" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-bottom: 1em;">
<h2 id="post-23" style="clear: both; color: #333333; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">May 21st, 2008 By: brian</span></h2>
<div class="entry" style="margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
This is a quick post to possibly save someone some time when they google for restoring mysql data files. The gist of it is, <em>don’t try to copy InnoDB files directly into your data directory, it won’t work.</em></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>Background</strong></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Sometime back I wiped my development box clean and reinstalled the OS from scratch. It’s a wonderful feeling to start fresh and get rid of all the old whacky configs and random junk that collects on a filesystem. Prior to this cleansing, I backed up all the junk I considered save-worthy. One thing I saved was they MySQL data directory. Many of the databases were old projects and at the time I didn’t think I’d need to look at them anytime soon. Well, anytime soon arrived yesterday in the form of me really wanting to see how I had implemented a particular feature in an old project. The database component of that project was essential, so I couldn’t just glance at the code, I wanted to get it running again with the database backend.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>Problem</strong></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I probably should have known better, but I decided to just try to shutdown mysql and copy the files directly to my new data directory. After some permission and user adjusting, that seemed to work… until I actually tried to access the restored database I needed, which used mostly InnoDB tables. They were not showing up or working properly. A quick glance revealed a file I hadn’t copied which seemed like it *might* be something important:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="bash" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">$ <span style="color: #c20cb9; font-weight: bold;">ls</span> -lh <span style="color: black; font-weight: bold;">/</span>Backup<span style="color: black; font-weight: bold;">/</span>mysql<span style="color: black; font-weight: bold;">/</span>data<span style="color: black; font-weight: bold;">/</span>
-rw-rw---- <span style="color: black;">1</span> brian staff <span style="color: black;">1</span>.0G May <span style="color: black;">21</span> <span style="color: black;">10</span>:<span style="color: black;">05</span> ibdata1</pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Yeah, oops. So InnoDB stores things a bit differently than MyISAM.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>Solution</strong></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
The solution turns out to be simple and is what I should have done in the first place.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
First, shutdown the mysql server:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="bash" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">$ mysqladmin -u root -p shutdown</pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Next, startup mysqld with the –datadir option pointing to your old data directory:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="bash" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">$ mysqld --<span style="color: #007800;">datadir=</span><span style="color: black; font-weight: bold;">/</span>Backup<span style="color: black; font-weight: bold;">/</span>mysql<span style="color: black; font-weight: bold;">/</span>data<span style="color: black; font-weight: bold;">/</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
It may complain about some issue with writing to log files, but that doesn’t matter for this quick export.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Now just dump your database as you normally would (or should have originally):</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="bash" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">$ mysqldump -u root -p database_name <span style="color: black; font-weight: bold;">></span> database_name.sql</pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Lastly, shutdown mysqld again, start mysqld normally and then do the import as usual:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="bash" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">$ mysql -u root -p database_name <span style="color: black; font-weight: bold;"><</span> database_name.sql</pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
(you’ll likely need to create the database first)</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
There you have it – the way to get your old database files restored into your current setup. There is probably some better easier way to do this, and if someone knows it, clue me in will ya?</div>
<div class="postmetadata alt" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; color: #777777; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em; padding: 10px;">
<small style="font-size: 12px; line-height: 1.5em;">This entry was posted on Wednesday, May 21st, 2008 at 11:48 am and is filed under <a href="http://www.mokisystems.com/blog/category/mysql/" rel="category tag" style="color: #004c94; text-decoration: none;" title="View all posts in MySQL">MySQL</a>.</small></div>
</div>
</div>
<h3 id="comments" style="background-color: white; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 12pt;">
2 Responses to “Restoring MySQL Databases”</h3>
<ol class="commentlist" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; padding: 0px;">
<li class="alt" id="comment-79" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://cbl.us/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">Cassidy</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/restoring-mysql-databases/#comment-79" style="color: #004c94; text-decoration: none;" title="">June 3rd, 2008 at 4:55 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
You should have been able to tar up the whole data directory and extract it in its new home. Assuming the paths were the same between installs, (if not, edit your my.cnf) innodb should happily come up just fine without missing a beat. Of course you’d want to have done the tarring with MySQL cleanly shutdown, otherwise you’d probably have some issue with ibdata files and probably the MyISAM files too.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Another gotcha is if you change architectures and try and copy the ibdata files to a new box.</div>
</li>
<li class="" id="comment-87" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">brian</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/restoring-mysql-databases/#comment-87" style="color: #004c94; text-decoration: none;" title="">June 9th, 2008 at 12:27 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Cassidy – ah, thanks for the tip. I still probably needed to use the method I did since I wasn’t moving an entire data directory to an empty new one. I was only moving part of the old into my “new” (been using it for 8 months) dev environment.</div>
</li>
</ol>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-53258908256918774462013-04-05T17:36:00.002-07:002013-04-05T17:36:26.575-07:00Recover a deleted file in Subversion<br />
<h2 id="post-24" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">May 29th, 2008 By: brian</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
SVN is great for keeping our projects under tight control. Occasionally, we have the need to get something back that was deleted in a previous revision. So I can remember how to do it next time, here it is:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="bash" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">$ svn copy -r <span style="color: black;">1234</span> url<span style="color: black; font-weight: bold;">/</span>to<span style="color: black; font-weight: bold;">/</span>deleted<span style="color: black; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">file</span> path<span style="color: black; font-weight: bold;">/</span>to<span style="color: black; font-weight: bold;">/</span>recovered<span style="color: black; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">file</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
This will copy the file at the revision specified to the new file in the “restore to path” part. You can find the revision by doing an ’svn log –verbose’ of the directory it was in. That’s all there is to it!</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
My theme seems to be restoring and recovering… is that a bad thing?</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-27498389681558777752013-04-05T17:34:00.006-07:002013-04-05T17:34:51.312-07:00Fragment caching with Radiant CMS<br />
<h2 id="post-26" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">June 10th, 2008 By: Wes Bangerter</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
We’re in the process of converting our website to <a href="http://www.radiantcms.com/" style="color: #004c94; text-decoration: none;">Radiant CMS</a>, and one of the new things on the site is a “Blog Blurbs” section at the bottom of every page that lists our latest blog post. Our blog is in Wordpress, so I setup the RSS Reader extension in Radiant to fetch the posts. Everything worked great, except that page loading was noticeably slower. After the page gets cached everything is fine but this is included on every page so going through the site when there were not cached pages was really frustrating. I thought about modifying the RSS Reader extension to cache our blog blurbs, but I figured a more general approach would work better, so I came up with a fragment caching extension. We’re using it like this:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><r:cache name="rss_fragment" time="60">
<r:feed:items url="[feed_url]" limit="1">
<h3><r:feed:link /></h3>
<p><r:feed:content max_length="300" no_html="true" /></p>
</r:feed:items>
</r:cache></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
The code is at <a href="http://github.com/mokisystems/radiant-fragment-cacher/tree/master" style="color: #004c94; text-decoration: none;">github</a>.</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-78553251722751936412013-04-05T17:34:00.002-07:002013-04-05T17:34:20.713-07:00Ruby Timing Shortcut<br />
<h2 id="post-11" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">June 10th, 2008 By: Daniel</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Recently I was trying to optimize my code a little and needed a quick way to compare the speed of different code snippets. Of course Rails comes with the <a href="http://www.ruby-doc.org/stdlib/libdoc/benchmark/rdoc/index.html" style="color: #004c94; text-decoration: none;">Benchmark module</a> for doing just that. It is, however, in my opinion a bit clunky for quick tests. Look at all the typing it takes just to find the average speed of a snippet over 100 iterations:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #cc00ff; font-weight: bold;">Benchmark</span>.<span style="color: #9900cc;">bm</span> <span style="color: #9966cc; font-weight: bold;">do</span> <span style="color: #006600; font-weight: bold;">|</span>x<span style="color: #006600; font-weight: bold;">|</span>
x.<span style="color: #9900cc;">report</span> <span style="color: #9966cc; font-weight: bold;">do</span>
<span style="color: #006666;">100</span>.<span style="color: #9900cc;">times</span> <span style="color: #9966cc; font-weight: bold;">do</span>
<span style="color: #006600; font-weight: bold;">(</span><span style="color: #006666;">1</span>...<span style="color: #006666;">1000</span><span style="color: #006600; font-weight: bold;">)</span>.<span style="color: #9900cc;">to_a</span>.<span style="color: #9900cc;">sum</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
So I tossed this into my ~/.irbrc file:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #9966cc; font-weight: bold;">class</span> <span style="color: #cc0066; font-weight: bold;">Integer</span>
<span style="color: #9966cc; font-weight: bold;">def</span> ti<span style="color: #006600; font-weight: bold;">(</span><span style="color: #006600; font-weight: bold;">&</span>block<span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #cc00ff; font-weight: bold;">Benchmark</span>.<span style="color: #9900cc;">bm</span> <span style="color: #9966cc; font-weight: bold;">do</span> <span style="color: #006600; font-weight: bold;">|</span>x<span style="color: #006600; font-weight: bold;">|</span>
x.<span style="color: #9900cc;">report</span> <span style="color: #9966cc; font-weight: bold;">do</span>
<span style="color: blue; font-weight: bold;">self</span>.<span style="color: #9900cc;">times</span> <span style="color: #9966cc; font-weight: bold;">do</span>
<span style="color: #9966cc; font-weight: bold;">yield</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
And now I can “time it” like this:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #006600; font-weight: bold;">>></span> <span style="color: #006666;">100</span>.<span style="color: #9900cc;">ti</span> <span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #006666;">1</span>...<span style="color: #006666;">1000</span><span style="color: #006600; font-weight: bold;">)</span>.<span style="color: #9900cc;">to_a</span>.<span style="color: #9900cc;">sum</span><span style="color: #006600; font-weight: bold;">}</span>
user <span style="color: #cc0066; font-weight: bold;">system</span> total real
<span style="color: #006666;">0.540000</span> <span style="color: #006666;">0.050000</span> <span style="color: #006666;">0.590000</span> <span style="color: #006600; font-weight: bold;">(</span> <span style="color: #006666;">0.597664</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #006600; font-weight: bold;">=></span> <span style="color: blue; font-weight: bold;">true</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Much nicer!</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-5734681861496899042013-04-05T17:33:00.007-07:002013-04-05T17:33:55.743-07:00How We’re Using VMWare Server<br />
<h2 id="post-9" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">July 15th, 2008 By: mark</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
VMWare releasing a free version of their server virtualization product opened up some possibilities for us. Moki Systems had multiple servers performing a variety of tasks but there were things we didn’t have. We didn’t have a split between production and development servers and we didn’t have good utilization. Low CPU and memory utilization offers a comfort level but it adds costs, especially when you need more servers that cost money, use electricity, and generate heat.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Free VMWare server limits running virtual servers to 4. Our solution was to purchase new servers equipped with 1 SATA disk for the OS and 4 SCSI disks, 1 for each virtual machine (VM). While VMWare offers an option to write to the disk directly I opted not to do that because the virtual disk files VMWare uses make your VM’s highly portable and easy to duplicate. Disaster recovery practice becomes far easier when you can easily make a duplicate of your production server.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
This architecture’s utility was brought to light when one of your servers died. We were able to pull the disks containing our production servers, copy the VM’s to another server, then get those servers running again quickly. There was no need for OS reinstall or recovery from backup and because of this portability downtime was minimized.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I have VMWare server installed on my Windows workstation with a Centos 5 VM running in the background. I use it for some MySQL and PHP stuff so it isn’t used a whole lot but I hardly know it’s there. The beauty of this that the Windows guys can have a Linux VM and the Linux guys can have a Windows VM. That can help quite a bit when testing browser compatibility on a website or getting access to a tool not available for your OS of choice.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
VMWare server has helped us utilize our server resources better at a very minimal cost. Running 4 servers for the price of one saves us time and money. What else could you ask for?</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-41826842633130185492013-04-05T17:33:00.004-07:002013-04-05T17:33:26.323-07:00Ajax multi file upload with php, iframe, & javascript<br />
<div class="post" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-bottom: 1em;">
<h2 id="post-28" style="clear: both; color: #333333; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">July 22nd, 2008 By: andrew</span></h2>
<div class="entry" style="margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I found several solutions after browsing around google trying to find a multi-file uploader built around php. Most of these solutions for multi-file uploading fit into one of these three categories.</div>
<ol style="margin: 0px; padding: 0px 0px 0px 35px;">
<li style="margin: 7px 0px 8px 10px; padding: 0px;">Use Flash to upload the images. (The browser only supports one image at a time) –<a href="http://swfupload.org/" style="color: #004c94; text-decoration: none;">SWFUpload</a></li>
<li style="margin: 7px 0px 8px 10px; padding: 0px;">Use Javascript to add multiple file type fields, while hidding previous fields – <a href="http://the-stickman.com/web-development/javascript/multiple-file-uploader-mootools-version/" style="color: #004c94; text-decoration: none;">the-stickman</a></li>
<li style="margin: 7px 0px 8px 10px; padding: 0px;">Use Javascript and hidden iframes embedded on the same page to upload the images. –<a href="http://www.ajaxf1.com/tutorial/ajax-file-upload-tutorial.html" style="color: #004c94; text-decoration: none;">ajaxf1</a></li>
</ol>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I decided to take pieces of the mentioned methods and come up with a solution that worked for me.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Here is the idea behind what we are going to be doing.</div>
<ol style="margin: 0px; padding: 0px 0px 0px 35px;">
<li style="margin: 7px 0px 8px 10px; padding: 0px;">Create a HTML form which has a file upload field</li>
<li style="margin: 7px 0px 8px 10px; padding: 0px;">Set the target of this HTML form to an iFrame which is on the same page</li>
<li style="margin: 7px 0px 8px 10px; padding: 0px;">Have Javascript submit the form everytime the “file” field changes</li>
<li style="margin: 7px 0px 8px 10px; padding: 0px;">Javascript hides the form when submitted, and displays an “animation”</li>
<li style="margin: 7px 0px 8px 10px; padding: 0px;">PHP takes the uploaded file, thumbnails it, and stores the image data</li>
<li style="margin: 7px 0px 8px 10px; padding: 0px;">Javascript unhides the form, and re-hides the animation when upload is complete</li>
<li style="margin: 7px 0px 8px 10px; padding: 0px;">Javascript and php show the thumbnail on the same page right after it was uploaded</li>
</ol>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
This makes this little script appear like an ajax application. It is NOT actually AJAX, but uses css, iframes, php sessions, and javascript to make it appear so.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I’ll try to explain what is happening at each step, but keep in mind, I’m not an expert programmer like my fellow co-workers, and I borrowed most of the work from the mentioned sources above. If you just want to download all the files and take the easy way out, skip to the bottom of the post.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>Steps 1 & 2 & 3 – Make Our Form</strong></div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<table style="border-collapse: collapse;"><tbody>
<tr><td class="line_numbers" style="background-color: #ddeeff; color: grey; overflow: visible; padding: 2px 4px; text-align: right; vertical-align: top;"><pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">1
2
3
4
5
6
7
8
9
</pre>
</td><td class="code" style="padding: 2px 4px; vertical-align: top;"><pre class="javascript" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #339933;"><</span>form <span style="color: #000066;">name</span><span style="color: #339933;">=</span><span style="color: #3366cc;">"pictureform"</span> action<span style="color: #339933;">=</span><span style="color: #3366cc;">"upload.php"</span> method<span style="color: #339933;">=</span><span style="color: #3366cc;">"post"</span> enctype<span style="color: #339933;">=</span><span style="color: #3366cc;">"multipart/form-data"</span> target<span style="color: #339933;">=</span><span style="color: #3366cc;">"upload_target"</span> <span style="color: #339933;">></span>
<span style="color: #339933;"><</span>p id<span style="color: #339933;">=</span><span style="color: #3366cc;">"f1_upload_process"</span><span style="color: #339933;">></span>Loading...<span style="color: #339933;"><</span>br<span style="color: #339933;">/><</span>img src<span style="color: #339933;">=</span><span style="color: #3366cc;">"loader.gif"</span> <span style="color: #339933;">/><</span>br<span style="color: #339933;">/></</span>p<span style="color: #339933;">></span>
<span style="color: #339933;"><</span>p id<span style="color: #339933;">=</span><span style="color: #3366cc;">"f1_upload_form"</span> align<span style="color: #339933;">=</span><span style="color: #3366cc;">"center"</span><span style="color: #339933;">><</span>br<span style="color: #339933;">/></span>
<span style="color: #339933;"><</span>label<span style="color: #339933;">></span>Add Pictures<span style="color: #339933;">:</span>
<span style="color: #339933;"><</span>input <span style="color: #000066;">name</span><span style="color: #339933;">=</span><span style="color: #3366cc;">"myfile"</span> type<span style="color: #339933;">=</span><span style="color: #3366cc;">"file"</span> size<span style="color: #339933;">=</span><span style="color: #3366cc;">"30"</span> onchange<span style="color: #339933;">=</span><span style="color: #3366cc;">"startUpload();document.pictureform.submit();"</span> <span style="color: #339933;">/></span>
<span style="color: #339933;"></</span>label<span style="color: #339933;">></span>
<span style="color: #339933;"></</span>p<span style="color: #339933;">></span>
<span style="color: #339933;"><</span>iframe id<span style="color: #339933;">=</span><span style="color: #3366cc;">"upload_target"</span> <span style="color: #000066;">name</span><span style="color: #339933;">=</span><span style="color: #3366cc;">"upload_target"</span> src<span style="color: #339933;">=</span><span style="color: #3366cc;">"#"</span> style<span style="color: #339933;">=</span><span style="color: #3366cc;">"width:0;height:0;border:0px solid #fff;"</span><span style="color: #339933;">></</span>iframe<span style="color: #339933;">></span>
<span style="color: #339933;"></</span>form<span style="color: #339933;">></span></pre>
</td></tr>
</tbody></table>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<span id="more-28"></span><br />Explanation of the mentioned code:<br /><code>enctype="multipart/form-data"</code><br />Tells the browser you are submitting files, or images with your form.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<code>onchange="startUpload();document.pictureform.submit();</code><br />The onchange event of the input field calls the function startUpload(), which will hide the form, and show the animation while uploading. The document.pictureform.submit(); Submits the form to our “action” which we have as “upload.php”</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>Step 4 – Make the JavaScript functions for hiding and showing</strong></div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<table style="border-collapse: collapse;"><tbody>
<tr><td class="line_numbers" style="background-color: #ddeeff; color: grey; overflow: visible; padding: 2px 4px; text-align: right; vertical-align: top;"><pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">1
2
3
4
5
</pre>
</td><td class="code" style="padding: 2px 4px; vertical-align: top;"><pre class="javascript" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #003366; font-weight: bold;">function</span> startUpload<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">{</span>
document.<span style="color: #006600;">getElementById</span><span style="color: #009900;">(</span><span style="color: #3366cc;">'f1_upload_process'</span><span style="color: #009900;">)</span>.<span style="color: #006600;">style</span>.<span style="color: #006600;">visibility</span> <span style="color: #339933;">=</span> <span style="color: #3366cc;">'visible'</span><span style="color: #339933;">;</span>
document.<span style="color: #006600;">getElementById</span><span style="color: #009900;">(</span><span style="color: #3366cc;">'f1_upload_form'</span><span style="color: #009900;">)</span>.<span style="color: #006600;">style</span>.<span style="color: #006600;">visibility</span> <span style="color: #339933;">=</span> <span style="color: #3366cc;">'hidden'</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span></pre>
</td></tr>
</tbody></table>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Explanation of the mentioned code:<br />By giving our HTML elements id tags,such as <code>id=f1_upload_process</code><br />we make them available for manipulation by JavaScript via the DOM.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<code>document.getElementById('f1_upload_process').style.visibility = 'visible';</code><br />says: “get the element in the document that has an id of “f1_upload_process” and make it visible.”</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
This then turns on the visibility of our “animation”</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
block which we have set “invisible” by default in our CSS file. The opposite occurs for the form block, we make it “invisible” or “hidden.”</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Step 5 – Create our “upload.php” script to handle thumbnail and copy image to filesystem</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<table style="border-collapse: collapse;"><tbody>
<tr><td class="line_numbers" style="background-color: #ddeeff; color: grey; overflow: visible; padding: 2px 4px; text-align: right; vertical-align: top;"><pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
</pre>
</td><td class="code" style="padding: 2px 4px; vertical-align: top;"><pre class="php" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="font-weight: bold;"><?php</span>
<span style="color: #666666; font-style: italic;">// keep our session</span>
<span style="color: #990000;">session_start</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Check the upload file type</span>
<span style="color: #000033;">$filetype</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$_FILES</span><span style="color: #009900;">[</span><span style="color: blue;">'myfile'</span><span style="color: #009900;">]</span><span style="color: #009900;">[</span><span style="color: blue;">'type'</span><span style="color: #009900;">]</span><span style="color: #339933;">;</span>
<span style="color: #000033;">$gd_function_suffix</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">(</span>
<span style="color: blue;">'image/pjpeg'</span> <span style="color: #339933;">=></span> <span style="color: blue;">'JPEG'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'image/jpeg'</span> <span style="color: #339933;">=></span> <span style="color: blue;">'JPEG'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'image/gif'</span> <span style="color: #339933;">=></span> <span style="color: blue;">'GIF'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'image/bmp'</span> <span style="color: #339933;">=></span> <span style="color: blue;">'WBMP'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'image/png'</span> <span style="color: #339933;">=></span> <span style="color: blue;">'PNG'</span><span style="color: #339933;">,</span>
<span style="color: blue;">'image/x-png'</span> <span style="color: #339933;">=></span> <span style="color: blue;">'PNG'</span>
<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000033;">$function_suffix</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$gd_function_suffix</span><span style="color: #009900;">[</span><span style="color: #000033;">$filetype</span><span style="color: #009900;">]</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Build Function name for ImageCreateFromSUFFIX </span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">(</span><span style="color: #339933;">!</span><span style="color: #000033;">$function_suffix</span><span style="color: #009900;">)</span><span style="color: #009900;">{</span>
<span style="color: #000033;">$err</span> <span style="color: #339933;">=</span> <span style="color: blue;">"Unsupported file type, must be JPG|PNG|GIF|BMP"</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #b1b100;">else</span><span style="color: #009900;">{</span>
<span style="color: #000033;">$function_to_read</span> <span style="color: #339933;">=</span> <span style="color: blue;">'ImageCreateFrom'</span> <span style="color: #339933;">.</span> <span style="color: #000033;">$function_suffix</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Get the image and create a thumbnail</span>
<span style="color: #000033;">$img</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$function_to_read</span><span style="color: #009900;">(</span><span style="color: #000033;">$_FILES</span><span style="color: #009900;">[</span><span style="color: blue;">'myfile'</span><span style="color: #009900;">]</span><span style="color: #009900;">[</span><span style="color: blue;">'tmp_name'</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #339933;">!</span><span style="color: #000033;">$img</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000033;">$err</span> <span style="color: #339933;">=</span> <span style="color: blue;">"could not create image handle"</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #000033;">$width</span> <span style="color: #339933;">=</span> imageSX<span style="color: #009900;">(</span><span style="color: #000033;">$img</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Get the image width</span>
<span style="color: #000033;">$height</span> <span style="color: #339933;">=</span> imageSY<span style="color: #009900;">(</span><span style="color: #000033;">$img</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Get the image height</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #339933;">!</span><span style="color: #000033;">$width</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #000033;">$height</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000033;">$err</span> <span style="color: #339933;">=</span> <span style="color: blue;">"No Width or Height"</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #666666; font-style: italic;">// Build the thumbnail</span>
<span style="color: #000033;">$target_width</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">100</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Thumnail width</span>
<span style="color: #000033;">$target_height</span> <span style="color: #339933;">=</span> <span style="color: #cc66cc;">100</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Thumbnail height</span>
<span style="color: #000033;">$target_ratio</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$target_width</span> <span style="color: #339933;">/</span> <span style="color: #000033;">$target_height</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//New target ratio</span>
<span style="color: #000033;">$img_ratio</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$width</span> <span style="color: #339933;">/</span> <span style="color: #000033;">$height</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Original ratio</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #000033;">$target_ratio</span> <span style="color: #339933;">></span> <span style="color: #000033;">$img_ratio</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000033;">$new_height</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$target_height</span><span style="color: #339933;">;</span>
<span style="color: #000033;">$new_width</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$img_ratio</span> <span style="color: #339933;">*</span> <span style="color: #000033;">$target_height</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Tall Image</span>
<span style="color: #009900;">}</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">{</span>
<span style="color: #000033;">$new_height</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$target_width</span> <span style="color: #339933;">/</span> <span style="color: #000033;">$img_ratio</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Wide Image</span>
<span style="color: #000033;">$new_width</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$target_width</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #000033;">$new_height</span> <span style="color: #339933;">></span> <span style="color: #000033;">$target_height</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000033;">$new_height</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$target_height</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #000033;">$new_width</span> <span style="color: #339933;">></span> <span style="color: #000033;">$target_width</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000033;">$new_height</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$target_width</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #000033;">$new_img</span> <span style="color: #339933;">=</span> ImageCreateTrueColor<span style="color: #009900;">(</span><span style="color: #000033;">$target_width</span><span style="color: #339933;">,</span> <span style="color: #000033;">$target_height</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Create a new image handle for thumbnail</span>
<span style="color: #000033;">$white</span> <span style="color: #339933;">=</span> imagecolorallocate<span style="color: #009900;">(</span><span style="color: #000033;">$new_img</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">255</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">255</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">255</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// Allocate the color white</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #339933;">!@</span>imagefilledrectangle<span style="color: #009900;">(</span><span style="color: #000033;">$new_img</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000033;">$target_width</span><span style="color: #cc66cc;">-1</span><span style="color: #339933;">,</span> <span style="color: #000033;">$target_height</span><span style="color: #cc66cc;">-1</span><span style="color: #339933;">,</span> <span style="color: #000033;">$white</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span> <span style="color: #666666; font-style: italic;">// Fill the image white</span>
<span style="color: #000033;">$err</span> <span style="color: #339933;">=</span> <span style="color: blue;">"Couldn't fill image"</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #666666; font-style: italic;">// Copy the uploaded image to the newly created image</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #339933;">!@</span>imagecopyresampled<span style="color: #009900;">(</span><span style="color: #000033;">$new_img</span><span style="color: #339933;">,</span> <span style="color: #000033;">$img</span><span style="color: #339933;">,</span> <span style="color: #009900;">(</span><span style="color: #000033;">$target_width</span><span style="color: #339933;">-</span><span style="color: #000033;">$new_width</span><span style="color: #009900;">)</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #009900;">(</span><span style="color: #000033;">$target_height</span><span style="color: #339933;">-</span><span style="color: #000033;">$new_height</span><span style="color: #009900;">)</span><span style="color: #339933;">/</span><span style="color: #cc66cc;">2</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> <span style="color: #000033;">$new_width</span><span style="color: #339933;">,</span> <span style="color: #000033;">$new_height</span><span style="color: #339933;">,</span> <span style="color: #000033;">$width</span><span style="color: #339933;">,</span> <span style="color: #000033;">$height</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000033;">$err</span> <span style="color: #339933;">=</span> <span style="color: blue;">"couldn't copy new image"</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #666666; font-style: italic;">// Create php Session array for image information</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">(</span><span style="color: #000033;">$_SESSION</span><span style="color: #009900;">[</span><span style="color: blue;">"file_info"</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000033;">$_SESSION</span><span style="color: #009900;">[</span><span style="color: blue;">"file_info"</span><span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #666666; font-style: italic;">// Use a output buffering to load the image into a variable</span>
<span style="color: #990000;">ob_start</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
imagejpeg<span style="color: #009900;">(</span><span style="color: #000033;">$new_img</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000033;">$imagevariable</span> <span style="color: #339933;">=</span> <span style="color: #990000;">ob_get_contents</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #990000;">ob_end_clean</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Create a unique id or name for the image</span>
<span style="color: #000033;">$file_id</span> <span style="color: #339933;">=</span> <span style="color: #990000;">md5</span><span style="color: #009900;">(</span><span style="color: #000033;">$_FILES</span><span style="color: #009900;">[</span><span style="color: blue;">"myfile"</span><span style="color: #009900;">]</span><span style="color: #009900;">[</span><span style="color: blue;">"tmp_name"</span><span style="color: #009900;">]</span> <span style="color: #339933;">+</span> <span style="color: #990000;">rand</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">*</span><span style="color: #cc66cc;">100000</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000033;">$new_name</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$file_id</span><span style="color: #339933;">.</span><span style="color: blue;">".$function_suffix"</span><span style="color: #339933;">;</span>
<span style="color: #000033;">$temp_name</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$_FILES</span><span style="color: #009900;">[</span><span style="color: blue;">"myfile"</span><span style="color: #009900;">]</span><span style="color: #009900;">[</span><span style="color: blue;">"tmp_name"</span><span style="color: #009900;">]</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// assign upload directory, and target path for image</span>
<span style="color: #000033;">$uploaddir</span> <span style="color: #339933;">=</span> <span style="color: #990000;">getcwd</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">//</span>
<span style="color: #000033;">$target_path</span> <span style="color: #339933;">=</span> <span style="color: #000033;">$uploaddir</span><span style="color: #339933;">.</span>DIRECTORY_SEPARATOR<span style="color: #339933;">.</span><span style="color: #000033;">$new_name</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Move uploaded image to uploaddir location</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">(</span><span style="color: #339933;">!@</span><span style="color: #990000;">move_uploaded_file</span><span style="color: #009900;">(</span><span style="color: #000033;">$temp_name</span><span style="color: #339933;">,</span> <span style="color: #000033;">$target_path</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #009900;">{</span>
<span style="color: #000033;">$err</span> <span style="color: #339933;">=</span> <span style="color: blue;">"Couldn't Copy File to Filesystem"</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #666666; font-style: italic;">// Create a Session array with name, type, and image object for use in displaying thumbnails</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">(</span><span style="color: #000033;">$_SESSION</span><span style="color: #009900;">[</span><span style="color: blue;">"file_info"</span><span style="color: #009900;">]</span><span style="color: #009900;">[</span><span style="color: #000033;">$file_id</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000033;">$_SESSION</span><span style="color: #009900;">[</span><span style="color: blue;">"file_info"</span><span style="color: #009900;">]</span><span style="color: #009900;">[</span><span style="color: #000033;">$file_id</span><span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">(</span> <span style="color: blue;">"name"</span> <span style="color: #339933;">=></span> <span style="color: #000033;">$new_name</span><span style="color: #339933;">,</span> <span style="color: blue;">"type"</span> <span style="color: #339933;">=></span> <span style="color: #000033;">$function_suffix</span><span style="color: #339933;">,</span>
<span style="color: blue;">"obj"</span> <span style="color: #339933;">=></span> <span style="color: #000033;">$imagevariable</span> <span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
<span style="color: #666666; font-style: italic;">// If no error, then pass good result and file id to Javascript for generating the thumbnail.</span>
<span style="color: #666666; font-style: italic;">// Pass our $err varialbe along</span>
<span style="color: #b1b100;">if</span><span style="color: #009900;">(</span><span style="color: #339933;">!</span><span style="color: #000033;">$err</span><span style="color: #009900;">)</span><span style="color: #009900;">{</span>
<span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> <span style="color: blue;">"'1','"</span><span style="color: #339933;">.</span><span style="color: #000033;">$file_id</span><span style="color: #339933;">.</span><span style="color: blue;">"'"</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #b1b100;">else</span><span style="color: #009900;">{</span>
<span style="color: #000033;">$result</span> <span style="color: #339933;">=</span> <span style="color: blue;">"'.$err.','"</span><span style="color: #339933;">.</span><span style="color: #000033;">$file_id</span><span style="color: #339933;">.</span><span style="color: blue;">"'"</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #990000;">sleep</span><span style="color: #009900;">(</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// in case of really fast upload, sleep script to show loading animation for a bit longer</span>
<span style="color: #666666; font-style: italic;">// Javascript calls the "stopUpload" function with its paramaters</span>
<span style="font-weight: bold;">?></span>
<span style="font-weight: bold;"><script language</span><span style="color: #339933;">=</span><span style="color: blue;">"javascript"</span> type<span style="color: #339933;">=</span><span style="color: blue;">"text/javascript"</span><span style="color: #339933;">></span>window<span style="color: #339933;">.</span>top<span style="color: #339933;">.</span>window<span style="color: #339933;">.</span>stopUpload<span style="color: #009900;">(</span><span style="font-weight: bold;"><?php</span> <span style="color: #990000;">echo</span> <span style="color: #000033;">$result</span><span style="color: #339933;">;</span> <span style="font-weight: bold;">?></span><span style="color: #009900;">)</span><span style="color: #339933;">;</</span>script<span style="color: #339933;">></span></pre>
</td></tr>
</tbody></table>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Explanation of Code:<br />These php functions make use of the GD library. You must have that enabled in PHP in order to use this. Also make sure your current directory is writeable.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I won’t explain to many things here, as the code has inline comments. You could make this code a function and have it thumbnail and save multiple sizes to the filesytem. Currently it simply thumbnails a 100 X 100 and copies the original to the current directory the script is running from. It will do GIF, JPEG, BMP, or PNG. Error checking and Session handling could be improved.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>Step 6 – Create JavaScript function to show form, and hide animation when upload is finished</strong></div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<table style="border-collapse: collapse;"><tbody>
<tr><td class="line_numbers" style="background-color: #ddeeff; color: grey; overflow: visible; padding: 2px 4px; text-align: right; vertical-align: top;"><pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre>
</td><td class="code" style="padding: 2px 4px; vertical-align: top;"><pre class="javascript" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #003366; font-weight: bold;">function</span> stopUpload<span style="color: #009900;">(</span>success<span style="color: #339933;">,</span>fileid<span style="color: #009900;">)</span><span style="color: #009900;">{</span>
<span style="color: #003366; font-weight: bold;">var</span> result <span style="color: #339933;">=</span> <span style="color: #3366cc;">''</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">(</span>success <span style="color: #339933;">==</span> <span style="color: #cc0000;">1</span><span style="color: #009900;">)</span><span style="color: #009900;">{</span>
result <span style="color: #339933;">=</span> <span style="color: #3366cc;">'<span class="msg">The file was uploaded successfully!<<span style="color: #000099; font-weight: bold;">\/</span>span><br/><br/>'</span><span style="color: #339933;">;</span>
addImage<span style="color: #009900;">(</span><span style="color: #3366cc;">"thumbnail.php?id="</span> <span style="color: #339933;">+</span> fileid<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">{</span>
result <span style="color: #339933;">=</span> <span style="color: #3366cc;">'<span class="emsg">There was an error during file upload!'</span> <span style="color: #339933;">+</span> success <span style="color: #339933;">+</span> <span style="color: #3366cc;">'<<span style="color: #000099; font-weight: bold;">\/</span>span><br/><br/>'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
document.<span style="color: #006600;">getElementById</span><span style="color: #009900;">(</span><span style="color: #3366cc;">'f1_upload_process'</span><span style="color: #009900;">)</span>.<span style="color: #006600;">style</span>.<span style="color: #006600;">visibility</span> <span style="color: #339933;">=</span> <span style="color: #3366cc;">'hidden'</span><span style="color: #339933;">;</span>
document.<span style="color: #006600;">getElementById</span><span style="color: #009900;">(</span><span style="color: #3366cc;">'f1_upload_form'</span><span style="color: #009900;">)</span>.<span style="color: #006600;">innerHTML</span> <span style="color: #339933;">=</span> result <span style="color: #339933;">+</span> <span style="color: #3366cc;">'<label>File: <input name="myfile" type="file" size="30" onchange="startUpload();document.pictureform.submit();" /><<span style="color: #000099; font-weight: bold;">\/</span>label>'</span><span style="color: #339933;">;</span>
document.<span style="color: #006600;">getElementById</span><span style="color: #009900;">(</span><span style="color: #3366cc;">'f1_upload_form'</span><span style="color: #009900;">)</span>.<span style="color: #006600;">style</span>.<span style="color: #006600;">visibility</span> <span style="color: #339933;">=</span> <span style="color: #3366cc;">'visible'</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span></pre>
</td></tr>
</tbody></table>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Explanation of Code:<br />From our upload.php script, we passed two varialbes to this JavaScript function, Success and File Id.<br />If we had a successful file upload, we throw up a message saying “success” and call another function called <code>addImage("thumbnail.php?id=" + fileid);</code> <- More on this later...</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
If we didn't have a successful upload, we return a message saying so.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
The last few lines of the function hide the "animation" bar, and recreate our form input element so we can upload another image, and do the whole thing over again. All without leaving the page!</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>Step 7 – Our Thumbnail.php script and our addImage() Javascript function</strong></div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<table style="border-collapse: collapse;"><tbody>
<tr><td class="line_numbers" style="background-color: #ddeeff; color: grey; overflow: visible; padding: 2px 4px; text-align: right; vertical-align: top;"><pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
</pre>
</td><td class="code" style="padding: 2px 4px; vertical-align: top;"><pre class="php" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="font-weight: bold;"><?php</span>
<span style="color: #666666; font-style: italic;">// This script accepts an ID and looks in the user's session for stored thumbnail data.</span>
<span style="color: #666666; font-style: italic;">// It then streams the data to the browser as an image </span>
<span style="color: #990000;">session_start</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000033;">$image_id</span> <span style="color: #339933;">=</span> <span style="color: #990000;">isset</span><span style="color: #009900;">(</span><span style="color: #000033;">$_GET</span><span style="color: #009900;">[</span><span style="color: blue;">"id"</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span> ? <span style="color: #000033;">$_GET</span><span style="color: #009900;">[</span><span style="color: blue;">"id"</span><span style="color: #009900;">]</span> <span style="color: #339933;">:</span> <span style="font-weight: bold;">false</span><span style="color: #339933;">;</span> <span style="color: #666666; font-style: italic;">// get the id from the URL</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #000033;">$image_id</span> <span style="color: #339933;">===</span> <span style="font-weight: bold;">false</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #990000;">exit</span><span style="color: #009900;">(</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #b1b100;">if</span> <span style="color: #009900;">(</span><span style="color: #339933;">!</span><span style="color: #990000;">is_array</span><span style="color: #009900;">(</span><span style="color: #000033;">$_SESSION</span><span style="color: #009900;">[</span><span style="color: blue;">"file_info"</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span><span style="color: #990000;">isset</span><span style="color: #009900;">(</span><span style="color: #000033;">$_SESSION</span><span style="color: #009900;">[</span><span style="color: blue;">"file_info"</span><span style="color: #009900;">]</span><span style="color: #009900;">[</span><span style="color: #000033;">$image_id</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #009900;">}</span>
<span style="color: #990000;">header</span><span style="color: #009900;">(</span><span style="color: blue;">"Content-type: image/jpeg"</span><span style="color: #009900;">)</span> <span style="color: #339933;">;</span>
<span style="color: #990000;">header</span><span style="color: #009900;">(</span><span style="color: blue;">"Content-Length: "</span><span style="color: #339933;">.</span><span style="color: #990000;">strlen</span><span style="color: #009900;">(</span><span style="color: #000033;">$_SESSION</span><span style="color: #009900;">[</span><span style="color: blue;">"file_info"</span><span style="color: #009900;">]</span><span style="color: #009900;">[</span><span style="color: #000033;">$image_id</span><span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #990000;">echo</span> <span style="color: #000033;">$_SESSION</span><span style="color: #009900;">[</span><span style="color: blue;">"file_info"</span><span style="color: #009900;">]</span><span style="color: #009900;">[</span><span style="color: #000033;">$image_id</span><span style="color: #009900;">]</span><span style="color: #009900;">[</span>obj<span style="color: #009900;">]</span><span style="color: #339933;">;</span>
<span style="color: #990000;">exit</span><span style="color: #009900;">(</span><span style="color: #cc66cc;">0</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="font-weight: bold;">?></span></pre>
</td></tr>
</tbody></table>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Code Explanation:<br />This bit of code simply gets the image id from the URL and pulls the image thumbnail data we saved into our session in our upload.php script, and outputs the image to the browser.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>addImage() Javascript Function</strong></div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<table style="border-collapse: collapse;"><tbody>
<tr><td class="line_numbers" style="background-color: #ddeeff; color: grey; overflow: visible; padding: 2px 4px; text-align: right; vertical-align: top;"><pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
</pre>
</td><td class="code" style="padding: 2px 4px; vertical-align: top;"><pre class="javascript" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #003366; font-weight: bold;">function</span> addImage<span style="color: #009900;">(</span>src<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #003366; font-weight: bold;">var</span> newImg <span style="color: #339933;">=</span> document.<span style="color: #006600;">createElement</span><span style="color: #009900;">(</span><span style="color: #3366cc;">"img"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
newImg.<span style="color: #006600;">style</span>.<span style="color: #006600;">margin</span> <span style="color: #339933;">=</span> <span style="color: #3366cc;">"5px"</span><span style="color: #339933;">;</span>
document.<span style="color: #006600;">getElementById</span><span style="color: #009900;">(</span><span style="color: #3366cc;">"thumbnails"</span><span style="color: #009900;">)</span>.<span style="color: #006600;">appendChild</span><span style="color: #009900;">(</span>newImg<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">(</span>newImg.<span style="color: #006600;">filters</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000066; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
newImg.<span style="color: #006600;">filters</span>.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">(</span><span style="color: #3366cc;">"DXImageTransform.Microsoft.Alpha"</span><span style="color: #009900;">)</span>.<span style="color: #006600;">opacity</span> <span style="color: #339933;">=</span> <span style="color: #cc0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: #000066; font-weight: bold;">catch</span> <span style="color: #009900;">(</span>e<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #006600; font-style: italic;">// If it is not set initially, the browser will throw an error. This will set it if it is not set yet.</span>
newImg.<span style="color: #006600;">style</span>.<span style="color: #006600;">filter</span> <span style="color: #339933;">=</span> <span style="color: #3366cc;">'progid:DXImageTransform.Microsoft.Alpha(opacity='</span> <span style="color: #339933;">+</span> <span style="color: #cc0000;">0</span> <span style="color: #339933;">+</span> <span style="color: #3366cc;">')'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">{</span>
newImg.<span style="color: #006600;">style</span>.<span style="color: #006600;">opacity</span> <span style="color: #339933;">=</span> <span style="color: #cc0000;">0</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
newImg.<span style="color: #000066;">onload</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
fadeIn<span style="color: #009900;">(</span>newImg<span style="color: #339933;">,</span> <span style="color: #cc0000;">0</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span><span style="color: #339933;">;</span>
newImg.<span style="color: #006600;">src</span> <span style="color: #339933;">=</span> src<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #003366; font-weight: bold;">function</span> fadeIn<span style="color: #009900;">(</span>element<span style="color: #339933;">,</span> opacity<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #003366; font-weight: bold;">var</span> reduceOpacityBy <span style="color: #339933;">=</span> <span style="color: #cc0000;">5</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> rate <span style="color: #339933;">=</span> <span style="color: #cc0000;">30</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// 15 fps</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">(</span>opacity <span style="color: #339933;"><</span> <span style="color: #cc0000;">100</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
opacity <span style="color: #339933;">+=</span> reduceOpacityBy<span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">(</span>opacity <span style="color: #339933;">></span> <span style="color: #cc0000;">100</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
opacity <span style="color: #339933;">=</span> <span style="color: #cc0000;">100</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">(</span>element.<span style="color: #006600;">filters</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000066; font-weight: bold;">try</span> <span style="color: #009900;">{</span>
element.<span style="color: #006600;">filters</span>.<span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">(</span><span style="color: #3366cc;">"DXImageTransform.Microsoft.Alpha"</span><span style="color: #009900;">)</span>.<span style="color: #006600;">opacity</span> <span style="color: #339933;">=</span> opacity<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span> <span style="color: #000066; font-weight: bold;">catch</span> <span style="color: #009900;">(</span>e<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #006600; font-style: italic;">// If it is not set initially, the browser will throw an error. This will set it if it is not set yet.</span>
element.<span style="color: #006600;">style</span>.<span style="color: #006600;">filter</span> <span style="color: #339933;">=</span> <span style="color: #3366cc;">'progid:DXImageTransform.Microsoft.Alpha(opacity='</span> <span style="color: #339933;">+</span> opacity <span style="color: #339933;">+</span> <span style="color: #3366cc;">')'</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">{</span>
element.<span style="color: #006600;">style</span>.<span style="color: #006600;">opacity</span> <span style="color: #339933;">=</span> opacity <span style="color: #339933;">/</span> <span style="color: #cc0000;">100</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">(</span>opacity <span style="color: #339933;"><</span> <span style="color: #cc0000;">100</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
setTimeout<span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
fadeIn<span style="color: #009900;">(</span>element<span style="color: #339933;">,</span> opacity<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span><span style="color: #339933;">,</span> rate<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
</td></tr>
</tbody></table>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Code Explanation:<br />I borrowed most of this code from the SWFUpload project. The basic idea is that we create a new image tag via javascript, give it a src of “thumbnail.php?id=XXXXX” XXXXX being our image name, and call a “fadeIn” function which does just that, fade the image in for a lovely effect. I have this javascript included in my index.php page via</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><script type="text/javascript" src="handlers.js"></script></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Thats it! Hope you learned as much as I did from this tutorial.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<em>Important Notes:</em></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
-This script does not check file size, or limit the number of files that can be uploaded.<br />-You will need to add in appropriate error checking on the uploaded files for security.<br />-You will want to clean out the data from the session when done with the uploading.<br />-Make sure you have write permission the directory where images are being saved<br />-You must have GD library installed for this script to work</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
All the files you need to be up and running are found here -> <a href="http://www.mokisystems.com/blog/wp-content/uploads/2008/07/ajax-file-upload-mokisystems.zip" style="color: #004c94; text-decoration: none;">ajax-file-upload-mokisystems</a></div>
<div class="postmetadata alt" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; color: #777777; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em; padding: 10px;">
<small style="font-size: 12px; line-height: 1.5em;">This entry was posted on Tuesday, July 22nd, 2008 at 4:08 pm and is filed under <a href="http://www.mokisystems.com/blog/category/javascript/" rel="category tag" style="color: #004c94; text-decoration: none;" title="View all posts in JavaScript">JavaScript</a>, <a href="http://www.mokisystems.com/blog/category/php/" rel="category tag" style="color: #004c94; text-decoration: none;" title="View all posts in PHP">PHP</a>.</small></div>
</div>
</div>
<h3 id="comments" style="background-color: white; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 12pt;">
16 Responses to “Ajax multi file upload with php, iframe, & javascript”</h3>
<ol class="commentlist" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; padding: 0px;">
<li class="alt" id="comment-96" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://www.spintechwebdevelopment.com/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">Sean</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-96" style="color: #004c94; text-decoration: none;" title="">July 31st, 2008 at 9:56 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Hello. I am running into a problem using your little script here for multi-file uploading. In my xampp environment on my laptop I am running php version 5.2.5 and the code works completely fine in both Firefox 3.0 and IE7. However when I upload it to my website, any image file I upload will upload just fine, yet the thumbnail that is supposed to be generated does not display.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
If I view the source I can see where it creates an img tag like but it does not display that image. Any ideas on why this might be?</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Since the code is the same from my laptop to my website and the only thing different is the version of php that is running between the two the only thing I can think of is that there is something missing from the version of php that my website is running which is php version 4.4.8. Any help would be greatly appreciated.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Thanks,<br />Sean Meyer</div>
</li>
<li class="" id="comment-97" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">andrew</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-97" style="color: #004c94; text-decoration: none;" title="">July 31st, 2008 at 10:14 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Sean</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
It could be a number of things. It sounds like the “thumbnail.php” is not outputting it to the browser. It is also possible that the upload.php file is adding the thumbnail picture id to the Session. Try commenting out the following line of code in the thumbnail.php:</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Make<br /><code>header("Content-Length: ".strlen($_SESSION["file_info"][$image_id]));</code><br />Becomes<br /><code>//header("Content-Length: ".strlen($_SESSION["file_info"][$image_id]));</code></div>
</li>
<li class="alt" id="comment-98" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://www.spintechwebdevelopment.com/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">Sean</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-98" style="color: #004c94; text-decoration: none;" title="">July 31st, 2008 at 1:04 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Hey thanks, that worked perfectly!. I appreciate the quick response.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Sean</div>
</li>
<li class="" id="comment-100" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">Ken</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-100" style="color: #004c94; text-decoration: none;" title="">August 4th, 2008 at 7:39 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
This is a great script, i just need some help on how to actually create and save a thumbnail of the image being uploaded, like “imageid_th.jpg”</div>
</li>
<li class="alt" id="comment-101" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">Ken</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-101" style="color: #004c94; text-decoration: none;" title="">August 4th, 2008 at 8:46 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
^^ I spoke too soon!</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
After you create the unique id or name for the image, create one for the thumbnail as well:</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
####//// create a thumbnail image as well<br />$thumb_name = $file_id.”_th.$function_suffix”;<br />imagejpeg($new_img, $thumb_name);</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
And then you can upload it just like you did the image:</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
###// Move thumbnail image to uploaddir location<br />if(!@move_uploaded_file($thumb_name, $target_path)){<br />$err = “Couldn’t Copy Thumbnail to Filesystem”;<br />}</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Thanks again for this great script!</div>
</li>
<li class="" id="comment-125" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">Sven</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-125" style="color: #004c94; text-decoration: none;" title="">September 30th, 2008 at 4:50 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
was looking for such a detailed tutorial for quite a while. very cool. however i’m having problems with FF3. in other browsers it’s working fine but with FF3 all i get is “There was an error during file upload!.Unsupported file type, must be JPG|PNG|GIF|BMP.”. of course i’m trying to upload a jpg. any ideas?</div>
</li>
<li class="alt" id="comment-318" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">apex</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-318" style="color: #004c94; text-decoration: none;" title="">January 7th, 2009 at 3:51 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
nice script but thumb’s are not showing. I have tryed suggestions above, but nothing work’s. When i go trough firebug i don’t have any errors in code, but something is not working. Im stuck here please suggest? I use php5 and GD is working fine, tryed in firefox3 and ie6</div>
</li>
<li class="" id="comment-319" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">apex</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-319" style="color: #004c94; text-decoration: none;" title="">January 7th, 2009 at 5:12 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
here, i setup a simple demo (no files are changed).<br />try to upload more than 2 images with no error. i can’t</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://apextest.awardspace.com/" rel="nofollow" style="color: #004c94; text-decoration: none;">http://apextest.awardspace.com/</a></div>
</li>
<li class="alt" id="comment-322" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">push</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-322" style="color: #004c94; text-decoration: none;" title="">January 20th, 2009 at 2:52 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
any idea how to display thumbnails using ajax…. i create the thumbnails on the fly in a php but unable to show that ouput using ajax to the browser… although i f i don use ajax i can see that on browser</div>
</li>
<li class="" id="comment-409" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://www.filhacks.com/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">angelivene</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-409" style="color: #004c94; text-decoration: none;" title="">March 1st, 2009 at 1:10 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
hi, would like to know how to upload multiple files? i already tried the script but unable to select multiple files</div>
</li>
<li class="alt" id="comment-472" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">Jamie</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-472" style="color: #004c94; text-decoration: none;" title="">March 17th, 2009 at 3:02 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
How do I change the script so that it doesnt change the name of the file so if I upload googleLogo.jpg I want the file name on the server to be googleLogo.jpg</div>
</li>
<li class="" id="comment-497" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">Srini</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-497" style="color: #004c94; text-decoration: none;" title="">June 9th, 2009 at 10:51 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Hi,</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
The demo script is working great!<br />Can you please help me on how to retrict to upload only 4 or 5 etc., files.</div>
</li>
<li class="alt" id="comment-576" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">Jason</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-576" style="color: #004c94; text-decoration: none;" title="">October 27th, 2009 at 9:15 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Demo is working great! What is about remove and session destroy? When I don’t want picture then I decided to remove picture but still session keep there should remove session, too.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
For example:</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
I click upload file for picture then uploaded then made a mistake I should click remove then remove picture and memory session should remove like destroy session.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
That’s idea.</div>
</li>
<li class="" id="comment-602" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">CTroy</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-602" style="color: #004c94; text-decoration: none;" title="">July 21st, 2010 at 6:04 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Hi,</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Love the demo script it is working great…<br />Hope you do more of these, this was fun… <img alt=":)" class="wp-smiley" src="http://www.mokisystems.com/blog/wp-includes/images/smilies/icon_smile.gif" style="max-width: 100%; padding: 0px;" /></div>
</li>
<li class="alt" id="comment-978" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://vadevel.com/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">Justin - Web Design Dublin</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-978" style="color: #004c94; text-decoration: none;" title="">January 11th, 2011 at 11:34 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Thanks for the script. I wrote my own image handler with codeigniter but you JavaScript came in very handy. Thanks.</div>
</li>
<li class="" id="comment-1017" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://www.mokisystems.com/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">Andy</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/ajax-multi-file-upload-with-php-iframe-javascript/#comment-1017" style="color: #004c94; text-decoration: none;" title="">June 2nd, 2011 at 1:02 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
I tried Ken’s code and work fine, but can’t save thumbnail image to another folder. Each time the thumbnail image is saved in same folder near original image</div>
</li>
</ol>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-63905146871022415032013-04-05T17:32:00.000-07:002013-04-05T17:32:14.092-07:00Add Markers to a Google Map With Ruby on Rails and JSON<br />
<div class="post" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-bottom: 1em;">
<h2 id="post-27" style="clear: both; color: #333333; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">September 25th, 2008 By: Wes</span></h2>
<div class="entry" style="margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
This tutorial will guide you through creating a map using the Google Maps API that will be dynamically populated with markers as the user zooms or scrolls around the map.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
For this example, we’re going to create and use a generic <code>Location</code> model.</div>
<h3 style="color: #333333; font-size: 12pt;">
Geocoding Your Addresses</h3>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Geocoding will translate an address into its approximate latitude and longitude.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
We’ll use <a href="http://geokit.rubyforge.org/" style="color: #004c94; text-decoration: none;">GeoKit</a>, a Ruby on Rails plugin to geocode our addresses. Install it with:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="bash" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">script<span style="color: black; font-weight: bold;">/</span>plugin <span style="color: #c20cb9; font-weight: bold;">install</span> svn:<span style="color: black; font-weight: bold;">//</span>rubyforge.org<span style="color: black; font-weight: bold;">/</span>var<span style="color: black; font-weight: bold;">/</span>svn<span style="color: black; font-weight: bold;">/</span>geokit<span style="color: black; font-weight: bold;">/</span>trunk</pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Follow the instructions to obtain and install your own Google API key.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Generate the model, controller and views for our map locations:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="bash" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">script<span style="color: black; font-weight: bold;">/</span>generate scaffold location name:string address:string city:string \
state:string <span style="color: #c20cb9; font-weight: bold;">zip</span>:string</pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
We also need to edit the migration file for this model and add fields for the location’s latitude and longitude:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">t.<span style="color: #9900cc;">decimal</span> <span style="color: #ff3333; font-weight: bold;">:lat</span>, <span style="color: #ff3333; font-weight: bold;">:precision</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">15</span>, <span style="color: #ff3333; font-weight: bold;">:scale</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">12</span>
t.<span style="color: #9900cc;">decimal</span> <span style="color: #ff3333; font-weight: bold;">:lng</span>, <span style="color: #ff3333; font-weight: bold;">:precision</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">15</span>, <span style="color: #ff3333; font-weight: bold;">:scale</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">12</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Replace the code in <code>app/models/location.rb</code> with:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #9966cc; font-weight: bold;">class</span> Location <span style="color: #006600; font-weight: bold;"><</span> <span style="color: #6666ff; font-weight: bold;">ActiveRecord::Base</span>
acts_as_mappable
validates_presence_of <span style="color: #ff3333; font-weight: bold;">:name</span>, <span style="color: #ff3333; font-weight: bold;">:address</span>, <span style="color: #ff3333; font-weight: bold;">:city</span>, <span style="color: #ff3333; font-weight: bold;">:state</span>, <span style="color: #ff3333; font-weight: bold;">:zip</span>, <span style="color: #ff3333; font-weight: bold;">:lat</span>, <span style="color: #ff3333; font-weight: bold;">:lng</span>
before_validation_on_create <span style="color: #ff3333; font-weight: bold;">:geocode_address</span>
private
<span style="color: #9966cc; font-weight: bold;">def</span> geocode_address
geo=<span style="color: #6666ff; font-weight: bold;">GeoKit::Geocoders::MultiGeocoder</span>.<span style="color: #9900cc;">geocode</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">"#{address} #{city} #{state} #{zip}"</span><span style="color: #006600; font-weight: bold;">)</span>
errors.<span style="color: #9900cc;">add</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #ff3333; font-weight: bold;">:address</span>, <span style="color: #996600;">"Could not Geocode address"</span><span style="color: #006600; font-weight: bold;">)</span> <span style="color: #9966cc; font-weight: bold;">if</span> !geo.<span style="color: #9900cc;">success</span>
<span style="color: blue; font-weight: bold;">self</span>.<span style="color: #9900cc;">lat</span>, <span style="color: blue; font-weight: bold;">self</span>.<span style="color: #9900cc;">lng</span> = geo.<span style="color: #9900cc;">lat</span>,geo.<span style="color: #9900cc;">lng</span> <span style="color: #9966cc; font-weight: bold;">if</span> geo.<span style="color: #9900cc;">success</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
That’s all there is to geocoding, now any time we create a Location it will automatically be assigned a latitude and longitude.</div>
<h3 style="color: #333333; font-size: 12pt;">
Adding the Google Map</h3>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
In <code>app/views/locations/index.html.erb</code> add:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="css" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><div id=<span style="color: red;">"map"</span> style=<span style="color: red;">"width: 890px; height: 600px;"</span>></div></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
And in <code>app/views/controllers/locations_controller.rb</code>, change the index action to:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: green; font-style: italic;"># GET /locations</span>
<span style="color: green; font-style: italic;"># GET /locations.xml</span>
<span style="color: green; font-style: italic;"># GET /locations.js</span>
<span style="color: #9966cc; font-weight: bold;">def</span> index
respond_to <span style="color: #9966cc; font-weight: bold;">do</span> <span style="color: #006600; font-weight: bold;">|</span>format<span style="color: #006600; font-weight: bold;">|</span>
<span style="color: #cc0066; font-weight: bold;">format</span>.<span style="color: #9900cc;">html</span> <span style="color: #9966cc; font-weight: bold;">do</span>
<span style="color: #0066ff; font-weight: bold;">@locations</span> = Location.<span style="color: #9900cc;">find</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #ff3333; font-weight: bold;">:all</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #cc0066; font-weight: bold;">format</span>.<span style="color: #9900cc;">xml</span> <span style="color: #006600; font-weight: bold;">{</span> render <span style="color: #ff3333; font-weight: bold;">:xml</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #0066ff; font-weight: bold;">@locations</span> <span style="color: #006600; font-weight: bold;">}</span>
<span style="color: #cc0066; font-weight: bold;">format</span>.<span style="color: #9900cc;">js</span> <span style="color: #9966cc; font-weight: bold;">do</span>
ne = params<span style="color: #006600; font-weight: bold;">[</span><span style="color: #ff3333; font-weight: bold;">:ne</span><span style="color: #006600; font-weight: bold;">]</span>.<span style="color: #cc0066; font-weight: bold;">split</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">','</span><span style="color: #006600; font-weight: bold;">)</span>.<span style="color: #9900cc;">collect</span><span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">|</span>e<span style="color: #006600; font-weight: bold;">|</span>e.<span style="color: #9900cc;">to_f</span><span style="color: #006600; font-weight: bold;">}</span>
sw = params<span style="color: #006600; font-weight: bold;">[</span><span style="color: #ff3333; font-weight: bold;">:sw</span><span style="color: #006600; font-weight: bold;">]</span>.<span style="color: #cc0066; font-weight: bold;">split</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">','</span><span style="color: #006600; font-weight: bold;">)</span>.<span style="color: #9900cc;">collect</span><span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">|</span>e<span style="color: #006600; font-weight: bold;">|</span>e.<span style="color: #9900cc;">to_f</span><span style="color: #006600; font-weight: bold;">}</span>
<span style="color: #0066ff; font-weight: bold;">@locations</span> = Location.<span style="color: #9900cc;">find</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #ff3333; font-weight: bold;">:all</span>, <span style="color: #ff3333; font-weight: bold;">:limit</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">100</span>, <span style="color: #ff3333; font-weight: bold;">:bounds</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006600; font-weight: bold;">[</span>sw, ne<span style="color: #006600; font-weight: bold;">]</span><span style="color: #006600; font-weight: bold;">)</span>
render <span style="color: #ff3333; font-weight: bold;">:json</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #0066ff; font-weight: bold;">@locations</span>.<span style="color: #9900cc;">to_json</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
The index action will now respond to javascript requests with a JSON object containing the first 100 Locations inside of the map boundaries.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
In your layout file, add this code inside of the <code><head></code> tag:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #006600; font-weight: bold;"><%</span> <span style="color: #9966cc; font-weight: bold;">unless</span> <span style="color: #0066ff; font-weight: bold;">@locations</span>.<span style="color: #9900cc;">blank</span>? <span style="color: #006600; font-weight: bold;">%></span>
<span style="color: #006600; font-weight: bold;"><</span>script
src=<span style="color: #996600;">"http://maps.google.com/maps?file=api&v=2.x&key=<%= GeoKit::Geocoders::google -%>"</span>
type=<span style="color: #996600;">"text/javascript"</span><span style="color: #006600; font-weight: bold;">></</span>script<span style="color: #006600; font-weight: bold;">></span>
<span style="color: #006600; font-weight: bold;"><%</span>= javascript_include_tag <span style="color: #996600;">'prototype'</span>, <span style="color: #996600;">'maps'</span> <span style="color: #006600; font-weight: bold;">%></span>
<span style="color: #006600; font-weight: bold;"><%</span> <span style="color: #9966cc; font-weight: bold;">end</span> <span style="color: #006600; font-weight: bold;">%></span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
And finally, create a <code>public/javascripts/maps.js</code> file with this code:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="javascript" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">window.<span style="color: #000066;">onunload</span> <span style="color: #339933;">=</span> GUnload<span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> map<span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> markers <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
Event.<span style="color: #006600;">observe</span><span style="color: #009900;">(</span>window<span style="color: #339933;">,</span> <span style="color: #3366cc;">'load'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">(</span>GBrowserIsCompatible<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
map <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> GMap2<span style="color: #009900;">(</span>document.<span style="color: #006600;">getElementById</span><span style="color: #009900;">(</span><span style="color: #3366cc;">"map"</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// Center the map on the US</span>
map.<span style="color: #006600;">setCenter</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">new</span> GLatLng<span style="color: #009900;">(</span><span style="color: #cc0000;">37.731145</span><span style="color: #339933;">,</span><span style="color: #cc0000;">-97.326092</span><span style="color: #009900;">)</span><span style="color: #339933;">,</span><span style="color: #cc0000;">4</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
GEvent.<span style="color: #006600;">addListener</span><span style="color: #009900;">(</span>map<span style="color: #339933;">,</span><span style="color: #3366cc;">"moveend"</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">{</span>updateMap<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span><span style="color: #009900;">}</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
map.<span style="color: #006600;">addControl</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">new</span> GLargeMapControl<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
map.<span style="color: #006600;">addControl</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">new</span> GMapTypeControl<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
updateMap<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> updateMap<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #003366; font-weight: bold;">var</span> bounds <span style="color: #339933;">=</span> map.<span style="color: #006600;">getBounds</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> southWest <span style="color: #339933;">=</span> bounds.<span style="color: #006600;">getSouthWest</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> northEast <span style="color: #339933;">=</span> bounds.<span style="color: #006600;">getNorthEast</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// Send an AJAX request for our locations</span>
<span style="color: #003366; font-weight: bold;">new</span> Ajax.<span style="color: #006600;">Request</span><span style="color: #009900;">(</span><span style="color: #3366cc;">'/locations.js'</span><span style="color: #339933;">,</span> <span style="color: #009900;">{</span>
method<span style="color: #339933;">:</span><span style="color: #3366cc;">'get'</span><span style="color: #339933;">,</span>
parameters<span style="color: #339933;">:</span> <span style="color: #009900;">{</span>sw<span style="color: #339933;">:</span> southWest.<span style="color: #006600;">toUrlValue</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">,</span> ne<span style="color: #339933;">:</span> northEast.<span style="color: #006600;">toUrlValue</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">}</span><span style="color: #339933;">,</span>
onSuccess<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span>transport<span style="color: #009900;">)</span><span style="color: #009900;">{</span>
<span style="color: #006600; font-style: italic;">// Remove markers outside of our maps boundaries.</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">(</span>markers.<span style="color: #006600;">length</span> <span style="color: #339933;">></span> <span style="color: #cc0000;">0</span><span style="color: #009900;">)</span><span style="color: #009900;">{</span>
removeMarkersOutsideOfMapBounds<span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #006600; font-style: italic;">// Add our new markers to the map (unless they are already on the map.)</span>
<span style="color: #003366; font-weight: bold;">var</span> json <span style="color: #339933;">=</span> transport.<span style="color: #006600;">responseText</span>.<span style="color: #006600;">evalJSON</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
json.<span style="color: #006600;">each</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span>i<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
id <span style="color: #339933;">=</span> i.<span style="color: #006600;">location</span>.<span style="color: #006600;">id</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">(</span><span style="color: #339933;">!</span>markers<span style="color: #009900;">[</span>id<span style="color: #009900;">]</span> <span style="color: #339933;">||</span> markers<span style="color: #009900;">[</span>id<span style="color: #009900;">]</span> <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">)</span><span style="color: #009900;">{</span>
<span style="color: #006600; font-style: italic;">// Marker doesnt exist, add it.</span>
markers<span style="color: #009900;">[</span>id<span style="color: #009900;">]</span> <span style="color: #339933;">=</span> createMarker<span style="color: #009900;">(</span>i.<span style="color: #006600;">location</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
map.<span style="color: #006600;">addOverlay</span><span style="color: #009900;">(</span>markers<span style="color: #009900;">[</span>id<span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #003366; font-weight: bold;">function</span> createMarkerClickHandler<span style="color: #009900;">(</span>marker<span style="color: #339933;">,</span> location<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
marker.<span style="color: #006600;">openInfoWindowHtml</span><span style="color: #009900;">(</span>
<span style="color: #3366cc;">'<div><strong>'</span> <span style="color: #339933;">+</span> location.<span style="color: #000066;">name</span> <span style="color: #339933;">+</span> <span style="color: #3366cc;">'</strong><br/> '</span> <span style="color: #339933;">+</span>
location.<span style="color: #006600;">address</span> <span style="color: #339933;">+</span> <span style="color: #3366cc;">'<br/>'</span> <span style="color: #339933;">+</span> location.<span style="color: #006600;">city</span> <span style="color: #339933;">+</span> <span style="color: #3366cc;">', '</span> <span style="color: #339933;">+</span>
location.<span style="color: #006600;">state</span> <span style="color: #339933;">+</span> <span style="color: #3366cc;">' '</span> <span style="color: #339933;">+</span> location.<span style="color: #006600;">zip</span> <span style="color: #339933;">+</span> <span style="color: #3366cc;">'</div>'</span>
<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #003366; font-weight: bold;">function</span> createMarker<span style="color: #009900;">(</span>location<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #003366; font-weight: bold;">var</span> latlng <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> GLatLng<span style="color: #009900;">(</span>location.<span style="color: #006600;">lat</span><span style="color: #339933;">,</span> location.<span style="color: #006600;">lng</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> marker <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> GMarker<span style="color: #009900;">(</span>latlng<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> handler <span style="color: #339933;">=</span> createMarkerClickHandler<span style="color: #009900;">(</span>marker<span style="color: #339933;">,</span> location<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
GEvent.<span style="color: #006600;">addListener</span><span style="color: #009900;">(</span>marker<span style="color: #339933;">,</span> <span style="color: #3366cc;">"click"</span><span style="color: #339933;">,</span> handler<span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #000066; font-weight: bold;">return</span> marker<span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #003366; font-weight: bold;">function</span> removeMarkersOutsideOfMapBounds<span style="color: #009900;">(</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">(</span>i <span style="color: #000066; font-weight: bold;">in</span> markers<span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">(</span>i <span style="color: #339933;">></span> <span style="color: #cc0000;">0</span> <span style="color: #339933;">&&</span> markers<span style="color: #009900;">[</span>i<span style="color: #009900;">]</span> <span style="color: #339933;">&&</span> <span style="color: #339933;">!</span>map.<span style="color: #006600;">getBounds</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span>.<span style="color: #006600;">containsLatLng</span><span style="color: #009900;">(</span>markers<span style="color: #009900;">[</span>i<span style="color: #009900;">]</span>.<span style="color: #006600;">getLatLng</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span><span style="color: #009900;">)</span> <span style="color: #009900;">{</span>
map.<span style="color: #006600;">removeOverlay</span><span style="color: #009900;">(</span>markers<span style="color: #009900;">[</span>i<span style="color: #009900;">]</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
markers<span style="color: #009900;">[</span>i<span style="color: #009900;">]</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span>
<span style="color: #009900;">}</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
The <code>updateMap()</code> function is run after the page initially loads and each time the user moves or zooms the map. It sends an AJAX request to the server with the maps boundaries, and the server returns a JSON object of the locations within those boundaries. After it receives the JSON object, it will add new locations to the map (it skips locations that have already been mapped) and removes locations that are no longer within the visible map boundaries.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
A sample app containing all of the code can be downloaded here: <a href="http://www.mokisystems.com/blog/wp-content/uploads/2008/09/map-sample-code.zip" style="color: #004c94; text-decoration: none;">map-sample-code.zip</a></div>
<div class="postmetadata alt" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; color: #777777; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em; padding: 10px;">
<small style="font-size: 12px; line-height: 1.5em;">This entry was posted on Thursday, September 25th, 2008 at 3:23 pm and is filed under <a href="http://www.mokisystems.com/blog/category/javascript/" rel="category tag" style="color: #004c94; text-decoration: none;" title="View all posts in JavaScript">JavaScript</a>, <a href="http://www.mokisystems.com/blog/category/ruby-on-rails/" rel="category tag" style="color: #004c94; text-decoration: none;" title="View all posts in Ruby on Rails">Ruby on Rails</a>.</small></div>
</div>
</div>
<h3 id="comments" style="background-color: white; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 12pt;">
7 Responses to “Add Markers to a Google Map With Ruby on Rails and JSON”</h3>
<ol class="commentlist" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; padding: 0px;">
<li class="alt" id="comment-305" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://www.recyclelocal.co.uk/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">David H</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/add-markers-to-a-google-map-with-ruby-on-rails-and-json/#comment-305" style="color: #004c94; text-decoration: none;" title="">December 11th, 2008 at 3:14 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Maybe I’m missing something … but I cant find the locations file in your sample code?</div>
</li>
<li class="" id="comment-306" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">Wes Bangerter</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/add-markers-to-a-google-map-with-ruby-on-rails-and-json/#comment-306" style="color: #004c94; text-decoration: none;" title="">December 11th, 2008 at 4:11 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
I’m not sure which location file you are referring to. I double checked and I’m pretty sure everything is in the sample code.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
The model, controller and views are in app/models/location.rb, app/controllers/locations_controller.rb and app/views/locations/ respectively.</div>
</li>
<li class="alt" id="comment-307" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://www.recyclelocal.co.uk/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">David H</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/add-markers-to-a-google-map-with-ruby-on-rails-and-json/#comment-307" style="color: #004c94; text-decoration: none;" title="">December 11th, 2008 at 5:16 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
locations.js?</div>
</li>
<li class="" id="comment-308" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">Wes Bangerter</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/add-markers-to-a-google-map-with-ruby-on-rails-and-json/#comment-308" style="color: #004c94; text-decoration: none;" title="">December 11th, 2008 at 5:27 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
location.js is handled dynamically by Rails. When you access /locations.js it is ending up in app/controllers/locations_controller.rb and rendering the code in the format.js block on line 11.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Basically, /location.js just returns a JSON string with all of the locations that should be displayed on the map, there isn’t any real code in it.</div>
</li>
<li class="alt" id="comment-309" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://www.recyclelocal.co.uk/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">David H</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/add-markers-to-a-google-map-with-ruby-on-rails-and-json/#comment-309" style="color: #004c94; text-decoration: none;" title="">December 12th, 2008 at 3:17 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
I get it now. Thank you for your replies and your great tutorial!</div>
</li>
<li class="" id="comment-477" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">James</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/add-markers-to-a-google-map-with-ruby-on-rails-and-json/#comment-477" style="color: #004c94; text-decoration: none;" title="">April 15th, 2009 at 4:15 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Thanks for this! Every other article seems to suggest clearing and reloading ALL the markers which seems like overkill to me. This looks much simpler.</div>
</li>
<li class="alt" id="comment-558" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">Nauman</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/add-markers-to-a-google-map-with-ruby-on-rails-and-json/#comment-558" style="color: #004c94; text-decoration: none;" title="">September 29th, 2009 at 2:09 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Hi,</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
I m not ROR guru, but doing work in simple php. and want to create boundries around markers as</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.redfin.com/search#search_location=90061" rel="nofollow" style="color: #004c94; text-decoration: none;">http://www.redfin.com/search#search_location=90061</a></div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.maplandia.com/pakistan/punjab/" rel="nofollow" style="color: #004c94; text-decoration: none;">http://www.maplandia.com/pakistan/punjab/</a></div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Can anybody show me the sample result of above code that how it’s looking.</div>
</li>
</ol>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-23116987270203135302013-04-05T17:31:00.001-07:002013-04-05T17:31:04.335-07:00Search Engine Optimization Class<br />
<h2 id="post-33" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">September 29th, 2008 By: brian</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.mokisystems.com/blog/wp-content/uploads/2008/09/dscn3045.jpg" style="color: #004c94; text-decoration: none;"><img alt="" class="alignnone size-medium wp-image-38" height="214" src="http://www.mokisystems.com/blog/wp-content/uploads/2008/09/dscn3045-300x214.jpg" style="border: 0px; max-width: 100%; padding: 0px;" title="dscn3045" width="300" /></a></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Recently Moki Systems was invited to teach, at <a href="http://www.dixie.edu/" style="color: #004c94; text-decoration: none;">Dixie State College</a>, the first class in a series as part of the SEED Dixie program. (<a href="http://www.seedutah.com/" style="color: #004c94; text-decoration: none;">http://www.seedutah.com/</a>)<br /><a href="http://www.mokisystems.com/blog/wp-content/uploads/2008/09/dscn3043.jpg" style="color: #004c94; text-decoration: none;"><img alt="" class="alignnone size-medium wp-image-36" height="214" src="http://www.mokisystems.com/blog/wp-content/uploads/2008/09/dscn3043-300x214.jpg" style="border: 0px; max-width: 100%; padding: 0px;" title="dscn3043" width="300" /></a><br />I’ve uploaded the slides (in Microsoft PowerPoint format) that were used during the class in case any class members want to refer to them. Feel free to comment with any questions you have.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Link to slides: <a href="http://www.mokisystems.com/blog/wp-content/uploads/2008/09/seo.ppt" style="color: #004c94; text-decoration: none;">SEO Presentation</a></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.mokisystems.com/blog/wp-content/uploads/2008/09/dscn3042.jpg" style="color: #004c94; text-decoration: none;"><img alt="" class="alignnone size-medium wp-image-35" height="300" src="http://www.mokisystems.com/blog/wp-content/uploads/2008/09/dscn3042-213x300.jpg" style="border: 0px; max-width: 100%; padding: 0px;" title="dscn3042" width="213" /></a></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.mokisystems.com/blog/wp-content/uploads/2008/09/dscn3044.jpg" style="color: #004c94; text-decoration: none;"><img alt="" class="alignnone size-medium wp-image-37" height="300" src="http://www.mokisystems.com/blog/wp-content/uploads/2008/09/dscn3044-214x300.jpg" style="border: 0px; max-width: 100%; padding: 0px;" title="dscn3044" width="214" /></a></div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-18606531314054387002013-04-05T17:30:00.002-07:002013-04-05T17:30:13.771-07:00Rails Utility Methods<br />
<h2 id="post-41" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">October 20th, 2008 By: Daniel</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Browsing the <a href="http://api.rubyonrails.com/" style="color: #004c94; text-decoration: none;">Rails API</a> I found a few methods I wish I’d known about earlier.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>current_page?</strong> in ActionView::Helpers::UrlHelper returns “true if the current request URI was generated by the given options.”</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"> current_page?<span style="color: #006600; font-weight: bold;">(</span><span style="color: #ff3333; font-weight: bold;">:action</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">'process'</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: green; font-style: italic;"># => false</span>
current_page?<span style="color: #006600; font-weight: bold;">(</span><span style="color: #ff3333; font-weight: bold;">:action</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">'checkout'</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: green; font-style: italic;"># => true</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>reverse_merge!</strong> in ActiveSupport::CoreExtensions::Hash::ReverseMerge “allows for reverse merging where its the keys in the calling hash that wins over those in the other_hash.”</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
So now instead of</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"> <span style="color: #9966cc; font-weight: bold;">def</span> setup<span style="color: #006600; font-weight: bold;">(</span>options = <span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">}</span><span style="color: #006600; font-weight: bold;">)</span>
options = <span style="color: #006600; font-weight: bold;">{</span>:income <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">0</span>, <span style="color: #ff3333; font-weight: bold;">:expenses</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">0</span><span style="color: #006600; font-weight: bold;">}</span>.<span style="color: #9900cc;">merge</span><span style="color: #006600; font-weight: bold;">(</span>options<span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I can do</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"> <span style="color: #9966cc; font-weight: bold;">def</span> setup<span style="color: #006600; font-weight: bold;">(</span>options = <span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">}</span><span style="color: #006600; font-weight: bold;">)</span>
options.<span style="color: #9900cc;">reverse_merge</span>! <span style="color: #ff3333; font-weight: bold;">:income</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">0</span>, <span style="color: #ff3333; font-weight: bold;">:expenses</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">0</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
And with ActiveSupport::CoreExtensions::String::Conversions I can stop using the PHP feeling</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"> <span style="color: #cc00ff; font-weight: bold;">Date</span>.<span style="color: #9900cc;">parse</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">"10/20/2008"</span><span style="color: #006600; font-weight: bold;">)</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
to the more rubyish</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"> <span style="color: #996600;">"10/20/2008"</span>.<span style="color: #9900cc;">to_date</span></pre>
</div>
</div>
</div>
<div class="postmetadata" style="background-color: white; color: #777777; font-family: Futura, Arial, sans-serif; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Posted in <a href="http://www.mokisystems.com/blog/category/ruby-on-rails/" rel="category tag" style="color: #004c94; text-decoration: none;" title="View all posts in Ruby on Rails">Ruby on Rails</a> <strong>|</strong> <a href="http://www.mokisystems.com/blog/rails-utility-methods/#comments" style="color: #004c94; text-decoration: none;" title="Comment on Rails Utility Methods">1 Comment »</a></div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-1441210668596514122013-04-05T17:29:00.002-07:002013-04-05T17:29:32.481-07:00SSH Host Aliases<br />
<h2 id="post-42" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">November 18th, 2008 By: Wes</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
If you use SSH from the command line you can save yourself some typing by aliasing the servers hostname to something shorter. There’s a bunch of different ways to get similar results, but I prefer to use the built in SSH functionality for this. Create a <code>~/.ssh/config</code> file. The syntax is:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="bash" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">Host server
HostName server.example.com
User username
Host another
HostName another.example.com
User username</pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Now you can just <code>ssh server</code> instead of <code>ssh username@example.server.com</code>. SCP also works great with these aliases, just <code>scp file.txt server:/path</code></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
You can leave the <code>User</code> part out of the config file if your local and remote usernames are the same.</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-79454456409089753382013-04-05T17:28:00.007-07:002013-04-05T17:28:54.866-07:00Zebra Striping with jQuery<br />
<h2 id="post-43" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">November 18th, 2008 By: Wes</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Zebra Striping a table with <a href="http://jquery.com/" style="color: #004c94; text-decoration: none;">jQuery</a> is ridiculously easy. This code will add even and odd classes to every row in all tables:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="javascript" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">$<span style="color: #009900;">(</span>document<span style="color: #009900;">)</span>.<span style="color: #006600;">ready</span><span style="color: #009900;">(</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">(</span><span style="color: #009900;">)</span><span style="color: #009900;">{</span>
<span style="color: #006600; font-style: italic;">// Zebra stripe our tables</span>
$<span style="color: #009900;">(</span><span style="color: #3366cc;">"table tr:odd"</span><span style="color: #009900;">)</span>.<span style="color: #006600;">addClass</span><span style="color: #009900;">(</span><span style="color: #3366cc;">"odd"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
$<span style="color: #009900;">(</span><span style="color: #3366cc;">"table tr:even"</span><span style="color: #009900;">)</span>.<span style="color: #006600;">addClass</span><span style="color: #009900;">(</span><span style="color: #3366cc;">"even"</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span>
<span style="color: #009900;">}</span><span style="color: #009900;">)</span><span style="color: #339933;">;</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
You can make it more selective by changing the <code>table</code> part in <code>$("table tr:odd")</code> to something like <code>table.stripe</code>, so it will only apply to tables with a <code>stripe</code> class.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Of course you’ll have to throw in some CSS so the even and odd classes actually do something:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="css" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">table tr<span style="color: #6666ff;">.odd</span> <span style="color: #66cc66;">{</span>
<span style="color: black; font-weight: bold;">background-color</span><span style="color: #66cc66;">:</span> <span style="color: #cc00cc;">#fff</span><span style="color: #66cc66;">;</span>
<span style="color: #66cc66;">}</span>
table tr<span style="color: #6666ff;">.even</span> <span style="color: #66cc66;">{</span>
<span style="color: black; font-weight: bold;">background-color</span><span style="color: #66cc66;">:</span> <span style="color: #cc00cc;">#f3f3f3</span><span style="color: #66cc66;">;</span>
<span style="color: #66cc66;">}</span></pre>
</div>
</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-36254006492869932562013-04-05T17:28:00.004-07:002013-04-05T17:28:15.528-07:00Interesting Google Technique – CSS Sprites<br />
<h2 id="post-47" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">November 21st, 2008 By: brian</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
As I was browsing today, I noticed an interesting technique in use on the Google <a href="http://www.google.com/search?q=google+logo" style="color: #004c94; text-decoration: none;">search results</a> page. The innocent and plain logo at the top left is actually a single image file made up of multiple images which then are made visible by the CSS for each placement:</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.mokisystems.com/blog/wp-content/uploads/2008/11/picture-3.png" style="color: #004c94; text-decoration: none;"><img alt="" class="alignnone size-full wp-image-50" height="343" src="http://www.mokisystems.com/blog/wp-content/uploads/2008/11/picture-3.png" style="border: 0px; max-width: 100%; padding: 0px;" title="google-logo" width="472" /></a></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.mokisystems.com/blog/wp-content/uploads/2008/11/picture-1.png" style="color: #004c94; text-decoration: none;"><img alt="" class="alignnone size-full wp-image-49" height="299" src="http://www.mokisystems.com/blog/wp-content/uploads/2008/11/picture-1.png" style="border: 0px; max-width: 100%; padding: 0px;" title="the-actual-image" width="500" /></a></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
This is presumably for optimization. Every little bit counts when you serve up 20 bazillion hits a minute.</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-23476473669380398042013-04-05T17:27:00.003-07:002013-04-05T17:27:20.000-07:00Using Rails’ New I18n Support in Real Life: Part the First<br />
<h2 id="post-51" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">December 11th, 2008 By: Daniel</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Well, there are plenty of <a href="http://almosteffortless.com/2008/07/21/simple-localization-in-rails-22/" style="color: #004c94; text-decoration: none;">nice</a> <a href="http://railscasts.com/episodes/138-i18n" style="color: #004c94; text-decoration: none;">introductions</a> and <a href="http://i18n-demo.phusion.nl/" style="color: #004c94; text-decoration: none;">demos</a> to <a href="http://www.artweb-design.de/2008/7/18/the-ruby-on-rails-i18n-core-api" style="color: #004c94; text-decoration: none;">Rails’ slick new I18n features</a> out there but I haven’t seen much on using it on a real decent-sized app. So I’ll share some of my thoughts on the subject.<br /><span id="more-51"></span></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Now a real application has more text that just hello_world and a couple paragraphs, so the question is how to organize it all in a way that makes sense. My first thought was to use controllers and actions, but that doesn’t work because sometimes the action doesn’t match the page you are rendering (for example when a create fails validation you probably render the new page even though <em>params[:action]</em> is still ‘create’). So instead I set my namespaces up to mimic my directory/filename structure as much as possible. And in order to make that a lot shorter and cleaner, I wrote a helper method (and put it in application_helper.rb) to help me out:<br /><strong>UPDATE</strong>: Rails 2.3 added “<a href="http://guides.rubyonrails.org/i18n.html#lazy-lookup" style="color: #004c94; text-decoration: none;">lazy</a>” lookup so instead of the ugly __FILE__ stuff you can just prepend a dot. e.g. “.title” I don’t think it woks in controllers though.</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"> <span style="color: green; font-style: italic;"># Translate from file (I18n namespace set to file path)</span>
<span style="color: #9966cc; font-weight: bold;">def</span> tf<span style="color: #006600; font-weight: bold;">(</span>file, key, options = <span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">}</span><span style="color: #006600; font-weight: bold;">)</span>
t<span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">"#{file.gsub(%r|#{RAILS_ROOT}/app/<span style="color: #000099;">\w</span>*/|, '').sub(/<span style="color: #000099;">\.</span>(.*)$/, '').gsub('/', '.')}.#{key}"</span>, options<span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
So now any page that starts with a title looks like this:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"> <h1><%= tf __FILE__, "title" %></h1></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
And I can also use it in my controllers (as long as I <em>include ApplicationHelper</em>):</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"> <span style="color: #9966cc; font-weight: bold;">def</span> create
<span style="color: #0066ff; font-weight: bold;">@agent</span> = Agent.<span style="color: #9900cc;">new</span><span style="color: #006600; font-weight: bold;">(</span>params<span style="color: #006600; font-weight: bold;">[</span><span style="color: #ff3333; font-weight: bold;">:agent</span><span style="color: #006600; font-weight: bold;">]</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #9966cc; font-weight: bold;">if</span> <span style="color: #0066ff; font-weight: bold;">@agent</span>.<span style="color: #9900cc;">save</span>
flash<span style="color: #006600; font-weight: bold;">[</span><span style="color: #ff3333; font-weight: bold;">:notice</span><span style="color: #006600; font-weight: bold;">]</span> = tf<span style="color: #006600; font-weight: bold;">(</span><span style="color: blue; font-weight: bold;">__FILE__</span>, <span style="color: #996600;">'create_s'</span><span style="color: #006600; font-weight: bold;">)</span>
redirect_to documents_url
<span style="color: #9966cc; font-weight: bold;">else</span>
flash<span style="color: #006600; font-weight: bold;">[</span><span style="color: #ff3333; font-weight: bold;">:notice</span><span style="color: #006600; font-weight: bold;">]</span> = tf<span style="color: #006600; font-weight: bold;">(</span><span style="color: blue; font-weight: bold;">__FILE__</span>, <span style="color: #996600;">'create_f'</span><span style="color: #006600; font-weight: bold;">)</span>
render <span style="color: #ff3333; font-weight: bold;">:action</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">'new'</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
And my <em>config/locales/en-US.yml</em> might look like this:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">en-US:
agent_interface:
agents_controller:
create_s: "Agent was successfully created."
create_f: "Error creating agent."
agents:
new:
title: "Create a new Agent"
show:
title: "Showing Agent"
_form:
legend: "Agent Information"
layouts:
agent_interface:
agent_interface:
login: "Log In"
logout: "Log Out"</pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I like this method because not only does it work for the simple cases shown above but it also works great with layouts and partials and helpers.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I think it also helps to set some conventions for yourself. At first I started naming things with numbers (p1, p2, etc) but then I realized that makes views very cryptic to understand. So instead I tried to pick translation keys that explained the text a little better. And then tried to reuse those names when applicable. For instance, quite a few pages have a title, intro, legend, submit, etc. For flash messages I used the action name with an _s appended for successes and _f for failures. In general I tried to be as consistent as possible.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
In future posts I’ll talk about how I <a href="http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-second/" style="color: #004c94; text-decoration: none;">handled images</a>, some <a href="http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-third/" style="color: #004c94; text-decoration: none;">I18n customizations</a> and how I <a href="http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-fourth/" style="color: #004c94; text-decoration: none;">checked</a> for translation coverage.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
P.S. I think it’s pretty ugly to have all those redundant __FILE__s every time I call the helper, but I couldn’t find a good way to get the filename of the file where the method was first called. I tried playing with the stack trace from <code>caller</code> but it got confused on partials and layouts, and I didn’t have the time to find a better way.</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-50087168423616049072013-04-05T17:26:00.003-07:002013-04-05T17:26:40.157-07:00Using Rails’ New I18n Support in Real Life: Part the Second<br />
<div class="post" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-bottom: 1em;">
<h2 id="post-52" style="clear: both; color: #333333; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">December 12th, 2008 By: Daniel</span></h2>
<div class="entry" style="margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
A few more thoughts on handling I18n for real projects.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<span id="more-52"></span></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>Images</strong></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
The way I handled images was pretty simple. Just added this application_helper:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"> <span style="color: green; font-style: italic;"># Translated image tag</span>
<span style="color: #9966cc; font-weight: bold;">def</span> timage_tag<span style="color: #006600; font-weight: bold;">(</span>source, options = <span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">}</span><span style="color: #006600; font-weight: bold;">)</span>
image_tag<span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">"#{I18n.locale}/#{source}"</span>, options<span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Then I created a directory in public/images for each of the supported locales (e.g. public/images/en-US), put all the images with text in there and I was good to go.</div>
<hr style="border-bottom-color: rgb(238, 238, 238); border-bottom-style: solid; border-left-width: 0px; border-right-width: 0px; border-top-color: rgb(204, 204, 204); border-top-style: solid; height: 0px; margin-top: 1em;" />
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>Pagination</strong></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Pagination was handled similarly with a helper to wrap the call to <a href="http://github.com/mislav/will_paginate/wikis" style="color: #004c94; text-decoration: none;">mislav’s will_paginate gem</a>:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"> <span style="color: green; font-style: italic;"># Translated will_paginate</span>
<span style="color: #9966cc; font-weight: bold;">def</span> twill_paginate<span style="color: #006600; font-weight: bold;">(</span>collection = <span style="color: blue; font-weight: bold;">nil</span>, options = <span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">}</span><span style="color: #006600; font-weight: bold;">)</span>
will_paginate collection, <span style="color: #006600; font-weight: bold;">{</span>:previous_label <span style="color: #006600; font-weight: bold;">=></span> t<span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">'constants.will_paginate.previous'</span><span style="color: #006600; font-weight: bold;">)</span>, <span style="color: #ff3333; font-weight: bold;">:next_label</span> <span style="color: #006600; font-weight: bold;">=></span> t<span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">'constants.will_paginate.next'</span><span style="color: #006600; font-weight: bold;">)</span><span style="color: #006600; font-weight: bold;">}</span>.<span style="color: #9900cc;">merge</span><span style="color: #006600; font-weight: bold;">(</span>options<span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"># config/locales/en-US.yml
en-US:
constants:
will_paginate:
previous: "« Previous"
next: "Next »"</pre>
</div>
</div>
<hr style="border-bottom-color: rgb(238, 238, 238); border-bottom-style: solid; border-left-width: 0px; border-right-width: 0px; border-top-color: rgb(204, 204, 204); border-top-style: solid; height: 0px; margin-top: 1em;" />
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<strong>activerecord</strong></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Oh and another thing that really helped was using the human_name stuff <a href="http://iain.nl/2008/09/translating-activerecord/" style="color: #004c94; text-decoration: none;">built in</a> to activerecord. So, for example, everywhere I found an “Agent” in the text instead of an explicit call to <em>translate</em> I could just do<em>Agent.human_name</em>. And for each of Agent’s attributes I could do <em>Agent.human_attribute_name(’name’)</em>. And that even works when it’s not a real attribute, but just one of Agent’s public methods (or anything else for that matter). Plus it’ll work for your form labels too, once you install the <a href="git://github.com/iain/i18n_label.git" style="color: #004c94; text-decoration: none;">i18n label plugin</a>. (One caveat though: <em>label User, :username</em> won’t work. It has to be a <em>form_for(@user) do |f|</em> and then your<em>f.label :username</em> will show the human_attribute_name).</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">#config/locales/en-US.yml
en-US:
activerecord:
models:
agent: "Agent"
attributes:
agent:
name: "Name"
some_calculated_value: "Some Calculated Value"</pre>
</div>
</div>
<div class="postmetadata alt" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; color: #777777; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em; padding: 10px;">
<small style="font-size: 12px; line-height: 1.5em;">This entry was posted on Friday, December 12th, 2008 at 10:36 am and is filed under <a href="http://www.mokisystems.com/blog/category/ruby-on-rails/" rel="category tag" style="color: #004c94; text-decoration: none;" title="View all posts in Ruby on Rails">Ruby on Rails</a>.</small></div>
</div>
</div>
<h3 id="comments" style="background-color: white; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 12pt;">
4 Responses to “Using Rails’ New I18n Support in Real Life: Part the Second”</h3>
<ol class="commentlist" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; padding: 0px;">
<li class="alt" id="comment-310" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-first/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">Moki Systems Blog » Using Rails’ New I18n Support in Real Life: Part the First</a></cite>Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-second/#comment-310" style="color: #004c94; text-decoration: none;" title="">December 12th, 2008 at 10:36 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
[...] Interesting Google Technique Using Rails’ New I18n Support in Real Life: Part the Second [...]</div>
</li>
<li class="" id="comment-313" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://www.metapartei.de/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">Peter</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-second/#comment-313" style="color: #004c94; text-decoration: none;" title="">December 20th, 2008 at 6:13 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Thanks a lot for this!</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
For me the following code worked (the previous_label wasn’t working …):<br />def t_will_paginate(collection = nil, options = {})<br />will_paginate collection, {:prev_label => t(’constants.will_paginate.previous’),<br />:next_label => t(’constants.will_paginate.next’)}.merge(options)<br />end</div>
</li>
<li class="alt" id="comment-325" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">gemini</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-second/#comment-325" style="color: #004c94; text-decoration: none;" title="">January 31st, 2009 at 1:29 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
my project requires a very odd situation.<br />how can i put the next button at the left side?<br />and also, how can i put square brackets before the first link and after the last link which the user can not click.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
eg. the page should look like this</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Next> [ 1 2 3 4 5 ]</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
thanks in advance</div>
</li>
<li class="" id="comment-327" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">Daniel</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-second/#comment-327" style="color: #004c94; text-decoration: none;" title="">February 4th, 2009 at 9:54 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
@gemini Sounds like you need to customize the will_paginate helpers.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://thewebfellas.com/blog/2008/8/3/roll-your-own-pagination-links-with-will_paginate" rel="nofollow" style="color: #004c94; text-decoration: none;">http://thewebfellas.com/blog/2008/8/3/roll-your-own-pagination-links-with-will_paginate</a></div>
</li>
</ol>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-78457788404283314952013-04-05T17:25:00.005-07:002013-04-05T17:25:47.371-07:00Using Rails’ New I18n Support in Real Life: Part the Third<br />
<h2 id="post-53" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">December 15th, 2008 By: Daniel</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
What happens when you add a new string to your default locale file and forget about the other languages? Well, by default it’ll raise a MissingTranslationData and your users will see an ugly string the likes of “<em>es-MX, marketing_interface, index, title</em>“. Wouldn’t it be better to at least try and default to English? My guess is that most people would prefer to see the message in another language than some cryptic error message. And while we’re wishing, don’t you think the <em>localize</em> method shouldn’t die a noisy death when you happen to pass it a nil?</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
My solution? A custom I18n backend. I simply copy/pasted the code from the default “Simple” backend, tweaked a few lines and I was good to go!</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: green; font-style: italic;"># In some file that gets sourced on startup, like maybe in your config/initializers directory</span>
<span style="color: #9966cc; font-weight: bold;">module</span> I18n
<span style="color: #9966cc; font-weight: bold;">module</span> Backend
<span style="color: #9966cc; font-weight: bold;">class</span> Moki <span style="color: #006600; font-weight: bold;"><</span> Simple
<span style="color: #9966cc; font-weight: bold;">def</span> translate<span style="color: #006600; font-weight: bold;">(</span>locale, key, options = <span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">}</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #cc0066; font-weight: bold;">raise</span> InvalidLocale.<span style="color: #9900cc;">new</span><span style="color: #006600; font-weight: bold;">(</span>locale<span style="color: #006600; font-weight: bold;">)</span> <span style="color: #9966cc; font-weight: bold;">if</span> locale.<span style="color: blue; font-weight: bold;">nil</span>?
<span style="color: blue; font-weight: bold;">return</span> key.<span style="color: #9900cc;">map</span> <span style="color: #006600; font-weight: bold;">{</span> <span style="color: #006600; font-weight: bold;">|</span>k<span style="color: #006600; font-weight: bold;">|</span> translate<span style="color: #006600; font-weight: bold;">(</span>locale, k, options<span style="color: #006600; font-weight: bold;">)</span> <span style="color: #006600; font-weight: bold;">}</span> <span style="color: #9966cc; font-weight: bold;">if</span> key.<span style="color: #9900cc;">is_a</span>? <span style="color: #cc0066; font-weight: bold;">Array</span>
reserved = <span style="color: #ff3333; font-weight: bold;">:scope</span>, <span style="color: #ff3333; font-weight: bold;">:default</span>
count, scope, default = options.<span style="color: #9900cc;">values_at</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #ff3333; font-weight: bold;">:count</span>, <span style="color: #006600; font-weight: bold;">*</span>reserved<span style="color: #006600; font-weight: bold;">)</span>
options.<span style="color: #9900cc;">delete</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #ff3333; font-weight: bold;">:default</span><span style="color: #006600; font-weight: bold;">)</span>
values = options.<span style="color: #9900cc;">reject</span> <span style="color: #006600; font-weight: bold;">{</span> <span style="color: #006600; font-weight: bold;">|</span>name, value<span style="color: #006600; font-weight: bold;">|</span> reserved.<span style="color: #9966cc; font-weight: bold;">include</span>?<span style="color: #006600; font-weight: bold;">(</span>name<span style="color: #006600; font-weight: bold;">)</span> <span style="color: #006600; font-weight: bold;">}</span>
entry = lookup<span style="color: #006600; font-weight: bold;">(</span>locale, key, scope<span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #9966cc; font-weight: bold;">if</span> entry.<span style="color: blue; font-weight: bold;">nil</span>?
entry = default<span style="color: #006600; font-weight: bold;">(</span>locale, default, options<span style="color: #006600; font-weight: bold;">)</span>
entry <span style="color: #006600; font-weight: bold;">||</span>= lookup<span style="color: #006600; font-weight: bold;">(</span>I18n.<span style="color: #9900cc;">default_locale</span>, key, scope<span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #cc0066; font-weight: bold;">raise</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #6666ff; font-weight: bold;">I18n::MissingTranslationData</span>.<span style="color: #9900cc;">new</span><span style="color: #006600; font-weight: bold;">(</span>locale, key, options<span style="color: #006600; font-weight: bold;">)</span><span style="color: #006600; font-weight: bold;">)</span> <span style="color: #9966cc; font-weight: bold;">if</span> entry.<span style="color: blue; font-weight: bold;">nil</span>?
<span style="color: #9966cc; font-weight: bold;">end</span>
entry = pluralize<span style="color: #006600; font-weight: bold;">(</span>locale, entry, count<span style="color: #006600; font-weight: bold;">)</span>
entry = interpolate<span style="color: #006600; font-weight: bold;">(</span>locale, entry, values<span style="color: #006600; font-weight: bold;">)</span>
entry
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">def</span> localize<span style="color: #006600; font-weight: bold;">(</span>locale, object, <span style="color: #cc0066; font-weight: bold;">format</span> = <span style="color: #ff3333; font-weight: bold;">:default</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: blue; font-weight: bold;">return</span> <span style="color: blue; font-weight: bold;">nil</span> <span style="color: #9966cc; font-weight: bold;">if</span> object.<span style="color: blue; font-weight: bold;">nil</span>?
<span style="color: #cc0066; font-weight: bold;">raise</span> <span style="color: #cc00ff; font-weight: bold;">ArgumentError</span>, <span style="color: #996600;">"Object must be a Date, DateTime or Time object. #{object.inspect} given."</span> <span style="color: #9966cc; font-weight: bold;">unless</span> object.<span style="color: #9900cc;">respond_to</span>?<span style="color: #006600; font-weight: bold;">(</span><span style="color: #ff3333; font-weight: bold;">:strftime</span><span style="color: #006600; font-weight: bold;">)</span>
type = object.<span style="color: #9900cc;">respond_to</span>?<span style="color: #006600; font-weight: bold;">(</span><span style="color: #ff3333; font-weight: bold;">:sec</span><span style="color: #006600; font-weight: bold;">)</span> ? <span style="color: #996600;">'time'</span> : <span style="color: #996600;">'date'</span>
formats = translate<span style="color: #006600; font-weight: bold;">(</span>locale, <span style="color: #996600;">"#{type}.formats"</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #cc0066; font-weight: bold;">format</span> = formats<span style="color: #006600; font-weight: bold;">[</span><span style="color: #cc0066; font-weight: bold;">format</span>.<span style="color: #9900cc;">to_sym</span><span style="color: #006600; font-weight: bold;">]</span> <span style="color: #9966cc; font-weight: bold;">if</span> formats <span style="color: #006600; font-weight: bold;">&&</span> formats<span style="color: #006600; font-weight: bold;">[</span><span style="color: #cc0066; font-weight: bold;">format</span>.<span style="color: #9900cc;">to_sym</span><span style="color: #006600; font-weight: bold;">]</span>
<span style="color: #cc0066; font-weight: bold;">format</span> = <span style="color: #cc0066; font-weight: bold;">format</span>.<span style="color: #9900cc;">to_s</span>.<span style="color: #9900cc;">dup</span>
<span style="color: #cc0066; font-weight: bold;">format</span>.<span style="color: #cc0066; font-weight: bold;">gsub</span>!<span style="color: #006600; font-weight: bold;">(</span><span style="color: #006600; font-weight: bold;">/%</span>a<span style="color: #006600; font-weight: bold;">/</span>, translate<span style="color: #006600; font-weight: bold;">(</span>locale, <span style="color: #996600;">"date.abbr_day_names"</span><span style="color: #006600; font-weight: bold;">)</span><span style="color: #006600; font-weight: bold;">[</span>object.<span style="color: #9900cc;">wday</span><span style="color: #006600; font-weight: bold;">]</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #cc0066; font-weight: bold;">format</span>.<span style="color: #cc0066; font-weight: bold;">gsub</span>!<span style="color: #006600; font-weight: bold;">(</span><span style="color: #006600; font-weight: bold;">/%</span>A<span style="color: #006600; font-weight: bold;">/</span>, translate<span style="color: #006600; font-weight: bold;">(</span>locale, <span style="color: #996600;">"date.day_names"</span><span style="color: #006600; font-weight: bold;">)</span><span style="color: #006600; font-weight: bold;">[</span>object.<span style="color: #9900cc;">wday</span><span style="color: #006600; font-weight: bold;">]</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #cc0066; font-weight: bold;">format</span>.<span style="color: #cc0066; font-weight: bold;">gsub</span>!<span style="color: #006600; font-weight: bold;">(</span><span style="color: #006600; font-weight: bold;">/%</span>b<span style="color: #006600; font-weight: bold;">/</span>, translate<span style="color: #006600; font-weight: bold;">(</span>locale, <span style="color: #996600;">"date.abbr_month_names"</span><span style="color: #006600; font-weight: bold;">)</span><span style="color: #006600; font-weight: bold;">[</span>object.<span style="color: #9900cc;">mon</span><span style="color: #006600; font-weight: bold;">]</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #cc0066; font-weight: bold;">format</span>.<span style="color: #cc0066; font-weight: bold;">gsub</span>!<span style="color: #006600; font-weight: bold;">(</span><span style="color: #006600; font-weight: bold;">/%</span>B<span style="color: #006600; font-weight: bold;">/</span>, translate<span style="color: #006600; font-weight: bold;">(</span>locale, <span style="color: #996600;">"date.month_names"</span><span style="color: #006600; font-weight: bold;">)</span><span style="color: #006600; font-weight: bold;">[</span>object.<span style="color: #9900cc;">mon</span><span style="color: #006600; font-weight: bold;">]</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #cc0066; font-weight: bold;">format</span>.<span style="color: #cc0066; font-weight: bold;">gsub</span>!<span style="color: #006600; font-weight: bold;">(</span><span style="color: #006600; font-weight: bold;">/%</span><span style="color: #cc0066; font-weight: bold;">p</span><span style="color: #006600; font-weight: bold;">/</span>, translate<span style="color: #006600; font-weight: bold;">(</span>locale, <span style="color: #996600;">"time.#{object.hour < 12 ? :am : :pm}"</span><span style="color: #006600; font-weight: bold;">)</span><span style="color: #006600; font-weight: bold;">)</span> <span style="color: #9966cc; font-weight: bold;">if</span> object.<span style="color: #9900cc;">respond_to</span>? <span style="color: #ff3333; font-weight: bold;">:hour</span>
object.<span style="color: #9900cc;">strftime</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #cc0066; font-weight: bold;">format</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
I18n.<span style="color: #9900cc;">backend</span> = <span style="color: #6666ff; font-weight: bold;">I18n::Backend::Moki</span>.<span style="color: #9900cc;">new</span></pre>
</div>
</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-30880602807969385432013-04-05T17:25:00.001-07:002013-04-05T17:25:05.113-07:00Using Rails’ New I18n Support in Real Life: Part the Fourth<br />
<h2 id="post-54" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">December 16th, 2008 By: Daniel</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
So after tediously going through your entire site and extracting all displayed strings to a separate translation file, how do you know you didn’t miss something somewhere? My solution was to create a quick rake task that machine translates my English yaml file to something else. A quick <em>sudo aptitude install bsdgames</em> and I had pig latin at my fingertips. So I switched to that and browsed through the site and looked for anything that hadn’t changed. And I found quite a bit of stuff that I had missed.</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: green; font-style: italic;"># lib/tasks/pig.rake</span>
desc <span style="color: #996600;">"Creates a config/locales/pig-US.yml from config/locales/en-US.yml"</span>
task <span style="color: #ff3333; font-weight: bold;">:pig</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #ff3333; font-weight: bold;">:environment</span> <span style="color: #9966cc; font-weight: bold;">do</span>
DEFAULT_LOCALE = <span style="color: #996600;">'en-US'</span>
<span style="color: #cc00ff; font-weight: bold;">File</span>.<span style="color: #cc0066; font-weight: bold;">open</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #cc00ff; font-weight: bold;">File</span>.<span style="color: #9900cc;">join</span><span style="color: #006600; font-weight: bold;">(</span>RAILS_ROOT, <span style="color: #996600;">'config'</span>, <span style="color: #996600;">'locales'</span>, <span style="color: #996600;">'pig-US.yml'</span><span style="color: #006600; font-weight: bold;">)</span>, <span style="color: #996600;">"w"</span><span style="color: #006600; font-weight: bold;">)</span> <span style="color: #9966cc; font-weight: bold;">do</span> <span style="color: #006600; font-weight: bold;">|</span>fout<span style="color: #006600; font-weight: bold;">|</span>
<span style="color: #cc00ff; font-weight: bold;">File</span>.<span style="color: #cc0066; font-weight: bold;">readlines</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #cc00ff; font-weight: bold;">File</span>.<span style="color: #9900cc;">join</span><span style="color: #006600; font-weight: bold;">(</span>RAILS_ROOT, <span style="color: #996600;">'config'</span>, <span style="color: #996600;">'locales'</span>, <span style="color: #996600;">"#{DEFAULT_LOCALE}.yml"</span><span style="color: #006600; font-weight: bold;">)</span><span style="color: #006600; font-weight: bold;">)</span>.<span style="color: #9900cc;">each</span> <span style="color: #9966cc; font-weight: bold;">do</span> <span style="color: #006600; font-weight: bold;">|</span>line<span style="color: #006600; font-weight: bold;">|</span>
<span style="color: #9966cc; font-weight: bold;">unless</span> line =~ <span style="color: #006600; font-weight: bold;">/</span><span style="color: #996600;">"/
fout.puts line.sub(DEFAULT_LOCALE, 'pig-US')
else
key, *translation = line.split(':')
translation = translation.join(':')
translation.split(/("</span>.<span style="color: #9900cc;">*</span>?<span style="color: #996600;">")/).each do |quote|
if quote =~ /"</span><span style="color: #006600; font-weight: bold;">/</span>
quote.<span style="color: #cc0066; font-weight: bold;">gsub</span>!<span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">'"'</span>, <span style="color: #996600;">''</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #cc0066; font-weight: bold;">string</span> = quote.<span style="color: #cc0066; font-weight: bold;">split</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #006600; font-weight: bold;">/</span><span style="color: #006600; font-weight: bold;">(</span>\<span style="color: #006600; font-weight: bold;">{</span>\<span style="color: #006600; font-weight: bold;">{</span>.<span style="color: #9900cc;">*</span>?\<span style="color: #006600; font-weight: bold;">}</span>\<span style="color: #006600; font-weight: bold;">}</span><span style="color: #006600; font-weight: bold;">)</span><span style="color: #006600; font-weight: bold;">/</span><span style="color: #006600; font-weight: bold;">)</span>.<span style="color: #9900cc;">map</span> <span style="color: #9966cc; font-weight: bold;">do</span> <span style="color: #006600; font-weight: bold;">|</span>s<span style="color: #006600; font-weight: bold;">|</span>
<span style="color: #006600; font-weight: bold;">(</span>s =~ <span style="color: #006600; font-weight: bold;">/</span>\<span style="color: #006600; font-weight: bold;">{</span>\<span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">/</span><span style="color: #006600; font-weight: bold;">)</span> ? s : <span style="color: #996600;">`echo "#{s.gsub('$', '<span style="color: #000099;">\$</span>')}" | pig`</span>.<span style="color: #cc0066; font-weight: bold;">chomp</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
translation.<span style="color: #cc0066; font-weight: bold;">sub</span>!<span style="color: #006600; font-weight: bold;">(</span>quote, <span style="color: #cc0066; font-weight: bold;">string</span>.<span style="color: #9900cc;">join</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
fout.<span style="color: #cc0066; font-weight: bold;">puts</span> <span style="color: #996600;">"#{key}:#{translation}"</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
P.S. Note to anyone that actually tries to use this: This is just a quick and dirty script and will probably require some modification to work in your situation. In particular it requires all the strings you want translated to be within double quotes.</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-34832457370047125632013-04-05T17:24:00.002-07:002013-04-05T17:24:11.420-07:00Vim as a Ruby on Rails IDE<br />
<h2 id="post-56" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">December 29th, 2008 By: Daniel</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
In the words of <a href="http://www.vim.org/scripts/script.php?script_id=1567" style="color: #004c94; text-decoration: none;">Tim Pope</a> “TextMate may be the latest craze for developing Ruby on Rails applications, but Vim is forever”</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Here’s how I use vim (and gnome-terminal) to program in Rails on Ubuntu.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I have a <a href="http://github.com/eremite/binfiles/tree/master/zvim_rails_ide" style="color: #004c94; text-decoration: none;">ruby script</a> that opens two gnome-terminals each with 9 tabs each. That may seem like a lot, but each one is assigned a specific purpose and by now my fingers know just where to go depending on the task at hand. For example, models, views and controllers each get their own tab. So if I need to edit a model my fingers will do an <alt-1>vim model_name.rb (or :e model_name.rb if I’m already in vim). And of course <a href="http://github.com/eremite/dotfiles/tree/master/bashrc" style="color: #004c94; text-decoration: none;">bash aliases</a> and tab_completion minimizes the actual number of keystrokes required. In the same way, I know exactly where to go to watch the log, play in the console, use the SCM or anything else.</alt-1></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.mokisystems.com/blog/wp-content/uploads/2008/12/zvim_rails_ide.png" style="color: #004c94; text-decoration: none;"><img alt="My Vim Rails IDE" class="alignnone size-medium wp-image-57" height="174" src="http://www.mokisystems.com/blog/wp-content/uploads/2008/12/zvim_rails_ide-300x174.png" style="border: 0px; max-width: 100%; padding: 0px;" title="vim_rails_ide" width="300" /></a></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
So that’s what it actually looks like. Notice how I have Gmail in the background so I can know immediately when I get a new email or IM (and ignore it at my leisure). Not shown is a separate Firefox window running on my other monitor so that I can see both the code and the running application at the same time.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Now, I have some doubts as to how well my solution would work for other people as it requires a bit of discipline to make sure <a href="http://www.google.com/search?hl=en&q=%22A+place+for+everything+and+everything+in+its+place%22&btnG=Search" style="color: #004c94; text-decoration: none;">everything has a place</a> and to train yourself to always do things in the right place. It seems <a href="http://weblog.jamisbuck.org/2008/10/10/coming-home-to-vim" style="color: #004c94; text-decoration: none;">most people</a> prefer to have only a few windows (or tabs or buffers or whatever) open and use some sort of <a href="http://github.com/jamis/fuzzyfinder_textmate/tree/master" style="color: #004c94; text-decoration: none;">fuzzy finder</a> or <a href="http://www.vim.org/scripts/script.php?script_id=1658" style="color: #004c94; text-decoration: none;">file explorer</a> to find the file they want to work on next. But that’s what I love about vim. I can come up with a custom workflow that works for me instead of conforming to the whims of some dictatorial IDE. True, the learning curve was quite steep at first, and I still occasionally invest some of my time in learning how to use additional features and <a href="http://github.com/eremite/dotfiles/tree/master/vimrc" style="color: #004c94; text-decoration: none;">customizations</a>, but now contemplating using another text editor is like going back to riding tricycles after learning to fly jet planes.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Here’s the current version of the ruby script in case anyone’s interested. I call it zvim_rails_ide so I can use it with a quick zv<tab>.</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: green; font-style: italic;">#!/usr/bin/env ruby</span>
<span style="color: #9966cc; font-weight: bold;">if</span> ARGV.<span style="color: #9900cc;">size</span>.<span style="color: #9900cc;">zero</span>?
<span style="color: #cc0066; font-weight: bold;">puts</span> <span style="color: #996600;">"Usage: #{File.basename($0)} name_of_project"</span>
<span style="color: #cc0066; font-weight: bold;">exit</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
RAILS_ROOT = <span style="color: #cc00ff; font-weight: bold;">File</span>.<span style="color: #9900cc;">join</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #cc00ff; font-weight: bold;">Dir</span>.<span style="color: #9900cc;">pwd</span>, ARGV<span style="color: #006600; font-weight: bold;">[</span><span style="color: #006666;">0</span><span style="color: #006600; font-weight: bold;">]</span><span style="color: #006600; font-weight: bold;">)</span>
RAILS_ROOT <span style="color: #006600; font-weight: bold;"><<</span> <span style="color: #996600;">'/'</span> <span style="color: #9966cc; font-weight: bold;">unless</span> RAILS_ROOT<span style="color: #006600; font-weight: bold;">[</span><span style="color: #006666;">0</span><span style="color: #006600; font-weight: bold;">]</span> =~ <span style="color: #006600; font-weight: bold;">%</span>r<span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">/</span>$<span style="color: #006600; font-weight: bold;">}</span>
<span style="color: #9966cc; font-weight: bold;">unless</span> <span style="color: #cc00ff; font-weight: bold;">File</span>.<span style="color: #9900cc;">exists</span>?<span style="color: #006600; font-weight: bold;">(</span>RAILS_ROOT<span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #cc0066; font-weight: bold;">puts</span> <span style="color: #996600;">"#{RAILS_ROOT}: No such file or directory"</span>
<span style="color: #cc0066; font-weight: bold;">exit</span>
<span style="color: #9966cc; font-weight: bold;">end</span>
ls = <span style="color: #996600;">"ls --color"</span>
scm = <span style="color: #cc00ff; font-weight: bold;">File</span>.<span style="color: #9900cc;">exists</span>?<span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">'.git'</span><span style="color: #006600; font-weight: bold;">)</span> ? <span style="color: #996600;">'git status'</span> : <span style="color: #996600;">'svn status'</span>
test_dir = <span style="color: #cc00ff; font-weight: bold;">File</span>.<span style="color: #9900cc;">exists</span>?<span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">"#{RAILS_ROOT}spec"</span><span style="color: #006600; font-weight: bold;">)</span> ? <span style="color: #996600;">'spec'</span> : <span style="color: #996600;">'test'</span>
<span style="color: #006600; font-weight: bold;">[</span>
<span style="color: #006600; font-weight: bold;">{</span>
<span style="color: #ff3333; font-weight: bold;">:geometry</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">"140x38+90+270"</span>,
<span style="color: #ff3333; font-weight: bold;">:tabs</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006600; font-weight: bold;">[</span>
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">"app/models"</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">"app/views"</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">"app/controllers"</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">"app/helpers"</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">"public"</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">"vendor"</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> test_dir, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> test_dir, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">""</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>
<span style="color: #006600; font-weight: bold;">]</span>
<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>
<span style="color: #ff3333; font-weight: bold;">:geometry</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">"141x32+185+110"</span>,
<span style="color: #ff3333; font-weight: bold;">:tabs</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006600; font-weight: bold;">[</span>
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">""</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> scm<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">""</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">"lib"</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">""</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">"ruby script/console"</span><span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">""</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">"config/locales"</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">""</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">""</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>,
<span style="color: #006600; font-weight: bold;">{</span>:path <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">""</span>, <span style="color: #ff3333; font-weight: bold;">:command</span> <span style="color: #006600; font-weight: bold;">=></span> ls<span style="color: #006600; font-weight: bold;">}</span>
<span style="color: #006600; font-weight: bold;">]</span>
<span style="color: #006600; font-weight: bold;">}</span>
<span style="color: #006600; font-weight: bold;">]</span>.<span style="color: #9900cc;">each</span> <span style="color: #9966cc; font-weight: bold;">do</span> <span style="color: #006600; font-weight: bold;">|</span>window<span style="color: #006600; font-weight: bold;">|</span>
tabs = window<span style="color: #006600; font-weight: bold;">[</span><span style="color: #ff3333; font-weight: bold;">:tabs</span><span style="color: #006600; font-weight: bold;">]</span>.<span style="color: #9900cc;">map</span> <span style="color: #006600; font-weight: bold;">{</span><span style="color: #006600; font-weight: bold;">|</span>tab<span style="color: #006600; font-weight: bold;">|</span> <span style="color: #996600;">"--tab-with-profile=DEFAULT --working-directory='#{RAILS_ROOT}#{tab[:path]}' -e <span style="color: #000099;">\"</span>bash -c '#{tab[:command]}; bash'<span style="color: #000099;">\"</span>"</span><span style="color: #006600; font-weight: bold;">}</span>.<span style="color: #9900cc;">join</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #996600;">' '</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #cc0066; font-weight: bold;">system</span> <span style="color: #996600;">"gnome-terminal --geometry #{window[:geometry]} #{tabs}"</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-40106827419298207482013-04-05T17:22:00.002-07:002013-04-05T17:22:15.481-07:00A Couple Rails Find Gotchas<br />
<div class="post" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-bottom: 1em;">
<h2 id="post-59" style="clear: both; color: #333333; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">March 3rd, 2009 By: Daniel</span></h2>
<div class="entry" style="margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
We ran into a few little gotchas with ActiveRecord’s find method when upgrading from Rails 2.1.1 to 2.2.2. The solutions are pretty trivial, so the main lesson here is to test your code so things like this get caught by your test suite and not the client.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<span id="more-59"></span></div>
<h3 style="color: #333333; font-size: 12pt;">
Gotcha #1</h3>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<code><br />>> Rails.version<br />=> "2.1.1"<br />>> Client.find_all_by_notify_by(%w(email txt both)).size<br />=> 2</code></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<code><br />>> Rails.version<br />=> "2.2.2"<br />>> Client.find_all_by_notify_by(%w(email txt both)).size<br />ActiveRecord::StatementInvalid: Mysql::Error: Operand should contain 1 column(s): SELECT * FROM `clients` WHERE (notify_by = 'email','txt','both' AND clients.deleted_at IS NULL)<br />>> Client.find(:all, :conditions => ["notify_by = ? OR notify_by = ? OR notify_by = ?", *%w(email txt both)]).size<br />=> 2</code></div>
<h3 style="color: #333333; font-size: 12pt;">
Gotcha #2</h3>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<code><br />>> Rails.version<br />=> "2.1.1"<br />>> Client.find_all_by_agent_id(nil).size<br />=> 26</code></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<code><br />>> Rails.version<br />=> "2.2.2"<br />>> Client.find_all_by_agent_id(nil).size<br />=> 0<br />>> Client.find(:all, :conditions => "agent_id IS NULL").size<br />=> 26</code></div>
<div class="postmetadata alt" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; color: #777777; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em; padding: 10px;">
<small style="font-size: 12px; line-height: 1.5em;">This entry was posted on Tuesday, March 3rd, 2009 at 10:07 am and is filed under <a href="http://www.mokisystems.com/blog/category/ruby-on-rails/" rel="category tag" style="color: #004c94; text-decoration: none;" title="View all posts in Ruby on Rails">Ruby on Rails</a>.</small></div>
</div>
</div>
<h3 id="comments" style="background-color: white; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 12pt;">
5 Responses to “A Couple Rails Find Gotchas”</h3>
<ol class="commentlist" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; padding: 0px;">
<li class="alt" id="comment-483" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://danahern.com/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">Dan Ahern</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/#comment-483" style="color: #004c94; text-decoration: none;" title="">April 29th, 2009 at 5:53 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Hi Daniel,<br />I would like to point out a couple of things. First off, I would tend to avoid writing code with the named finders. The reason for this is that they are really a hack, what they do is wait for the undefined method error and then catch it and build the query from there. Repetitive use of those can slow your page load down.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Second, what I would recommend rather than using the array conditions method is to instead switch over to using a hash, much of the issue would be easily solved by using the hash. For example<br />Client.find(:all, :conditions => {:notify_by => %w(email txt both)}) will generate an sql query SELECT * FROM clients WHERE notify_by in (’email’,'txt’,'both’);</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
With the new Rails 2.2+ you can do neat things with the conditions hash as well like putting a condition for another table.<br />Client.find(:all, :conditions => {’projects.payment_type’ => %w(paying nonpaying both)}, :join => :project)<br />will generate<br />SELECT * FROM clients LEFT JOIN projects on clients.id = projects.client_id WHERE projects.payment_type in (’paying’,'nonpaying’,'both’);</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
You also aren’t just limited to arrays.<br />Client.find(:all, :conditions => {:activated => true})<br />Will generate the expected where activated = 1<br />Client.find(:all, :conditions => {:created_at => (Time.now-30.days)..Time.now})<br />Will generate created_at BETWEEN (’2009-04-1′, ‘2009-04-30′)<br />Client.find(:all, :conditions => {:agent => nil})<br />Will generate agent IS NULL</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
The only time you should need to slip back to your array conditions is when you have to do less than () or when dealing with much more complex conditions statements.</div>
</li>
<li class="" id="comment-484" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;">Daniel</cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/#comment-484" style="color: #004c94; text-decoration: none;" title="">April 30th, 2009 at 9:02 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Thanks for the pointers. They should clean up my code a bit as the hash conditions are a lot more readable than the array ones. Yet all too often I still find myself needing < , > or IS NOT NULL.</div>
</li>
<li class="alt" id="comment-486" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://danahern.com/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">Dan Ahern</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/#comment-486" style="color: #004c94; text-decoration: none;" title="">May 12th, 2009 at 8:49 pm</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
No problem, I really fell in love with the hash style syntax when I first realized it was available. It just makes a lot more sense than the Array format.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
One thing while I was digging around in to the BDD world that I found today was Squirrel by ThoughtBot.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.thoughtbot.com/projects/squirrel/" rel="nofollow" style="color: #004c94; text-decoration: none;">http://www.thoughtbot.com/projects/squirrel/</a></div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
This allows for Ruby blocks into the find method. I haven’t had a chance to use this yet but I think it would help to move completely out of the ActiveRecord Array conditions syntax.</div>
</li>
<li class="" id="comment-490" style="font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://www.marnen.org/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">Marnen Laibow-Koser</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/#comment-490" style="color: #004c94; text-decoration: none;" title="">May 16th, 2009 at 12:27 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
[Resubmitting with nonbreaking spaces for indentation.]</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Dan Ahern: AFAIK, the named finders are *not* a performance problem. I haven’t verified this in the ActiveRecord source code, but I remember reading (on the Rails list?) that AR is rather clever in this regard.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
Basically, IIRC, method_missing is invoked *only the first time* that a named finder is encountered, then it caches the method for future calls. I guess it would be something like this (in concept, not necessarily implementation):</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
class Person < ActiveRecord::Base<br /> def method_missing(name, *args, &block)<br /> if name.to_s =~ /^find_by_/<br /> method = Proc.new { #some dynamic finder code }<br /> class << self.class<br /> self.define_method(name, method)<br /> end<br /> self.send(name, *args, block)<br /> end<br /> end<br />end</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
…so that the first time Person.find_by_name is called, you do incur the method_missing overhead — but the second time Person.find_by_name is called, it exists as a real method, so method_missing doesn’t come into play.</div>
<div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
So don’t worry about dynamic finders for performance, so long as you’re not using too many different ones.</div>
</li>
<li class="alt" id="comment-492" style="background-color: #f8f8f8; border-bottom-color: rgb(221, 221, 221); border-bottom-style: solid; border-bottom-width: 1px; border-top-color: rgb(221, 221, 221); border-top-style: solid; border-top-width: 1px; font-size: 0.9em; font-weight: bold; list-style: none; margin: 15px 0px 3px; padding: 5px 10px 3px;"><cite style="font-size: 1.1em; font-style: normal;"><a class="url" href="http://www.marnen.org/" rel="external nofollow" style="color: #004c94; font-size: 1.1em; text-decoration: none;">Marnen Laibow-Koser</a></cite> Says:<br /><small class="commentmetadata" style="color: #777777; display: block; font-size: 12px; font-weight: normal; line-height: 1.5em; margin: 0px;"><a href="http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/#comment-492" style="color: #004c94; text-decoration: none;" title="">May 18th, 2009 at 9:51 am</a></small><div style="font-size: 11pt; font-weight: normal; line-height: 1.6em; margin-bottom: 0.5em;">
I just confirmed that I was correct about this. Look at .methods on any ActiveRecord class, then run .find_by_whatever and look at .methods again. You’ll see that .methods has gained a ‘find_by_whatever’ entry.</div>
</li>
</ol>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-12005636055064757872013-04-05T17:21:00.003-07:002013-04-05T17:21:15.100-07:00Ruby thinks (19.99 * 100).to_i = 1998<br />
<h2 id="post-60" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">March 26th, 2009 By: Daniel</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #006600; font-weight: bold;">>></span> <span style="color: #006600; font-weight: bold;">(</span><span style="color: #006666;">19.99</span> <span style="color: #006600; font-weight: bold;">*</span> <span style="color: #006666;">100</span><span style="color: #006600; font-weight: bold;">)</span>.<span style="color: #9900cc;">to_i</span>
<span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">1998</span>
<span style="color: #006600; font-weight: bold;">>></span> <span style="color: #006600; font-weight: bold;">(</span><span style="color: #006666;">9.99</span> <span style="color: #006600; font-weight: bold;">*</span> <span style="color: #006666;">100</span><span style="color: #006600; font-weight: bold;">)</span>.<span style="color: #9900cc;">to_i</span>
<span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">999</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Someone please tell me what’s up with that!</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
In the meantime:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #006600; font-weight: bold;">>></span> <span style="color: #006600; font-weight: bold;">(</span><span style="color: #006666;">19.99</span> <span style="color: #006600; font-weight: bold;">*</span> <span style="color: #006666;">100</span><span style="color: #006600; font-weight: bold;">)</span>.<span style="color: #9900cc;">to_s</span>.<span style="color: #9900cc;">to_i</span>
<span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">1999</span></pre>
</div>
</div>
</div>
<div class="postmetadata" style="background-color: white; color: #777777; font-family: Futura, Arial, sans-serif; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Posted in <a href="http://www.mokisystems.com/blog/category/ruby-on-rails/" rel="category tag" style="color: #004c94; text-decoration: none;" title="View all posts in Ruby on Rails">Ruby on Rails</a> <strong>|</strong> <a href="http://www.mokisystems.com/blog/ruby-thinks-1999-100to_i-1998/#comments" style="color: #004c94; text-decoration: none;" title="Comment on Ruby thinks (19.99 * 100).to_i = 1998">4 Comments »</a></div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com2tag:blogger.com,1999:blog-3776253546234311964.post-32632584629729947782013-04-05T17:20:00.004-07:002013-04-05T17:20:50.734-07:00A few handy things to know about bash<br />
<h2 id="post-61" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">May 15th, 2009 By: Daniel</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Pipes and Redirection</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
These are standard shell tools, but sometimes I get confused about which one I need. So my way of thinking about it is that pipes are a connection between programs while redirection always goes to (or from) a file.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
So, for example, in order to find all my session routes I would connect the rake and grep commands via a pipe:</div>
<pre code="bash"> rake routes | grep session
</pre>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
On the other hand, I would use redirection to save the output of a git diff to a file so as to be able to feed it in to the patch program (which expects its input on standard in).</div>
<pre code="bash"> git diff > patchfile
patch < patchfile
</pre>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Braces</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I just learned about these recently and they make renaming things so much easier!</div>
<pre code="bash"> mv file.old file.new # old way
mv file.{old,new} # does the same thing!
</pre>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
So creating your database.yml file from the example one is as easy as:</div>
<pre code="bash"> mv config/database.yml{.example,}
</pre>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Changing Directories</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
I assume everyone already knows that cd with arguments goes to your home directory (the contents of the $HOME environment variable), but did you know you can do 'cd -' to go to the previous directory you were in ($OLDPWD)?</div>
<pre code="bash"> :/var/www$ cd /etc/apache2/sites-enabled/
:/etc/apache2/sites-enabled$ cd -
/var/www
:/var/www$
</pre>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
History</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
!! # execute the previous command (great for when you forget to sudo something)<br />!$ # The last argument of the previous command<br />!^ # The first argument<br />!* # All the previous arguments<br />^old^new^ # Repeat the previous command replacing old for new</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
And lots, lots more! See 'man history' for details.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Keyboard shortcuts</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Here are a few of the keyboard shortcuts that I use regularly (copied from the wikipedia article http://en.wikipedia.org/wiki/Bash):</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
CTRL + l : clears the screen content (equivalent to the command : clear).<br />CTRL + u : clears the line content before the cursor and copy it in the clipboard.<br />CTRL + k : clears thctrl alt copy pastee line content after the cursor and copy it in the clipboard.<br />CTRL + w : clears the word before the cursor and copy it in the clipboard.<br />CTRL + y : (yank) adds the clipboard content from the cursor position.</div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-69087614897058716862013-04-05T17:20:00.001-07:002013-04-05T17:20:05.988-07:00Savings records that fail validation<br />
<h2 id="post-62" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">June 9th, 2009 By: Daniel</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
So I had this problem with a record that was being saved even though it failed validation:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">cc = CreditCard.<span style="color: #9900cc;">new</span><span style="color: #006600; font-weight: bold;">(</span><span style="color: #ff3333; font-weight: bold;">:card_number</span> <span style="color: #006600; font-weight: bold;">=></span> <span style="color: #996600;">'invalid'</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #006600; font-weight: bold;">>></span> cc.<span style="color: #9900cc;">save</span>
<span style="color: #006600; font-weight: bold;">=></span> <span style="color: blue; font-weight: bold;">false</span>
<span style="color: #006600; font-weight: bold;">>></span> cc.<span style="color: #9900cc;">id</span>
<span style="color: #006600; font-weight: bold;">=></span> <span style="color: #006666;">3</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
That one had me stumped for a while until I realized I was carelessly using update_attribute in my custom writer:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="ruby" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #9966cc; font-weight: bold;">def</span> card_number=<span style="color: #006600; font-weight: bold;">(</span>num<span style="color: #006600; font-weight: bold;">)</span>
update_attribute<span style="color: #006600; font-weight: bold;">(</span><span style="color: #ff3333; font-weight: bold;">:crypted_card_number</span>, encrypt<span style="color: #006600; font-weight: bold;">(</span>num<span style="color: #006600; font-weight: bold;">)</span><span style="color: #006600; font-weight: bold;">)</span>
<span style="color: #9966cc; font-weight: bold;">end</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
And we all know that <a href="http://apidock.com/rails/ActiveRecord/Base/update_attribute" style="color: #004c94; text-decoration: none;">update_attribute</a> “saves the record without going through the normal validation procedure.”</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Everything worked much nicer after I changed the code to:</div>
<pre code="ruby">def card_number=(num)
self.crypted_card_number = encrypt(num)
end</pre>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-17964887633165550512013-04-05T17:19:00.003-07:002013-04-05T17:19:19.304-07:00Linux Clipboard Snippets<br />
<h2 id="post-63" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">September 4th, 2009 By: Daniel</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Whenever I find myself typing the same thing over and over again, I have to come up with some way to avoid the repetition. And one thing I do a lot is fill out web forms that require things like credit card numbers and unique email addresses. For a while I tried using Parcellite (a clipboard manager) but it wasn’t really designed for what I wanted to use it for. Finally with the inspiration of <a href="http://bbs.archlinux.org/viewtopic.php?id=71938" style="color: #004c94; text-decoration: none;">this thread</a> I was able to cobble together a solution that does just what I want.<br /><span id="more-63"></span><br />First I created a snippets directory and filled it with files that contained the text to insert or scripts to generate the desired text:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;">$ cd ~/.snippets
$ ls -1
credit_card
email
@example.com
phone
RAILS_ENV=test
sql_create
sql_permissions
$ cat credit_card
4111111111111111
$ cat sql_permissions
GRANT ALL PRIVILEGES ON .* TO ''@'localhost' IDENTIFIED BY ''<semi>
$ cat phone
#!/usr/bin/env ruby
print (1..12).map {<pipe>i<pipe> i == 4 <pipe><pipe> i == 8 ? '-' : rand(10).to_s}.join</pipe></pipe></pipe></pipe></semi></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Then I put this little script in ~/bin:</div>
<div class="wp_syntax" style="background-color: #f9f9f9; border: 1px solid silver; color: #110000; margin: 0px 0px 1.5em 30px; overflow-x: auto; overflow-y: hidden;">
<div class="code" style="padding: 2px 4px; vertical-align: top;">
<pre class="bash" style="clear: none; float: none; font-size: 12px; line-height: 1.333; overflow: visible; width: auto;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
<span style="color: #666666; font-style: italic;"># http://bbs.archlinux.org/viewtopic.php?id=71938</span>
<span style="color: #007800;">DIR=</span><span style="color: maroon;">${HOME}</span><span style="color: black; font-weight: bold;">/</span>.snippets
<span style="color: #007800;">DMENU_ARGS=</span><span style="color: red;">"-i -fn -*-terminal-*-*-*-*-18-*-*-*-*-*-*-*"</span> <span style="color: #666666; font-style: italic;"># xfontsel to select font</span>
<span style="color: #007800;">FILE=</span><span style="color: black; font-weight: bold;">`/</span>bin<span style="color: black; font-weight: bold;">/</span><span style="color: #c20cb9; font-weight: bold;">ls</span> <span style="color: #007800;">$DIR</span> <span style="color: black; font-weight: bold;">|</span> <span style="color: black; font-weight: bold;">/</span>usr<span style="color: black; font-weight: bold;">/</span>bin<span style="color: black; font-weight: bold;">/</span>dmenu <span style="color: maroon;">${DMENU_ARGS}</span><span style="color: black; font-weight: bold;">`</span>
<span style="color: black; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">[</span> -x <span style="color: maroon;">${DIR}</span><span style="color: black; font-weight: bold;">/</span><span style="color: maroon;">${FILE}</span> <span style="color: #7a0874; font-weight: bold;">]</span>; <span style="color: black; font-weight: bold;">then</span> <span style="color: #666666; font-style: italic;">#executable</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> -n <span style="color: black; font-weight: bold;">`</span><span style="color: maroon;">${DIR}</span><span style="color: black; font-weight: bold;">/</span><span style="color: maroon;">${FILE}</span><span style="color: black; font-weight: bold;">`</span> <span style="color: black; font-weight: bold;">|</span> xsel -b -i
<span style="color: black; font-weight: bold;">elif</span> <span style="color: #7a0874; font-weight: bold;">[</span> -f <span style="color: maroon;">${DIR}</span><span style="color: black; font-weight: bold;">/</span><span style="color: maroon;">${FILE}</span> <span style="color: #7a0874; font-weight: bold;">]</span>; <span style="color: black; font-weight: bold;">then</span>
<span style="color: #c20cb9; font-weight: bold;">cat</span> <span style="color: maroon;">${DIR}</span><span style="color: black; font-weight: bold;">/</span><span style="color: maroon;">${FILE}</span> <span style="color: black; font-weight: bold;">|</span> xsel -b -i
<span style="color: black; font-weight: bold;">fi</span>
xdotool key ctrl+v <span style="color: #666666; font-style: italic;"># for non-console</span>
xdotool key ctrl+<span style="color: #7a0874; font-weight: bold;">shift</span>+v <span style="color: #666666; font-style: italic;"># for console</span></pre>
</div>
</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
And then I mapped that script to a handy key combination in compiz. So now whenever I need a test credit card number, phone number, or email address I can just do <ctrl>c, type the first few characters to select the right snippet, hit return and it gets pasted in to whatever I’m working on.</ctrl></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
Notes and caveats:</div>
<ul style="list-style: none; margin-left: 0px; margin-top: 0px; padding: 0px 0px 0px 10px;">
<li style="margin: 7px 0px 8px 10px;">I had to aptitude install some packages to get dmenu and xdotool to work.</li>
<li style="margin: 7px 0px 8px 10px;">dmenu is ugly and has no mouse support.</li>
<li style="margin: 7px 0px 8px 10px;">Pasting into vim has occasional issues.</li>
</ul>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-15235775673762411762013-04-05T17:18:00.004-07:002013-04-05T17:18:34.989-07:00www.MantiCityCreek.org Goes Live<br />
<div style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<small style="color: #777777; font-size: 13px; line-height: 1.5em;">August 5th, 2010 By: Daniel</small><span style="font-size: 16px; line-height: normal;"></span></div>
<div class="entry" style="font-size: 16px; line-height: normal; margin-top: 0.5em;">
</div>
<br />
<div style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<span style="font-size: 11pt; line-height: 1.6em;">I have been asked to announce that we have recently gone live with </span><a href="http://www.manticitycreek.org/" style="color: #004c94; font-size: 11pt; line-height: 1.6em; text-decoration: none;">manticitycreek.org</a><span style="font-size: 11pt; line-height: 1.6em;">, a website for the Manti Irrigation and Reservoir Company of Manti, Utah to monitor real-time data from local canals, ponds and rivers.</span></div>
<div style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.manticitycreek.org/" style="color: #004c94; text-decoration: none;"><img alt="manticitycreekdotorg" class="alignnone size-full wp-image-102" height="398" src="http://www.mokisystems.com/blog/wp-content/uploads/2010/08/manticitycreekdotorg.png" style="border: 0px; max-width: 100%; padding: 0px;" title="manticitycreekdotorg" width="650" /></a></div>
<div style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
There are a number of different data products for viewing the <a href="http://www.manticitycreek.org/water/" style="color: #004c94; text-decoration: none;">data</a>, including charts and graphs and tabular reports. It is even available by <a href="http://www.manticitycreek.org/reports/data-by-telephone-ivr/" style="color: #004c94; text-decoration: none;">phone</a> thanks to <a href="http://www.cloudvox.com/" style="color: #004c94; text-decoration: none;">cloudvox</a>’s IVR technology. The site has been built with <a href="http://radiantcms.org/" style="color: #004c94; text-decoration: none;">Radiant</a> which makes it easy for us to embed <a href="http://jquery.com/" style="color: #004c94; text-decoration: none;">jQuery</a>-powered data products from our data collection and management tool, which is a <a href="http://rubyonrails.org/" style="color: #004c94; text-decoration: none;">Ruby on Rails</a> application. We have also integrated external resources such as <a href="http://www.manticitycreek.org/weather/" style="color: #004c94; text-decoration: none;">SNOTEL graphs</a> from the <a href="http://www.wrcc.dri.edu/" style="color: #004c94; text-decoration: none;">Western Regional Climate Center</a> to make it easy to analyze long term precipitation trends.</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-21477836029755896902013-04-05T17:16:00.002-07:002013-04-05T17:17:30.292-07:00Stress Testing Your Web App<span style="background-color: white; color: #777777; font-family: Futura, Arial, sans-serif; font-size: 13px; line-height: 19.1875px;">August 9th, 2010 By: bret</span><br />
<br />
<iframe allowfullscreen="" frameborder="0" height="315" src="http://www.youtube.com/embed/NtvNSg69P7g" width="420"></iframe>Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0tag:blogger.com,1999:blog-3776253546234311964.post-80654797373951512782013-04-05T17:14:00.004-07:002013-04-05T17:14:46.604-07:00Hydrology and the Real-Time Web<br />
<h2 id="post-88" style="background-color: white; clear: both; color: #333333; font-family: Futura, Arial, sans-serif; font-size: 13pt; margin-bottom: 0.2em; margin-top: 1em;">
<span style="color: #777777; font-size: 13px; line-height: 1.5em;">August 18th, 2010 By: bret</span></h2>
<span style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px;"></span><div class="entry" style="background-color: white; color: #555555; font-family: Futura, Arial, sans-serif; font-size: 16px; margin-top: 0.5em;">
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
The Sevier River Water Users Association (SRWUA) in Central Utah are pioneers in the use of the Real-Time Web. For the past 10 years SRWUA has been delivering real-time water flow data to the public via the website <a href="http://www.sevierriver.org/" style="color: #004c94; text-decoration: none;">www.SevierRiver.org</a>.</div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
More that 100 remote, solar-powered, stations record water flow and capacity data from canals, rivers and reservoirs. This data is collected and disseminated by the the MetriDyne tool, created by <a href="http://www.mokisystems.com/" style="color: #004c94; text-decoration: none;">Moki Systems.</a></div>
<div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
A schematic view of a portion of the system is useful as an overview for operations:<br /><a href="http://www.sevierriver.org/rivers/upper/" style="color: #004c94; text-decoration: none;"><img alt="Flows of Rivers and Canals" class="size-full wp-image-89" height="341" src="http://www.mokisystems.com/blog/wp-content/uploads/2010/08/Upper.PNG" style="border: 0px; max-width: 100%; padding: 0px;" title="Upper" width="262" /></a></div>
<a href="http://www.sevierriver.org/rivers/upper/" style="color: #004c94; text-decoration: none;"><div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<br /></div>
</a><div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.sevierriver.org/rivers/upper/" style="color: #004c94; text-decoration: none;">A tabular view of the same data:</a><a href="http://www.sevierriver.org/rivers/upper/" style="color: #004c94; text-decoration: none;"><img alt="Tabular view of flow data on the Upper Seiver" class="size-full wp-image-91" height="292" src="http://www.mokisystems.com/blog/wp-content/uploads/2010/08/UpperTable.png" style="border: 0px; max-width: 100%; padding: 0px;" title="UpperTable" width="712" /></a></div>
<a href="http://www.sevierriver.org/rivers/upper/" style="color: #004c94; text-decoration: none;"><div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<br /></div>
</a><div style="font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em;">
<a href="http://www.sevierriver.org/rivers/upper/" style="color: #004c94; text-decoration: none;">Drilling down on an individual station shows a time series graph with options for tabular display or data export:</a><a href="http://www.sevierriver.org/rivers/upper/" style="color: #004c94; text-decoration: none;"><img alt="Time Series Graph of Data" class="size-full wp-image-93" height="421" src="http://www.mokisystems.com/blog/wp-content/uploads/2010/08/SevierBelowPiuteRes.png" style="border: 0px; max-width: 100%; padding: 0px;" title="SevierBelowPiuteRes" width="690" /></a></div>
<div style="color: #004c94; font-size: 11pt; line-height: 1.6em; margin-bottom: 0.5em; text-decoration: none;">
<br /></div>
</div>
Brethttp://www.blogger.com/profile/15806296282896863045noreply@blogger.com0