How I Do Page Level Meta Tags With Docpad

DocPad is a fantastic Node-based tool for generating static web sites.  I have used it on a couple of simple, content only web sites and it gives you all of the needed tools for templates, programmability and creating reusable components.  For all of those sites that don’t really need any server side functionality, it’s a great alternative that leaves you with a set of web site files that you can host right on Amazon S3.

In my time with DocPad I have only found one missing feature built in support for page level meta tags.  Search engine optimization is constantly changing and new features such as Open Graph and Twitter card tags are absolutely necessary for the visibility of your content on social media.  If you’ve combed through the DocPad documentation like I have then you have no doubt come across DocPad’s meta block as a potential solution.  Except the meta block strangely does not allow you to add meta tags to it as is the case with the style and script blocks.

I came up with another solution using the document meta data in DocPad that works great for me.  Here’s how it works:

In Your Layout File

Your layout file should define all of the meta tags that will have the same values across the entire site and then pull in the page level values from the document.  Here’s an example of what I do:

<meta property="og:locale" content="en_US" />
<meta property="og:type" content="<%= if @document.url == "/index.html" then "website" else "article" %>">
<meta property="og:title" content="<%= @document.heading %>" />
<meta property="og:description" content="<%= @document.description %>" />

In the example above you can see that the og:locale tag is set to a static value, since that will stay the same across all pages. The og:type tag will choose between website or article depending on if it is the home page or not. Finally, I have the og:title and og:description tags pulling from my custom document metadata that we will add next.

In Your Documents

No configuration is required to add items to a document’s meta data on the fly.  All you have to do is update each file and define the meta data you need, then save and regenerate.  If you haven’t yet defined these, it’s no problem. Your generated output will leave them blank in the meantime.  Here’s the top of an example document:


---
title: "Home"
layout: "default"
isPage: true
heading: "My Home Page"
description: "A description for the home page."
---

…Your HTML content here.

When your site is generated, the heading and description meta data will be pulled into the meta tags that we set up in the layout file.  This method works great for me.  I only define information on the page level that is specific to that page.  It’s right where it should be.

CodeCalculated Web Site Launch!

For the launch of CodeCalculated, I have built an entirely new web site.  I wanted to throw together a blog post that goes in depth on the technologies that were used and a little bit about the development workflow.

The web site was built using Docpad, a fantastic, node based static site generator that I am growing to love.  Docpad takes a set of template files, static content and HTML documents which it combines to create a full fledged web site.   Your template contains all of the repeating information on your site, such as navigation, footer and stylesheets.  A document file represents each page of your site.  You just tell Docpad which template to use, provide the page content in your document and the output is a set of flattened pages ready to be pushed out to your web host.  I keep an instance of Docpad running with a web server pointed to the output directory so that I can view my changes instantly.

The front end is much more basic.  I chose Bootstrap, with some slight style modifications to achieve my look.  I tend to waver back and forth between Bootstrap and Foundation, but now I’m back to Bootstrap.  I find it much easier to customize and it contains much more of the visual elements that I like to use, such as the glyph icons.  With either framework you get a set of scaffolding components that make responsive design a piece of cake.

At the moment I do not have any true back end functionality on the web site, so I can host it easily on Amazon S3.  The process for setting up a bucket for hosting static web sites on Amazon S3 is very easy.  You can check that out here if you are interested.  In the end, it’s the most affordable static hosting solution available and you only pay for what you use.

The web site was coded entirely using Atom on the Mac.  Some graphics work was done using Paint.net.   That’s it.  A very simple tool chain for development.

Take a look at the web site at codecalculated.com and let me know if you have any feedback.

Generating an Image of a PDF Page

I recently completed a project that required a thumbnail image automatically be generated from the first page of every PDF file that is uploaded to the system.  I was rather surprised to find that there was no drop in solution for such a thing.  There are many libraries out there that can create a PDF file from HTML content or an image, but no standalone libraries that could go from PDF to an image.  After testing out a couple of methods, I was able to find what I believe to be the easiest and least invasive method to implement it in a web application..

What You Will Need

To generate images from PDF in your project, you will need a couple of things.

Ghostscript, a set of libraries for working with a PDF.  You will need to download the version specific to your environment (32 bit/64 bit).  You can download those here.

GhostscriptSharp, a wrapper for using the Ghostscript libraries in .NET.  You can download it here.  It is written in C#, so if you are using VB.NET you will need to create a code sub-directory in your Web.config to use the file in your project.

