A-  A  A+ RSS Feed

Deep Thoughts by Robert Felty

thoughts on wordpress, latex, cooking et alia

Archive for the 'wordpress' Category

Thursday, February 18th, 2010

Multi-column balanced lists

List with balanced columns

List with balanced columns

List with unbalanced columns

List with unbalanced columns

Recently I was working on a project where a client wanted a list of items to be displayed over multiple columns, and requested that the columns be balanced (as balanced as possible). It didn’t take me too long to figure out how to do this for 3 columns, but I knew that there was a more general solution, which did take me a little time to figure out. I am sharing my solution here for my future reference. Perhaps some one else will find it useful too. The solution is in php, though the general algorithm should apply to any language.

The intuition that led me to this solution was to examine unbalanced columns. Let’s look at the case of 5 columns with 56 items, as shown in the figures. It quickly becomes obvious that you need 12 items per column (ceil(56/5)). However, this yields columns of lengths 12, 12, 12, 12 and 8. If you decrease the number of total items to 55, then you have balanced columns of 11. If you increase the number of items to 60, you have balanced columns of 12. Thus, it is possible for the last column to have n-1 items less than the other columns, where n is the number of columns. The preferred output is to have columns of 12, 11, 11, 11, and 11. So what we are doing is shifting over elements from columns 2, 3, and 4 to column 5 (note that we are not messing with the order of the elements). We can always achieve the desired result by simply decreasing the number of items from some of the columns by 1. To determine which columns to decrease, we simply look at the difference in the number of elements per column in the unbalanced solution. In the case of 5 columns with 56 items, the last column would only have 8 items, which is 4 less than 12. So we should start reducing the number of items per column at the 2nd column ((5-4)+1). If we had 57 items total, we would start reducing at the 3rd column ((5-3)+1).

Here is the snippet of code which takes care of figuring this out:

$numCols = 5;
$numItems = 56;
$itemsPerCol = ceil($numItems / $numCols);
$adjustedItemsPerCol=$itemsPerCol;
$blank =$itemsPerCol - ($numItems % $itemsPerCol);
if ($blank!=$itemsPerCol && $blank >0) {
  $adjustedItemsPerCol--;
}

While we are looping over our array of items (or, in my example case, using a while loop), we check to see which column we are on, and if we are on the column where we start to decrease the number of items per column, then we switch $itemsPerCol to $adjustedItemsPerCol.

if ($colNum == ($numCols - $blank)) {
  $itemsPerCol=$adjustedItemsPerCol;
}

Feel free to look at this working example, along with the code for it. I have used the CSS float property to make the divs act like columns, and added some colors to help them stand out.

Saturday, January 2nd, 2010

Wordpress 2.9 image changes

Wordpress 2.9 has several new image enhancements. One of the biggest features is some basic image editing functionality. Another one is that you can now specify different alt text from the “caption” field. The “caption” field places a caption under the image. The “alt” text is used to describe the picture to non-seeing users (including search engines). This is a nice addition. However, I usually like my caption, alt text, and title text to be all the same, and I don’t like to have to enter it all manually or copy and paste. By default, wordpress will use an IPTC caption as its “description” field, which shows up in the title attribute of the image. This is nice, since I can add a caption in my image editing program of choice (Picasa) and then I don’t have to enter it again. Except for those pesky alt and caption fields, which are blank by default.

This is particularly important if I am uploading many pictures. So I wrote a little sql which will set the “caption” and “alt text” fields to be the same as the description. I already had this working for the “caption” field for quite some time, but getting it to work for the different alt text handling in 2.9 was a bit tricky, since I discovered that the alt text is not stored in wp_posts like the other fields. Instead it is stored in the wp_postmeta table, which is new in 2.9. Although it took me awhile to figure this out, the new table is a welcome addition. Now for each image you upload, wordpress stores meta information in this table, including the width and height, different sized versions of the file, the IPTC caption, some EXIF info and a few other goodies. This means that if you like to include EXIF info about your pictures, that doing so requires only a simple database lookup, instead of having to read the headers from the image, which should be considerably faster I would imagine.

