Render Partial if File Exists

If you ever want to render a partial but don’t want an error thrown you can either check for the existence of the file first

<%= render :partial => params[:controller]+"/sidebar" if File.exists?(RAILS_ROOT+"/app/views/"+params[:controller]+"/_sidebar.html.erb") %>

or you can catch the error that Rails throws

<%= render :partial => params[:controller]+"/sidebar" rescue nil %>

My Review of Moodle 1.9 Extension Development

I wrote a review for Joseph Thibault’s Moodle News on extension development for Moodle. The book is quite good and I think an essential resource for anyone wanting to develop in Moodle. The book focuses on plugin development, but it will also give you an overview of the architecture, api and best practices.

I wish I had this book about 3 years ago when I first started fooling around in the code base! At any rate, you can read the review on Moodle News at http://www.moodlenews.com/2010/moodle-1-9-extension-development-review-by-bseanvt/

There is also an interesting discussion underway about the ‘bloat’ in the Moodle code at http://www.moodlenews.com/2010/opinion-1000000-lines-of-code/

27 May 2010, 11:32am
Programming:
by

1 comment

NO Table Cell Spacing Please

Remove cell padding on a table you add the cellspacing attribute and set it to “0″. Is there a better way to do this with straight up CSS? Nothing seems to work…

&lt;table id='my-favorite-table' cellspacing="0" &gt;
...

Offset an Element with Relative Position Property with CSS Without Taking Up Any Space in the Document

Using CSS positioning it’s possible to offset an element and collapse its width and height where it would normally appear. Wrapping the content in an absolute positioned element, the space that the element would normally take up is collapsed.

&lt;div style='position:relative;top:-10px;left:-100px;color:blue;width:50px;'&gt;
  &lt;div style='position:absolute;top:0px;left:0px;'&gt;
      Position of this element will be -100px from the left and -10px from the top. Because it is wrapped
      by an absolute positioned element, the original location of this element will be collapsed.
   &lt;/div&gt;
&lt;/div&gt;

Here is an example

[this is where the div should be]

Position of this element will be -100px from the left and -10px from the top. Because it is wrapped
by an absolute positioned element, the original location of this element will be collapsed.

but we see that this block of text is next in line instead!

Launch Photoshop (Or Any App) From The Command Line on Mac OS X

I often find myself coding with the terminal open. Cding around a web app project I usually end up at some point launching Photoshop. Either to touch up or work on a psd, png, jpg …etc. I fire up Photoshop and then navigate to the app’s public directory, where the site images are kept. Then begins the hunt in finder for the image. This takes some time and if I’m already at the command line it would be nice to launch Photoshop with the exact file I want with a single command! To accomplish this just make an alias in your bash profile like so…

#fire up your text editor and edit your profile
vim ~/.bash_profile
#create the alias command
alias psd="open -a /Applications/Adobe\ Photoshop\ Elements\ 3/Photoshop\ Elements\ 3.app"

You need to fire up a new terminal instance before this setting will take place. CMD+N.
Then from the command line type

psd my-image.psd

Note, I didn’t use “ps” as the alias because this is already taken by the system. Also the path to the application may be different on your system. Make sure you use the correct path or you may have an error like

LSOpenFromURLSpec() failed with error -10827 for the file...

Programmatically Turn Off Comments in WordPress with Filter

To turn comments off programmatically with a filter in WordPress, you can set the post object’s comment_status variable to “closed”. Call the filter at some point after the post is loaded but before the comments are rendered. This is a hack, but I haven’t seen a simpler approach, beside installing another plugin. In the example below, the condition to disable comments is simple. If a post is in a certain category, comments aren’t allowed. Otherwise, go ahead and behave as normal. You can still disable comments on a per post basis in other categories.

One thing to note is the use of the global $post object. The function needs access to the object to set the variable.