Setup

You will need to do a couple of things to get the Ghostscript components to function before you write any code.  First, you need to extract the gsdll file to a location on your system.  (Either gsdll32.dll or gsdll64.dll depending on your CPU.)

Then, you need to modify GhostscriptSharp.cs to specify the path to the Ghostscript library that you extracted before.  Look for this code on line 12 of the GhostscriptSharp.cs file:

#region Hooks into Ghostscript DLL

[DllImport("gsdll64.dll", EntryPoint = "gsapi_new_instance")]

private static extern int CreateAPIInstance(out IntPtr pinstance, IntPtr caller_handle);

[DllImport("gsdll64.dll", EntryPoint = "gsapi_init_with_args")]

private static extern int InitAPI(IntPtr instance, int argc, string[] argv);

[DllImport("gsdll64.dll", EntryPoint = "gsapi_exit")]

private static extern int ExitAPI(IntPtr instance);

[DllImport("gsdll64.dll", EntryPoint = "gsapi_delete_instance")]

private static extern void DeleteAPIInstance(IntPtr instance);

#endregion

You will need to change the paths in the DllImport constructors to the location of the file on your machine.  The DllImportAttribute only accepts a constant string, so you cannot pass a variable with the path or using a Web.config value.  This prevents you from using Server.MapPath to generate the path to your project’s bin folder, which is also unfortunate.

The Code

The actual implementation of the image generation from PDF is very simple once you have reached this point.  You just need to make a call to the GhostscriptWrapper.GeneratePageThumb method with the path to the PDF, and the path where the image should be saved.  You also specify the page number you want to generate from and the height and width of the final image.  A call to GeneratePageThumb might look like this:

// Creates a 100 x 100 thumbnail of page 1.
GhostscriptWrapper.GeneratePageThumb(pdfFileName, outputFileName, 1, 100, 100);

You will also need to import the GhostscriptSharp namespace in your code file.  That is all that there is to it!  After running your application, you will see the image file in the specified path.

Its important to note that GeneratePageThumb is a shortcut method that will only generate a JPG image.  If you need to have more control over the output of your image, then you will need to use the GenerateOutput method and pass in a GhostscriptSettings object that contains all of your required values.  The GhostscriptSharp link above provides more detailed examples if you need them.

Thanks for reading!  If you have any troubles with the process, feel free to leave a comment below.

Fixing reCAPTCHA.net 404 Errors

Last week, Google decommissioned the reCAPTCHA API components that were hosted on recaptcha.net.  According to reCAPTCHA support, the change was supposed to have occurred back in April, but for some reason or another the site has only now been replaced with a 404 error.

The good news is that Google has not made any changes to the reCAPTCHA API, so you will just need to change the reCAPTCHA path from the old location to the new location hosted with Google.

In your application, all instances of this URL:

http://api.recaptcha.net

need to be replaced with this:

http://www.google.com/recaptcha/api

You will need to change all references to that URL, including the recaptcha.js or recaptcha_ajax.js files and the /verify URL.  It is as simple as that.  Keep in mind that if your site uses SSL then you need to change the “http” in the URL to “https”.

Many Joomla users have been affected by this problem as well.  Luckily a proposed fix has already been committed to Joomla’s GitHub repository.  To view those changes or to download the updated file, click here.  If you’re not confident enough to fix the issue on your own, a formal patch should be on it’s way from Joomla soon.

Feel free to leave a comment if you have any questions.  Thanks for reading!

Code Wars: Training in Programming Arts

As developers we have to frequently consult outside resources for information on how to complete certain tasks.  Whether it’s a book or an online tutorial, a quick refresher is always helpful to get a push in the right direction.  The problem is that we will often look for these resources when we know specifically what we need to do, rather than using them to buff up our skills.

There are many sites out there that allow you to do programming challenges to work on your proficiency with a language.  Project Euler, TopCoder or the Daily Programmer subreddit come to mind.  My newest addiction of this type of site is Code Wars.

What is Code Wars?

I like to explain Code Wars as a combination of small programming challenges and Xbox style achievements.  You complete a series of code “katas“: short snippets or bug fixes that test basic understanding of programming language concepts.  For each kata that you complete, you work your way up to higher ranks and increasingly more difficult tasks.

Code Wars Dashboard

The user dashboard in Code Wars.

Code Wars tracks the type of the katas that you complete into different types, such as bug fixes, algorithms and reference.  You can also complete katas in either JavaScript, Coffee Script or Ruby.  Since Code Wars starts with the basics, it is perfect for supplementing your learning of a new language.

