Arshad Chummun

Programming Ramblings

A Rake Command to Create Asides on the Fly for Octopress

Edit your Rakefile and drop the following lines in it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# usage rake new_aside["Title of aside"]
desc "Generates a new aside in #{source_dir}/_includes/custom/asides"
task :new_aside, :title do |t, args|
  raise "### You haven't set anything up yet. First run `rake install` to set up an Octopress theme." unless File.directory?(source_dir)
  mkdir_p "#{source_dir}/_includes/custom/asides"
  args.with_defaults(:title => 'new-aside')
  title = args.title
  safe_filename = title.downcase.gsub(/[^\w\s_]+/, '').gsub(/(^|\b\s)\s+($|\s?\b)/, '\\1\\2').gsub(/\s+/, '_')
  filename = "#{source_dir}/_includes/custom/asides/#{safe_filename}.html"
  if File.exist?(filename)
    abort("rake aborted!") if ask("#{filename} already exists. Do you want to overwrite?", ['y', 'n']) == 'n'
  end
  puts "Creating new aside: #{filename}"
  open(filename, 'w') do |aside|
    aside.puts "<section>"
    aside.puts "<h1>#{title.gsub(/&/,'&amp;')}</h1>"
    aside.puts "</section>"
  end
  puts "Aside #{filename} created. Update _config.yml to add it to site."
end

Usage : rake new_aside[“Title of Aside”]

Recipe : Hiding Posts From the Octopress Front Page

Following a recent discussion on Twitter about excluding some posts from the front page (which I think is a great idea), here’s my recipe for controlling which posts are shown and which ones are hidden based on categories.

First, let’s add two settings to our _config.yml file.

1
2
front_page_categories: [] # A list of categories for the front page
front_page_categories_op : 'hide' # Whether to show or hide the list of categories from front_page_categories

Next, find the pagination plugin under the plugins directory, and add the following code just after line #33:

1
2
3
4
5
6
7
# show / hide some categories
op = (site.config['front_page_categories_op'] == 'hide') ? 'delete_if' : 'keep_if';
if site.config['front_page_categories'].kind_of?(Array)
  all_posts.send(op) do |post|
    (site.config['front_page_categories'] & post.categories).size == 1
  end
end

Your pagination file should look like this :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
...
def paginate(site, page)
  all_posts = site.site_payload['site']['posts']

  # show / hide some categories
  op = (site.config['front_page_categories_op'] == 'hide') ? 'delete_if' : 'keep_if';
  if site.config['front_page_categories'].kind_of?(Array)
    all_posts.send(op) do |post|
      (site.config['front_page_categories'] & post.categories).size == 1
    end
  end

  pages = Pager.calculate_pages(all_posts, site.config['paginate'].to_i)
  page_dir = page.destination('').sub(/\/[^\/]+$/, '')
  page_dir_config = site.config['pagination_dir']
  dir = ((page_dir_config || page_dir) + '/').sub(/^\/+/, '')

...etc

That’s all.

Now, here’s how it works. If you want to hide posts under categories “Octopress” and “Plugin”, just add it to your _config.yml

1
2
front_page_categories: [Octopress, Plugin] # A list of categories for the front page
front_page_categories_op : 'hide' # Whether to show or hide the list of categories from front_page_categories

And if you want to show only posts under category “Octopress” on the front page, replace “hide” by “show”:

1
2
front_page_categories: [Octopress] # A list of categories for the front page
front_page_categories_op : 'show' # Whether to show or hide the list of categories from front_page_categories

;)

Contact Form in Octopress: Making Notifications Awesomer

This is a follow-up of the Contact Form in Octopress. In this post, we’re going to use custom scripts in Google Docs to mail the form values on form submit. Here’s how:

Step 1: Open the spreadsheet for the Google Form built in the previous post.

Step 2: Open the Script Editor (Tools -> Script Editor)

Step 3: Add in a title for the new script. (eg. mailFormValuesOnSubmit)

Step 4: Paste in the following code and save it.

mailFormValuesOnSubmit
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function mailFormValuesOnSubmit(e) {
  try {
    var sheet = SpreadsheetApp.getActiveSheet();
    var sheetName = sheet.getParent().getName();

    var x = sheet.getLastRow();
    var y = sheet.getLastColumn();
    var values = sheet.getRange(x, 1, x, y).getValues();

    //email values
    var recipient = "INSERT_EMAIL_HERE";
    var name = values[0][1];
    var email = values[0][2];
    var subject = sheetName + ": " + values[0][3];
    var message = "From: " + name +" (" + email + ")\n\n";
    message += values[0][4];

    //send the email
    MailApp.sendEmail(recipient, subject, message);
  } catch(e){
    MailApp.sendEmail(recipient, sheetName + ": Error", sheetName + ": Error");
  }
}

The code above will get the values of the last row and mail it to the recipient email address provided. My form has name, email, subject and message fields. So I’m using this code to mail me the values with the name, email and message in the email body. You can customize the subject and message to send. The values variable is a 2d array indexed by row number then by column number. So the following code returns the value of the first row and third column, which in my case here is email.