add_filter('get_header', 'sb_turn_comments_off');
function sb_turn_comments_off(){
    if(in_category("Projects") AND is_single() ){
      global $post;
      $post->comment_status="closed";
  }
}

I’ve only tested this with the Thematic framework. I assume that other themes will check the comment_status variable before allowing comments.

Intercepting the WordPress Loop with Pre_get_posts

#deprecated (see http://codex.wordpress.org/Function_Reference/query_posts#Post_.26_Page_Parameters)

Using the “pre_get_posts” filter you can intercept the WordPress loop and override or set attributes in the “$query” object. This is useful because you can select just the posts you want, say for instance on your homepage you want to show posts from just one category.

add_filter('pre_get_posts', 'filter_homepage_posts');
function filter_homepage_posts($query) {
    $limit_number_of_posts = 5;
    $featured_category_id = get_cat_id('Reviews'); // by cat name...
    if ($query-&gt;is_home) {
        $query-&gt;set('cat', $featured_category_id);
        $query-&gt;set('showposts', $limit_number_of_posts);
    }
  return $query;
}

Thematic Function Reference

I could not find a listing of all thematic theme functions for WordPress online. So the following is just a recursive grep of the thematic directory.

grep -rh "function thematic_" *

Each function needs to prepended with “thematic_” when adding as a action or filter eto a WordPress childtheme. Example

function my_function_says_hello(){ print "Hello!"; }
add_filter('thematic_abovepagebottom', 'my_function_says_hello');

Here is the list

remove_generators()
abovecomments()
abovecommentslist()
belowcommentslist()
abovetrackbackslist()
belowtrackbackslist()
abovecommentsform()
show_subscription_checkbox()
belowcommentsform()
show_manual_subscription_form()
belowcomments()
singlecomment_text()
multiplecomments_text()
postcomment_text()
postreply_text()
commentbox_text()
commentbutton_text()
commenter_link()
comments_template()
include_comments()
abovecontainer()
archives()
navigation_above()
navigation_below()
above_indexloop()
archiveloop()
authorloop()
categoryloop()
indexloop()
searchloop()
singlepost()
tagloop()
below_indexloop()
above_categoryloop()
below_categoryloop()
above_searchloop()
below_searchloop()
above_tagloop()
below_tagloop()
belowcontainer()
page_title()
nav_above()
archive_loop()
author_loop()
category_loop()
index_loop()
single_post()
search_loop()
tag_loop()
time_title()
time_display()
postheader()
postheader_posteditlink()
postheader_posttitle()
postheader_postmeta()
postmeta_authorlink()
postmeta_entrydate()
postmeta_editlink()
content()
archivesopen()
category_archives()
monthly_archives()
archivesclose()
404()
404_content()
postfooter()
postfooter_posteditlink()
postfooter_postcategory()
postfooter_posttags()
postfooter_postcomments()
postfooter_postconnect()
nav_below()
previous_post_link()
next_post_link()
author_info_avatar()
cats_meow($glue)
tag_ur_it($glue)
comments($comment, $args, $depth)
pings($comment, $args, $depth)
body_class( $print = true )
post_class( $print = true )
comment_class( $print = true )
date_classes( $t, &amp;$c, $p = '' )
abovefooter()
footer()
footertext($thm_footertext)
belowfooter()
after()
subsidiaries()
siteinfoopen()
siteinfo()
siteinfoclose()
create_doctype()
head_profile()
doctitle()
create_contenttype()
seo()
canonical_url()
use_excerpt()
use_autoexcerpt()
create_description()
show_description()
create_robots()
show_robots()
create_stylesheet()
show_rss()
show_commentsrss()
show_pingback()
show_commentreply()
head_scripts()
add_menuclass($ulclass)
before()
aboveheader()
header()
brandingopen()
blogtitle()
blogdescription()
brandingclose()
access()
belowheader()
trim_excerpt($text)
the_excerpt($deprecated = '')
excerpt_rss()
tag_query()
sidebar()
abovemainasides()
betweenmainasides()
belowmainasides()
aboveindextop()
belowindextop()
aboveindexinsert()
belowindexinsert()
aboveindexbottom()
belowindexbottom()
abovesingletop()
belowsingletop()
abovesingleinsert()
belowsingleinsert()
abovesinglebottom()
belowsinglebottom()
abovepagetop()
belowpagetop()
abovepagebottom()
belowpagebottom()
abovesubasides()
belowsubasides()
subsidiaryopen()
before_first_sub()
between_firstsecond_sub()
between_secondthird_sub()
after_third_sub()
subsidiaryclose()
search_form()
widgets_init()
sort_widgetized_areas($content)
primary_aside()
secondary_aside()
1st_subsidiary_aside()
2nd_subsidiary_aside()
3rd_subsidiary_aside()
index_top()
index_insert()
index_bottom()
single_top()
single_insert()
single_bottom()
page_top()
page_bottom()
before_widget_area($hook)
after_widget_area($hook)
before_widget()
after_widget()
before_title()
after_title()