Now for my little SQL which sets the “caption” and “alt text” to be the same as the description. I run this on my server after uploading pictures. It would be even better if I could figure out how to do this as a wordpress plugin.

-- First we set the image caption (post_excerpt) to be the same as the
-- description (post_content)
UPDATE wp_posts SET post_excerpt=post_content WHERE post_type='attachment' AND
date(post_date)=curdate();

-- Next we set the alternative text to be the same as the post_excerpt
INSERT INTO wp_postmeta (wp_postmeta.post_id, wp_postmeta.meta_value) SELECT
DISTINCT wp_posts.ID, wp_posts.post_excerpt FROM wp_posts, wp_postmeta WHERE
wp_posts.ID=wp_postmeta.post_id AND post_type='attachment' AND
date(post_date)=curdate();

-- This line sets the correct meta_key for the previous line, which doesn't
-- seem possible otherwise
UPDATE wp_postmeta SET meta_key='_wp_attachment_image_alt' WHERE meta_key IS
NULL;
Monday, August 24th, 2009

Writing your own custom filters for postie

In version 1.3.1 of postie, it is now easy to add custom filters to the content of your posts. Best of all, by using filters, you can easily write your own plugin, which will not be affected by upgrades to postie (as opposed to modifying the postie functions directly). There are two examples now included in version 1.3.1 of postie, in the filterPostie.php file. Here is how to write your own filter.

  1. Copy the filterPostie.php into your plugins directory
  2. Change the metadata at the top of the file, such as the author and plugin name
  3. Modify the example functions to your liking, or create your own
  4. Activate the plugin

A few more details. After modifying the headers, you might have something like the following:

/* Plugin Name: My own Postie Filter Plugin
URI: http://mywebsite
Description: Adds a custom field to each post called postie
Version: 0.1 Author: Joe Bloe
Author URI: http://mywebsite.com
*/

Just as with any filter for wordpress, you have 2 parts.

  1. A function which receives an argument, makes some modifications (filtering) and returns a result
  2. A function call to add this new function to the list of filters for a certain action

As you can see in the example file, I have created two functions, filter_title, and filter_content. After creating these functions, I then “hook” them into postie using the add_filter function.

add_filter('postie_post', 'filter_title');
add_filter('postie_post', 'filter_content');

Now lets create our new function to add a custom field

function add_custom_field($post) {
  //this function appends "(via postie)" to the title (subject)
  add_post_meta($post['ID'], 'postie', 'postie');
  return ($post);
}

Finally, we let wordpress know that this function should filter any post that is sent via postie

add_filter('postie_post', 'add_custom_field');

Currently our function is really not that useful, since the key and value of our custom field are the same. However, there is really very little limit to what we can do with filters. Perhaps a more useful function would be an auto- tagger. Suppose I often write about cooking, wordpress, and latex (which I do). But when I am posting via e-mail, I frequently forget to add tags. We could write a little filter function to read the body of the post, and automatically add tags depending on the content. Here is what it might look like:

function auto_tag($post) {  
  // this function automatically inserts tags for a post  
  $my_tags=array('cooking', 'latex', 'wordpress');  
  foreach ($my_tags as $my_tag) {    
    if (stripos($post['post_content'], $my_tag)!==false)      
      array_push($post['tags_input'], $my_tag);  
  }  
  return ($post);
}
add_filter('postie_post', 'auto_tag');

I’m sure that users will come up with many other interesting filters. If you develop any you would like to share, please post them on the postie forum

Tuesday, August 18th, 2009

Blogging with LaTeX

The first question on reader’s mind must be — why use LaTeX to blog?