Test Your Might

Code Wars provides you with a very simple code editor with syntax highlighting.  It works surprisingly well in the browser, complete with handling of indentation and other features.  You are also provided with the ability to write unit tests against your solution to test any cases that will help you complete the kata.  Then you submit your solution.  There becomes nothing more addicting than getting that green check mark every time you complete a kata.

The best feature of Code Wars comes after you complete a kata.  Once you submit your solution and it is verified, you get to see the solutions that other developers submitted as well.  Sometimes you will see solutions that are more complicated than your own, but quite often you will see solutions that are mind blowing in their simplicity.  I typically spend just as much time reviewing other’s solutions as I do coming up with my own.

Future Wars

I have no doubt that in the future Code Wars will bring support for more languages.  I’m excited at the possibility of completing code katas with Python or PHP.  I can’t help but think that Code Wars would also be an amazing tool for teaching people how to use the UNIX command line.

The beauty of Code Wars is that its katas are populated by user submissions, so it will continue to grow with new content in the as time goes on.

Want to test your skills?  Sign up by completing the example kata at http://www.codewars.com!  Thanks for reading!  If you would like, you can view my Code Wars profile here!

Getting Started with the Stripes Framework

Stripes is an up-and-coming alternative to Apache Struts for developing web applications using Java. Stripes is very well documented, but leaves something to be desired in their sample projects and jump start information.  I’ve also noticed that while some of the features of Stripes are very extensible, it can be hard to understand what is needed and what isn’t.  I’ve included a quick briefing on some of the common pitfalls below.

ActionResolver

ActionResolver is a component of Stripes that discovers your ActionBeans and maps them to URLs for you to use in your views. One common mistake that occurs when setting up a new Stripes project is not having the ActionResolver properly mapped to the package containing your ActionBeans. This is done in the web.xml configuration file for your project.

<filter>
	<display-name>Stripes Filter</display-name>
	<filter-name>StripesFilter</filter-name>
	<filter-class>net.sourceforge.stripes.controller.StripesFilter</filter-class>
	<init-param>
		<param-name>ActionResolver.Packages</param-name>
		<param-value>{Your ActionBean package name goes here.}</param-value>
	</init-param>
</filter>

If this is not configured properly, you may see errors such as this: “Could not locate an ActionBean that was bound to the URL. Commons reasons for this include mis-matched URLs and forgetting to implement ActionBean in your class.” This can be misleading because the actual cause is related to neither of those reasons.

UrlBinding

One particular difficulty that I had when I started working with Stripes was the usage of UrlBinding annotations. The reason for this is that if your ActionBeans are named properly, then you may never need to use them.

For example, let’s say you have an ActionBean class named LoginActionBean. By default, the ActionResolver will automatically bind this to the Login.action URL without any manual configuration required from you. The only time you ever need to use a UrlBinding is if your URL needs to differ from the automatically generated URL.

This is important to know, because at times the error messages returned by Stripes when it is not configured properly, such as the ones above, can lead you to using a UrlBinding even when you don’t need it.

Using HTML5/Custom Attributes

If you try to use custom attributes with one of the Stripes jump start projects, you will find that using HTML5 or other custom attributes will cause an exception to occur in Stripes.

For example, if you want to add an HTML5 placeholder attribute to a text input that is generated by Stripes, you will not be able to do it with the standard Stripes tag library.  This is also the case with JavaScript event attributes such as “onclick” or “onchange”, and custom attributes prefixed with “data-“.

I found the solution difficult to track down, but all you need to do is use the dynamic tag library provided with Stripes.  To use the Stripes dynamic tag library in your project, just add this taglib reference to the top of your JSP file:

<%@ taglib prefix="stripes" uri="http://stripes.sourceforge.net/stripes-dynattr.tld" %>

You can use the standard Stripes tag library and the dynamic tag library together on the same page.  You just need to set the prefix value in the code above to something different than the prefix value you are using for the standard tag library.  This is actually the recommended usage of the dynamic tags, yet it is not used in any of the current Stripes samples.

Never fear

Stripes is a lightweight framework that is great for developing Java web applications. Not many people are using it, and unfortunately that means that there are not many resources available outside of the documentation. However, the documentation is very detailed and technical. The process of getting up to speed may take longer than usual, but having an alternative framework to available is great for the future of Java on the web.

More information, including samples and comparisons to Struts can be found at http://www.stripesframework.org.