Thematic is a nice theme framework for WordPress. More info is available at the developers website ThemeShaper. Using the above filters it is possible to create a highly customized child theme quickly.

Yield a Block within Rails Helper Method with Multiple Content_tags Using Concat

To clean up some repetitive html coding in views, pass a block of text to a helper function which will wrap it for you the same way, each and every time. For example, I have a ‘help’ link which will toggle the display of a block of text if a link is clicked. I use this “+/- help” link throughout my application in various views. I could create a partial but this gets messy. Instead this is what I want to write in my views…

&lt;% help do %&gt;
  here is my help text...
&lt;% end %&gt;

which will render HTML similar to this…

&lt;a href='#' 'class='help' id='help_link_123456' onclick='some_func_to_toggle_state'&gt;+/- help&lt;/a&gt;
&lt;div id="help_123456"&gt;
  here is my help text...
&lt;/div&gt;

In order to accomplish this you need to create a helper method. Assigning a unique id, just a random number, will help avoid collisions with the state of the toggled div if you use this more than once per page. Placing other HTML helper methods inside the concat() method allows multiple tags as well as rendering the block passed to the function in the appropriate place. It looks a little unwieldy, but works nicely.

# app/helpers/application_helper.rb
module ApplicationHelper
  def help(&block)
    uniqid = rand; concat( link_to_function("+/- help") do |page|
      page["help_#{uniqid}"].toggle
      page.visual_effect :highlight, "help_#{uniqid}"
    end + content_tag(:div,:class=>"help",:id=>"help_#{uniqid}", :style=>"display:none") do
      yield
    end )
  end
end

Carrier Email Addresses for Sending SMS over Email

Just for reference, here are the carrier email addresses for sending email as an SMS. Look up the carrier for the phone in question, then send an email in this format [telephonenumber]@[carrier-name.com]

Carrier Email to SMS Gateway

Alltel [10-digit phone number]@message.alltel.com
Example: 1234567890@message.alltel.com
AT&T (formerly Cingular) [10-digit phone number]@txt.att.net
[10-digit phone number]@mms.att.net (MMS)
[10-digit phone number]@cingularme.com
Example: 1234567890@txt.att.net
Boost Mobile [10-digit phone number]@myboostmobile.com
Example: 1234567890@myboostmobile.com
Nextel (now Sprint Nextel) [10-digit telephone number]@messaging.nextel.com
Example: 1234567890@messaging.nextel.com
Sprint PCS (now Sprint Nextel) [10-digit phone number]@messaging.sprintpcs.com
[10-digit phone number]@pm.sprint.com (MMS)
Example: 1234567890@messaging.sprintpcs.com
T-Mobile [10-digit phone number]@tmomail.net
Example: 1234567890@tmomail.net
US Cellular [10-digit phone number]email.uscc.net (SMS)
[10-digit phone number]@mms.uscc.net (MMS)
Example: 1234567890@email.uscc.net
Verizon [10-digit phone number]@vtext.com
[10-digit phone number]@vzwpix.com (MMS)
Example: 1234567890@vtext.com
Virgin Mobile USA [10-digit phone number]@vmobl.com
Example: 1234567890@vmobl.com
Free Email To SMS Gateways (International + Smaller US)

