Ordering wordpress menu items

Note: when I talk about wordpress here, I’m talking about the http://www.wordpress.com online service.

There are many available themes available for your wordpress blog, and they all come with at least one menu. The one I’m using is called “Enterprise” and comes with two menus. By default, the top menu contains my blog “pages” and the bottom menu contains my blog “categories”:

blog_menu

A common requirement is: how do I change the ordering of the menu entries ? (ie: what if I want the “uncategorized” category to be the last one ?)

Some people suggested adding a number if front of each category (like “1. Android” and “2. Linux”), hoping that wordpress would display the entries in the ascending order, but this doesn’t work. The truth is that this is not possible if you use the default theme menus: you need to create your own.

To do this, go to the “Appearance > Menu” section of your dashboard:

dashboard_menu

You will then see a “Theme locations” section with two dropdown lists. This is where you can specify your top and bottom menus (that is: if your theme allows two menus of course). By default, nothing is selected, which means that the theme built-in menus are used. As I said above, if you want to control exactly how your menus are organized, you need to create your own menus instead of using the built-in ones:

theme_locations_default

To create a new menu, click on the “+” button:

create_menu

Then, select the pages and/or categories that should be part of your menu and click on the “Add to menu” button:

pages_categories

Once the entries are added to your menu, use drag and drop to move them around until they are in the correct order.

drag_category

Finally, don’t forget to click on the “Save Menu” button !

Then, go back to the “Theme Locations” section and set your newly created menu as the primary one:

theme_locations_custom

There you go:

blog_menu_custom

Rotating photos from mobile devices uploaded to Google App Engine

I’m currently working on a Google App Engine application that allows users to upload photos from their mobile device and then view these photos in a slideshow.

So far, so good, until I realized that some of the uploaded images where sometimes rotated.

What the… ?

This is where I learnt about the concept of EXIF metadata. Long story short: each photo on your mobile device is stored as a jpeg file which contains the photo itself, but also a bunch of extra metadata, like the photo orientation.

This photo orientation depends on your mobile device orientation when the photo is taken. Using the iphone as an example, you basically have 4 possible positions:

  • If the iphone “home” button points downwards when the photo is taken, the photo is rotated 90° counter clockwise (“turned to the left” if you prefer)
  • If the iphone “home” button points upwards when the photo is taken, the photo is rotated 90° clockwise (“turned to the right” if you prefer)
  • If the iphone “home” button points to the left when the photo is taken,  the photo is rotated 180°.
  • If the iphone “home” button points to the right when the photo is taken,  the photo is not rotated (I guess this is how the iphone is supposed to be held when taking pictures).

What I ended up doing is:

  1. User uploads a photo
  2. GAE application determines what the photo orientation is and rotates it accordingly
  3. GAE application stores the rotated photo in the datastore

How to determine the photo orientation

As previously explained, you need to access the photo EXIF metadata and get the value of the “orientation” property.

Luckily, there is a great open-source project that can help us extract this value: it’s called metadata-extractor.

Here is how I used this library:


private int getEXIFOrientation(byte[] bytes) {
int orientation = -1; // default = unknown
 ByteArrayInputStream bis = null;
 try {
 bis = new ByteArrayInputStream(bytes);
 Metadata metadata = ImageMetadataReader.readMetadata(new BufferedInputStream(bis), false);
 ExifIFD0Directory exifDir = metadata.getDirectory(ExifIFD0Directory.class);
 if (exifDir != null) {
 orientation = exifDir.getInt(274); // 274 is the EXIF orientation standard code
 }
 } catch (Exception e) {
 log.warning("Couldn't extract EXIF orientation from image");
 } finally {
 if (bis != null) try {
 bis.close();
 } catch (IOException e) {
 // nothing
 }
 }
 return orientation;
}

How do I know that 274 is the internal code for the orientation EXIF tag ? Because of this link.

The orientation property can have 8 different values, but only 4 of them (in bold) are used:

  • 1: image is Normal-> that’s the orientation value you get when the iphone home button is on the right
  • 2: image is flipped horizontally
  • 3: image is rotated 180° -> that’s the orientation value you get when the iphone home button is on the left
  • 4: image is flipped vertically
  • 5: image is rotated 90° CCW and flipped vertically
  • 6: image is rotated 90° CCW -> that’s the orientation value you get when the iphone home button is upwards
  • 7: image is rotated 90° CW and flipped vertically
  • 8: image is rotated 90° CW -> that’s the orientation value you get when the iphone home button is downwards

How to rotate the image

That’s the easy part: we just use the GAE Image service, more precisely: ImagesServiceFactory.makeRotate().

  • orientation = 1 -> don’t rotate
  • orientation = 3 -> rotate 180° clockwise
  • orientation = 6 -> rotate 90° clockwise
  • orientation = 8 -> rotate -90° clockwise (or 90° counter clockwise if you prefer).

So we end up with:


private byte[] rotateImage(byte[] bytes) {
byte[] result = bytes;
int orientation = getEXIFOrientation(bytes);
int degrees = -1;
if (orientation == 3) degrees = 180;
else if (orientation == 6) degrees = 90;
else if (orientation == 8) degrees = -90;
if (degrees != -1) {
Image img = ImagesServiceFactory.makeImage(bytes);
Transform rotation = ImagesServiceFactory.makeRotate(degrees);
// GAE changes output format from JPEG to PNG while rotating the image if the expected output format is not given:
OutputSettings settings = new OutputSettings(ImagesService.OutputEncoding.JPEG);
settings.setQuality(1);
img = ImagesServiceFactory.getImagesService().applyTransform(rotation, img, settings);
result = img.getImageData();
}
return result;
}

Laurent KUBASKI

Serving dynamic images in Google App Engine

Serving a static image in Google App Engine is as easy as:


<img src="/images/01.jpg">

But what if the image is stored in the datastore as a BLOB ?

There is an official “Serving Dynamic Images with Google App Engine” article in the Google App Engine knowledge base, but it doesn’t explain all the needed steps to accomplish this… and that’s exactly what I’m going to do.

The thing is: the “src” attribute of the HTML “img” tag doesn’t need to be the path of an image on the server filesystem. It can also be the url of a Servlet that will return an image.

So, assuming that you know the id of your image in the datastore, you can have this:


<img src="/serveImage?id=<%=key.getId()%>">

/serveImage is the URI of my ServeImageServlet, as configured in web.xml:


<servlet>
<servlet-name>ServeImageServlet</servlet-name>
<servlet-class>fr.lk.servlet.ServeImageServlet</servlet-class>
</servlet>

<servlet-mapping>
<servlet-name>ServeImageServlet</servlet-name>
<url-pattern>/serveImage</url-pattern>
</servlet-mapping>

Now let’s see ServeImageServlet.java:

public class ServeImageServlet extends HttpServlet {

@Override
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
String id = req.getParameter("id");
byte[] bytes = new DAO().getImage(Long.parseLong(id));
resp.setContentType("image/jpeg");
resp.getOutputStream().write(bytes);
}
}

As you can see, the “id” request parameter is used to retrieve the image from the datastore (as a raw byte array), and we just directly write it to the response output stream.

Laurent KUBASKI