Well, I have a pretty specific instance in mind, but I can imagine that others might be interested as well. This fall I am teaching a course on computational corpus linguistics at CU Boulder. I like to have some materials online for the students, such as the syllabus, course notes, etc. I thought about setting up a simple webpage, but then I decided instead to use wordpress, because it would give me extra functionality, such as auto-generating rss feeds, and with some plugins, would allow me to notify students via e-mail when I post lecture notes or slides, or homework tips. The one drawback I could see is that it would be hard to update the syllabus throughout the semester, as I tend to change the calendar some throughout the semester. Then I thought that maybe I could hack up a quick xml-rpc solution to the problem, and about an hour later, I had it done. All I needed was the Wordpress::API perl module from CPAN.

Now I have a handy little publish script which first compiles my syllabus as pdf, then compiles it as html using plasTeX. Then I run it through tidy for formatting and hack in a few more things. Then I update the syllabus page on the course blog via xml-rpc. Finally, I rsync the pdf to the server. And with the post-notification plugin for wordpress, students will get an e-mail when the syllabus is updated.

Here are the scripts:

publish

#!/bin/bash
# this script compiles a pdf version, an html version, and then copies it to my
# webserver

# compile as pdf
pdflatex syllabus && pdflatex syllabus

# compile as html
plastex  -c syllabus.cfg syllabus
# clean up code a bit
tidy --show-body-only true --ascii-chars true  -asxhtml --input-encoding utf8 --output-encoding ascii -wrap 0 -indent --tab-size 4 syllabus/index.html > syllabus/syllabus.tmp

# add in link to pdf version in the html version
cat pdflink syllabus/syllabus.tmp > syllabus/syllabus.html

# update the syllabus page via xml-rpc
./updateSyllabusPage.pl

# upload the newest version of the pdf
rsync -avzu syllabus.pdf robfelty.com:/var/www/html/robfelty/teaching/ling5200Fall2009/ling5200Fall2009-syllabus.pdf

updateSyllabusPage.pl

#!/usr/bin/perl -w
use WordPress::API;

# get new syllabus content
my $contentFile = 'syllabus/syllabus.html';
open(CONTENT, $contentFile);

# slurp in content
$content = do {local ( $/ ); <CONTENT> };

my $w = WordPress::API->new({
   proxy => 'http://robfelty.com/teaching/ling5200Fall2009/xmlrpc.php',
   username => 'myusername',
   password => 'mypassword',
});

my $page = $w->page(3);

$page->description($content);
$page->save;

Finally, if you want to see how I customize content for pdf and html separately, you can check out the LaTeX source file

Friday, August 14th, 2009

Postie 1.3.0 released

postie_200x200_7After more than a month of fixing bugs and adding features, I have decided it is time to release Postie 1.3.0, the wordpress plugin which adds many features to post to your blog via e-mail. 1.3 offers many new features over the 1.2 line of postie, including better attachment handling, better language and character set support, and easier configuration. Here is a list of the new features and bug fixes from 1.3.beta to 1.3.0.

  • Features
    • Added mpeg4 to default list of videotypes
    • Added support for KOI8-R character set (cyrillic)
    • Added support for iso-8859-2 character set (eastern european)
    • Added option to include custom icons for attachments
    • Added option to send confirmation message to sender
    • Enhanced e-mails for unauthorized users
    • Added option to send unauthorized e-mail back to sender
    • Added option to only allow e-mails from a specified list of smtp
    • servers

    • Added option to use shortcode for embedding videos (works with the
    • videos plugin http://www.daburna.de/download/videos-plugin.zip

    • Better handling of comment authors (thanks to Petter for suggestion)
    • Simplified message options (now includes an advanced options section)
    • Added filter ability for post content
  • Bug fixes
    • No longer including wp-config.php
    • If tmpdir is not writable, try a different tmpdir
    • More subject encoding fixes
    • Updated image templates, which were causing problems for cron
    • Fixed in text captions
    • Fixed SQL problems when updating options
    • Fixed name clashes with other plugins
    • Fixed custom image field

I want to thank the many users who were willing to test out new features and bug fixes by trying out the development version. in particular, I want to thank Kyle and Hab at Abilene Christian University for offering me financial support to develop some additional features for their use of postie for a course at their university. I think that other postie users will enjoy some of these new features as well.