These are all I could find from Wikipedia and other sources. If you’re aware of any other ones please share them in comments and I’ll add them to the list.

Carrier Email to SMS Gateway
7-11 Speakout (USA GSM) number@cingularme.com
Airtel (Karnataka, India) number@airtelkk.com
Airtel Wireless (Montana, USA) number@sms.airtelmontana.com
Alaska Communications Systems number@msg.acsalaska.com
Aql number@text.aql.com
AT&T Enterprise Paging number@page.att.net
BigRedGiant Mobile Solutions number@tachyonsms.co.uk
Bell Mobility & Solo Mobile (Canada) number@txt.bell.ca
BPL Mobile (Mumbai, India) number@bplmobile.com
Cellular One (Dobson) number@mobile.celloneusa.com
Cingular (Postpaid) number@cingularme.com
Centennial Wireless number@cwemail.com
Cingular (GoPhone prepaid) number@cingularme.com (SMS)
Claro (Brasil) number@clarotorpedo.com.br
Claro (Nicaragua) number@ideasclaro-ca.com
Comcel number@comcel.com.co
Cricket number@sms.mycricket.com (SMS)
CTI number@sms.ctimovil.com.ar
Emtel (Mauritius) number@emtelworld.net
Fido (Canada) number@fido.ca
General Communications Inc. number@msg.gci.net
Globalstar (satellite) number@msg.globalstarusa.com
Helio number@messaging.sprintpcs.com
Illinois Valley Cellular number@ivctext.com
Iridium (satellite) number@msg.iridium.com
Iusacell number@rek2.com.mx
i wireless number.iws@iwspcs.net
Koodo Mobile (Canada) number@msg.koodomobile.com
LMT (Latvia) number@sms.lmt.lv
Meteor (Ireland) number@sms.mymeteor.ie
Mero Mobile (Nepal) 977number@sms.spicenepal.com
MetroPCS number@mymetropcs.com
Movicom (Argentina) number@sms.movistar.net.ar
Mobitel (Sri Lanka) number@sms.mobitel.lk
Movistar (Colombia) number@movistar.com.co
MTN (South Africa) number@sms.co.za
MTS (Canada) number@text.mtsmobility.com
Nextel (United States) number@messaging.nextel.com
Nextel (Argentina) TwoWay.11number@nextel.net.ar
Orange Polska (Poland) 9digit@orange.pl
Personal (Argentina) number@alertas.personal.com.ar
Plus GSM (Poland) +48number@text.plusgsm.pl
President’s Choice (Canada) number@txt.bell.ca
Qwest number@qwestmp.com
Rogers (Canada) number@pcs.rogers.com
SL Interactive (Australia) number@slinteractive.com.au
Sasktel (Canada) number@sms.sasktel.com
Setar Mobile email (Aruba) 297+number@mas.aw
Suncom number@tms.suncom.com
T-Mobile (Austria) number@sms.t-mobile.at
T-Mobile (UK) number@t-mobile.uk.net
Telus Mobility (Canada) number@msg.telus.com
Thumb Cellular number@sms.thumbcellular.com
Tigo (Formerly Ola) number@sms.tigo.com.co
Tracfone (prepaid) number@mmst5.tracfone.com
Unicel number@utext.com
Virgin Mobile (Canada) number@vmobile.ca
Vodacom (South Africa) number@voda.co.za
Vodafone (Italy) number@sms.vodafone.it
YCC number@sms.ycc.ru
MobiPCS (Hawaii only) number@mobipcs.net