1
var email = values[0][2]];

Now that our script is saved, we need to tell the spreadsheet to run this script on form submit. We’ll use a trigger.

Step 5 : Under Resources, Click on “Current Script’s triggers”. Add a new trigger : Run mailFormValuesOnSubmit From Spreadsheet On Form Submit. Save.

Now, when you submit your form, you should get the values submitted in an email right away.

That’s it, contact form awesomeness in Octopress.

Contact Form in Octopress

Building a contact form for Octopress can be a real PITA? Why? Octopress runs on a server-less (static pages) configuration, which means no interaction with any server and consequently no mail interface. Our only solution in this case is to use 3rd party forms that we can embed on our site. So here’s what we’re going to do :

  • Create a form on Google Docs.
  • Set notifications for the form.
  • Create a new page on Octopress to hold our form.
  • Use the Google Form Liquid tag to embed our form.

Create a form on Google Docs.

Step 1: Head to Google Docs

Step 2: Click on Create -> Form

Step 3: Build your form. (You can add required elements here)

Set notifications for the form.

Now that our form is ready. Let’s configure notifications for it.

Step 1: Find the See Responses button, and select Spreadsheet

Step 2: On the spreadsheet, open the notification (Tool -> Notification Rules)

Step 3: Tell Google to send you an email when a user submits the form.

Create a new page on Octopress to hold our form.

Our form is ready. Let’s add it to Octopress. We’ll build a page to hold the form.

bundle exec rake new_page["Contact"]

Use the Google Form filter to embed our form.

Now that the page is built. Let’s embed the form in it. You’ll need the Google Form plugin for that. Go here to get it.

Once installed, open the page created above in an editor and add the following code to it.

1
{% google_form YOUR_FORMKEY_GOES_HERE YOUR_SUCCESS_MESSAGE_HERE %}

Example

1
{% google_form dGVfY3Mw83fh3333kssoZWdJQnc6MQ Thank you. I'll get back to your shortly. %}

Regenerate your site and you should see your form on your contact page.

bundle exec rake generate

The Google Form plugin should take care of validation and custom CSS as well.

Here’s a demo of a contact form running off Google Docs. Please, don’t spam.

:)

Recent Comments in Octopress

See the recent comments in the sidebar? Here’s how it’s done:

Step 1: Let’s create a new aside. Create a new file recent_comment.html under source/_includes/custom/asides

1
touch /path/to/octopress/source/_includes/custom/asides/recent_comment.html

Step 2: Add the following code

1
2
3
4
<section>
  <h1>Recent Comments</h1>
  <div id="dsq-recentcomments" class="dsq-widget"><script type="text/javascript" src="http://disqus.com/forums/{{ site.disqus_short_name }}/recent_comments_widget.js?hide_avatars=1"></script></div>
</section>

Here are the parameters you can use for comments :

  • hide_avatars : hides the avatar in comments (values : 0, 1)
  • num_items : number of comments to show
  • excerpt_length : number of characters to show for each comment

Step 3: Add the aside to _config.yml

1
default_asides: [custom/asides/links.html, asides/recent_posts.html, custom/asides/recent_comments.html, asides/github.html, asides/twitter.html, asides/delicious.html, asides/pinboard.html, asides/googleplus.html]

Step 4: Re-build your site

1
bundle exec rake generate

That’s it.

Drupal Tag : Easily Link to Drupal.org Pages for Octopress

A while back, I helped write the Drupal 7 port for the Drupal DOPL module. This module makes it easy to link back to modules, themes, nodes, users and pretty much anything on http://drupal.org. For people who blogs about Drupal it’s a great help. So the first thing i wanted when I moved to Octopress is that same funtionality. So here goes “Drupal Tag”, an Octopress filter plugin that let’s you link to Drupal.org pages.

Installation

“Installation for Drupal Tag”
1
2
3
4
5
git clone git@github.com:arshad/Drupal-Tag.git
cd Drupal-Tag
mv drupal_tag.rb /path/to/octopress/plugins
cd /path/to/octopress/
bundle exec rake generate

Syntax

“Syntax for Drupal Tag”
1
{% drupal [name|nid|uid].[module|theme|installprofile|installprofile|project|node|user] %}

Examples

“Examples for Drupal Tag”
1
2
3
4
{% drupal views.module "Views" %}
{% drupal andromeda.theme "Andromeda Theme" %}
{% drupal 559302.node "Guidelines for SQL" %}
{% drupal 571032.user "This is my d.o profile" %}

Output

“Output for Drupal Tag”
1
2
3
4
<a href="http://drupal.org/project/views">Views</a>
<a href="http://drupal.org/project/andromeda">Andromeda Theme</a>
<a href="http://drupal.org/node/559302">Guidelines for SQL</a>
<a href="http://drupal.org/user/571032">This is my d.o profile</a>