Local Dev Environments For Newbies Part 2: AMP on Windows 7

Previously, we discussed the benefits of installing a local AMP stack (Apache, MySQL & PHP) for the purposes of development and testing, and walked through installing a stack in the Mac environment.  In this post, we will turn our attention to Windows.  (If you have not read Local Dev Environments for Newbies Part 1, and you are new to the AMP stack, you might want to go read the Introduction and Tips sections before continuing with this tutorial.)

Much like with the Mac stack, there are Windows stack installers that will do all of this for you.  For example, if you are looking to develop for Drupal, there’s an install package called Acquia that comes with a stack installer.   There’s also WAMPserver and XAMPP.  If you opt to go this route, you should do some research and decide which option is the best for you.  This article contains reviews of many of the main players, though it is a year old.

However, we are going to walk through each component manually so that we can see how it all works together.

So, let’s get going with Recipe 2 – Install the AMP Stack on Windows 7.

Prerequisites:

Notepad and Wordpad come with most Windows systems, but you may want to install a more robust code editor to edit configuration files and eventually, your code.  I prefer Notepad++, which is open source and provides much of the basic functionality needed in a code editor.  The examples here will reference Notepad++ but feel free to use whichever code editor works for you.

For our purposes, we are not going to allow traffic from outside the machine to access our test server.  If you need this functionality, you will need to open a port in your firewall on port 80.  Be very careful with this option.

As a prerequisite to installing Apache, we need to install the Visual C++ 2010 SP1 Redistributable Package x86.  As a pre-requisite to installing PHP, we need to install the Visual C++ 2008  SP1 Redistributable Package x86.

I create a directory called opt\local in my C drive to house all of the stack pieces.  I do this because it’s easier to find things on the command line when I need to and I like keeping development environment applications separate from Program Files.  I also create a directory called sites to house my web files.

wamp-opt copy

The last two prerequisites are more like common gotchas.  The first is that while you are manipulating configuration and initialization files throughout this process, you may find the Windows default view settings are getting in your way.  If this is the case, you can change it by going to Organize > Folder and search options > View tab.

wamp-windows

This will bring up a dialog which allows you to set preferences for the folder you are currently viewing.  You can select the option to “show hidden files” and uncheck the “hide file extensions” option, both of which make developing easier.

The other thing to know is that in our example, we will work with a Windows 7 installation – a 64-bit operating system.  However, when we get to PHP, you’ll notice that their website does not provide a 64-bit installer.  I have seen errors in the past when a 32-bit PHP installer and a 64-bit Apache version were both used, so we will install the 32-bit versions for both components.

Ok, I think we’re all set.  Let’s install Apache.

Apache

We want to download the .zip file for latest version.  For Windows binaries, I use apachelounge, which builds windows installer files.  For this example we’ll download httpd-2.4.4-win32.zip to the Desktop of our Windows machine.

wamp-apache1

Next, we want to extract files into chosen location for Apache directory, eg c:\opt\local\Apache24.  You can accomplish this a variety of ways but if you have WinZip, you can follow these steps:

  1. Copy the .zip folder to c:\opt\local
  2. Right-click and select “Extract all files”.
  3. Open the extracted folder, right-click on the Apache24 folder and select Cut.
  4. Go back up one directory and right-click to Paste the Apache24 folder, so that it now resides inside c:\opt\local.

No matter what unzip program you use, this is the configuration we are shooting for:wamp-apachedir

This extraction “installs” Apache; there is no installer to run, but we will need to configure a few things.

We want to open httpd.conf: this file contains all of the configuration settings for our web server.  If you followed the directions above, you can find the file in C:\opt\local\Apache24\conf\httpd.conf – we want to open it with our code editor and make the following changes:

1.  Find this line (in my copy, it’s line 37):

ServerRoot “c:/Apache24”

Change it to match the directory where you installed Apache.  In my case, it reads:

ServerRoot “c:/opt/local/Apache24”

You might notice that our slashes slant in the opposite direction from the usual Windows sytax.  In Windows, backslash ( \ ) delineates different directories, but in Unix, it’s forward slash ( / ).  Apache reads the configuration file in the Unix manner, even though we are working in Windows.  If you get a “directory not found” error at any point, check your slashes.

2.  At Line 58, we are going to change the listen command to just listen to our machine.  Change

Listen 80

to

Listen localhost:80

3.  There are 100 lines around 72-172 that all start with LoadModule.  Some of these are comments (they begin with a “#”).  Later on, you may need to uncomment some of these for a certain web program to work, like SSL.  For now, though, we’ll leave these as is.

4.  Next, we want to change our Document Root and the directory directive to the directory which has the web files.  These lines (beginning on line 237 in my copy) read:

DocumentRoot “c:/Apache24/htdocs”

Later, we’ll want to change this to our “sites” folder we created earlier.  For now, we’re just going to change this to the Apache installation directory for testing.  So, it should read:

DocumentRoot “c:/opt/local/Apache24/htdocs”

Save the httpd.conf file.  (In two of our test cases, after saving the file, closing and re-opening, the file appeared unchanged.  If you are having issues, try doing Save As and save the file to your desktop, then drag it into c:\opt\local\Apache24).

Next, we want to test our Apache configuration.  To do this, we open the command line.  In Windows, you can do this by going to the Start Menu, and typing

cmd.exe

in the Search box.  Then, press Enter.  Once you’re in the command prompt, type in

cd \opt\local\Apache24\bin

(Note that the first part of this path is the install directory I used above.  If you chose a different directory to install Apache, use that instead.)  Next, we start the web server with a “-t” flag to test it.  Type in:

httpd –t

If you get a Syntax OK, you’re golden.

wamp-apache4

Otherwise, try to resolve any errors based on the error message. If the error message does not make any sense after checking your code for typos, go back and make sure that your changes to httpd.conf did actually save.

Once you get Syntax OK, type in:

httpd

This will start the web server.  You should not get a message regarding the firewall if you changed the listen command to localhost:80.  But, if you do, decide what traffic you want to allow to your machine.  I would click “Cancel” instead of “Allow Access”, because I don’t want to allow outside access.

Now the server is running.  You’ll notice that you no longer have a C:\> prompt in the Command window.  To test our server, we open a browser and type in http://localhost  – you should get a website with text that reads “It works!”

wamp-apache5

Instead of starting up the server this way every time, we want to install it as a Windows service.  So, let’s go back to our command prompt and press Ctrl+C to stop web server.  You should now have a prompt again.

To install Apache as a service, type:

httpd.exe –k install

You will most likely get an error that looks like this:

wamp-apache6

We need to run our command prompt as an administrator.  So, let’s close the cmd.exe window and go back to our Start menu.  Go to Start > All Programs > Accessories and right-click on Command Prompt.  Select “Run As Administrator”.

(Note: If for some reason you do not have the ability to right-click, there’s a “How-To Geek” post with a great tip.  Go to the Start menu and in the Run box, type in cmd.exe as we did before, but instead of hitting Enter, hit Ctrl+Shift+Enter.  This does the same thing as the right-click step above.)

Click on Yes at the prompt that comes up, allowing the program to make changes.  You’ll notice that instead of starting in our user directory, we are starting in Windows\system32 So, let’s go back to our bin directory with:

cd \opt\local\Apache24\bin

Now, we can run our

httpd.exe –k install

command again, and it should succeed.  To start the service, we want to open our Services Dialog, located in the Control Panel (Start Menu > Control Panel) in the Administrative Tools section.  If you display your Control Panel by category (the default), you click on System & Security, then Administrative Tools.  If you display your control panel by small icon, Administrative Tools should be listed.

Double click on Services.

wamp-apache8

Find Apache2.4 in the list and select it.  Verify that the Startup Type is set to Automatic if you want the Service to start automatically (if you would prefer that the Service only start at certain times, change this to Manual, but remember that you have to come back in here to start it).  With Apache2.4 selected, click on Start Service in the left hand column.

wamp-apacheserv

Go back to the browser and hit Refresh to verify that everything is still working.  It should still say “It Works!”  And with that affirmation, let’s move to PHP.

 PHP

(Before installing PHP, make sure you have installed the Visual C++ 2008 Redistributable Package from the prerequisite section.)

For our purposes, we want to use the Thread Safe .zip from the PHP Downloads page.    Because we are running PHP under Apache, but not as a CGI, we use the thread safe version.  (For more on thread safe vs. non-thread safe, see this Wikipedia entry or this stackoverflow post)

PHP Download

Once you’ve downloaded the .zip file, extract it to your \opt\local directory.  Then, rename the folder to simply “php”.  As with Apache24, extracting the files does the “install”, we just need to configure everything to run properly.  Go to the directory where you installed PHP, (in my case, c:\opt\local\php) and find php.ini-development.

Make a copy of the file and rename the copy php.ini (this is one of those places where you may want to set the Folder and search options if you’re having problems).

PHP ini file

Open the file in Notepad++ (or your code editor of choice).  Note that here, comments are preceded by a “;” (without quotes) and the directories are delineated using the standard Windows format, with a “\”.  Most of the document is commented out, and includes a large section on recommended settings for production and development, so if you’re not sure of the changes to make you can check in the file (in addition to the PHP documentation).  For this tutorial, we want to make the following changes:

1.  On line 708, uncomment (remove semi-colon) include_path under “Windows” and make sure it matches the directory where you installed PHP (if the line numbers have changed, just search for Paths and Directories).

wamp-php2
2.  On line 730, uncomment the Windows directive for extension_dir and change extension_dir to match c:\opt\local\php\ext

wamp-php3
3.  Beginning on Line 868, in the Windows Extensions section, uncomment (remove the semi-colon) from the following lines (they are not right next to each other, they’re in a longer list, but we want these three uncommented):

extension=php_mysql.dll
extension=php_mysqli.dll
extension=php_pdo_mysql.dll

Save php.ini file.

You may want to double-check that the .dll files we enabled above are actually in the c:\opt\local\php\ext folder before trying to run php, because you will see an error if they are not there.

Next, we want to add the php directory to our path environment variables.  This section is a little tricky; be *extremely* careful when you are making changes to system settings like this.

First, we navigate to the Environment variables by opening the Control Panel and going to System & Security > System > Advanced System Settings > Environment Variables.

In the bottom scroll box, scroll until you find “Path”, click on it, then click on Edit.

wamp-php6

Append the following to the end of the Variable Value list (the semi-colon ends the previous item, then we add our installation path).

;c:\opt\local\php

wamp-php7

Click OK and continue to do so until you are out of the dialog.

Lastly, we need to add some lines to the httpd.conf so that Apache will play nice with PHP.  The httpd.conf file may still be open in your text editor.  If not, go back to c:\opt\local\Apache24\conf and open it.  At the bottom of this file, we need to add the following:

LoadModule php5_module "c:/opt/local/php/php5apache2_4.dll"
AddHandler application/x-httpd-php .php
PHPIniDir "c:/opt/local/php"

This tells Apache where to find php and loads the module needed to work with PHP.  (Note:  php5apache2_4.dll must be installed in the directory you specified above in the LoadModule statement.  It should have been extracted with the other files, but to download the file if it is not there, you can go to the apachelounge additional downloads page.)

While we’re in this file, we also want to tell Apache to look for an index.php file.  We’ll need this for testing, but also for some content management systems.  To do this, we change the DirectoryIndex directive on line 271.  It should look like

<IfModule dir_module>
  DirectoryIndex index.html

We want to change the DirectoryIndex line so it reads

DirectoryIndex index.php index.html

Save httpd.conf.

Before we restart Apache to pick up these changes, we’re going to do one last thing.  To test our php, we want to create a file called index.php with the following text inside:

<!--?php <span class="hiddenSpellError" pre="php "-->phpinfo() ?&gt;

Save it to c:\opt\local\Apache24\htdocs

wamp-php5

Restart Apache by going back to the Services dialog.  (If you closed it, it’s Control Panel > System & Security > Administrative Tools > Services).  Click on Apache2.4 and then click on Restart.

wamp-php8

If you get an error, you can always go back to the command line, navigate to c:\opt\local\Apache24\bin and run httpd.exe –t again.  This will check your syntax, which is most likely to the be problem.  (This page is also helpful in troubleshooting PHP 5.4 and Apache if you are having issues.)

Open a browser window and type in http://localhost – instead of “It Works!” you should see a list configuration settings for PHP.  (In one of our test cases, the tester needed to close Internet Explorer re-open it for this part to work.)

wamp-php9

Now, we move to the database.

MySQL

To install MySQL, we can follow the directions at the MySQL site.  For the purposes of this tutorial, we’re going to use the most recent version as of this writing, which is 5.6.11.  To download the files we need, we go to the Community Server download page.

MySQL Downloads

Again, we can absolutely use the installer here, which is the first option.  The MySQL installers will prompt you through the setup, and this video does a great job of walking through the process.

But, the since the goal of this tutorial is to see all the parts, I’m going to run through the setup manually.  First, we download the .zip archive.  Choose the .zip file which matches your operating system; I will choose 64-bit (there’s no agreement issue here).  Extract the files to c:\opt\local\mysql.  We do this in the same way we did the Apache24 files above.

Since we’re installing to our opt\local drive, we need to tell MySQL to look there for the program files and the data.  We do this by setting up an option file.  We can modify a file provided for us called my-default.ini.  Change the name to my.ini and open it with your code editor.

wamp-mysql2

In the MySQL config files, we use the Unix directory “/” again, and the comments are again preceded by a “#”.  So, to set our locations, we want to remove the # from the beginning of the basedir and datadir lines, and change to our installation directory as shown below.

wamp-mysql3

Then save my.ini.

As with Apache, we’re going to start MySQL for the first time from the command line, to make sure everything is working ok.  If you still have it open, navigate back there.  If not, remember to select the Run As Administrator option.

From your command prompt, type in

cd \opt\local\mysql\bin
mysqld --console

You should see a bunch of statements scroll by as the first database is created.  You may also get a firewall popup.  I hit Cancel here, so as not to allow access from outside my computer to the MySQL databases.

Ctrl+C to stop the server.  Now, let’s install MySQL as a service.  To do that, we type the command:

mysqld --install

wamp-mysql4

Next, we want to start the MySQL service, so we need to go back to Services.  You may have to Refresh the list in order to see the MySQL service.  You can do this by going to Action > Refresh in the menu.

wamp-mysql5

Then, we start the service my clicking on MySQL and clicking Start Service on the left hand side.

wamp-mysql6

 

One thing about installing MySQL in this manner is that the initial root user for the database will not have a password.  To see this, go back to your command line.  Type in

mysql -u root

This will open the command line MySQL client and allow you to run queries.  The -u flag sets the user, in this case, root.  Notice you are not prompted for a password.  Type in:

select user, host, password from mysql.user;

This command should show all the created user accounts, the hosts from which they can log in, and their passwords.  The semi-colon at the end is crucial – it signifies the end of a SQL command.

wamp-mysql8

Notice in the output that the password column is blank.  MySQL provides documentation on how to fix this on the Securing the Initial Accounts documentation page, but we’ll also step through it here.  We want to use the SET PASSWORD command to set the password for all of the root accounts.

Substituting the password you want for newpwd (keep the single quotes in the command), type in

SET PASSWORD FOR 'root'@'localhost' = PASSWORD('newpwd');
SET PASSWORD FOR 'root'@'127.0.0.1' = PASSWORD('newpwd');
SET PASSWORD FOR 'root'@'::1' = PASSWORD('newpwd');

You should get a confirmation after every command.  Now, if you run the select user command from above, you’ll see that there are values in the password field, equivalent to encrypted versions of what you specified.

A note about security: I am not a security expert and for a development stack we are usually less concerned with security.  But it is generally not a good idea to type in plain text passwords in the command line, because if the commands are being logged you’ve just saved your password in a plain text file that someone can access.  In this case, we have not turned on any logging, and the SET PASSWORD should not store the password in plain text.  But, this is something to keep in mind.

As before with Mac OS X, we could stop here.  But then you would have to administer the MySQL databases using the command line.  So we’ll install phpMyAdmin to make it a little easier and test to see how our web server works with our sites folder.

phpMyAdmin

Download the phpmyadmin.zip file from the phpmyadmin page to the sites folder we created all the way at the beginning.  Note that this does *not* go into the opt folder.

Extract the files to a folder called phpmyadmin using the same methods we’ve used previously.

wamp-phpmyadmin

Since we now want to use our sites folder instead of the default htdocs folder, we will need to change the DocumentRoot and Directory directives on lines 237 and 238 of our Apache config file.  So, open httpd.conf again.

We want to change the DocumentRoot to sites, and we’re going to set up the phpMyAdmin directory.

Change Document Root and Directory

Save the httpd.conf file.  Go back to Services and Restart the Apache2.4 service.

We will complete the configuration through the browser.  First, open the browser and try to navigate to http://localhost again.  You should get a 403 error.

wamp-phpmyadmin4

Instead, navigate to http://localhost/phpmyadmin/setup

wamp-phpmyadmin5

Click on the New Server button to set up a connection to our MySQL databases.  Double check that under the Basic Settings tab, the Server Name is set to localhost, and then click on Authentication.  Verify that the type is “cookie”.

At the bottom of the page, click on Save.  Now, change the address in the browser to http://localhost/phpmyadmin and log in with the root user, using the password you set above.

And that’s it.  Your Windows AMP stack should be ready to go.

In the next post, we’ll talk about how to install a content management system like WordPress or Drupal on top of the base stack.  Questions, comments or other recipes you would like to see?  Let us know in the comments.

 

Coding & Collaboration on GitHub

Previously on Tech Connect we wrote about the Git version control system, walking you through “cloning” a project onto to your computer, making some small changes, and committing them to the project’s history. But that post concluded on a sad note: all we could do was work by ourselves, fiddling with Git on our own computer and gaining nothing from the software’s ability to manage multiple contributors. Well, here we will return to Git to specifically cover GitHub, one of the most popular code-sharing websites around.

Git vs. GitHub

Git is open source version control software. You don’t need to rely on any third-party service to use it and you can benefit from many of its features even if you’re working on your own.

GitHub, on the other hand, is a company that hosts Git repositories on their website. If you allow your code to be publicly viewable, then you can host your repository for free. If you want to have a private repository, then you have to pay for a subscription.

GitHub layers some unique features on top of Git. There’s an Issues queue where bug reports and feature requests can be tracked and assigned to contributors. Every project has a Graphs section where interesting information, such as number of lines added and deleted over time, is charted (see the graphs for jQuery, for instance). You can create gists which are mini-repositories, great for sharing or storing snippets of useful code. There’s even a Wiki feature where a project can publish editable documentation and examples. All of these nice features build upon, but ultimately have little to do with, Git.

Collaboration

GitHub is so successful because of how well it facilitates collaboration. Hosted version control repositories are nothing new; SourceForge has been doing this since 1999, almost a decade prior to GitHub’s founding in 2008. But something about GitHub has struck a chord and it’s taken off like wildfire. Depending on how you count, it’s the most popular collection of open source code, over SourceForge and Google Code.[1] The New York Times profiled co-founder Tom Preston-Werner. It’s inspired spin-offs, like Pixelapse which has been called “GitHub for Photoshop” and Docracy which TechCrunch called “GitHub for legal documents.” In fact, just like the phrase “It’s Facebook for {{insert obscure user group}}” became a common descriptor for up-and-coming social networks, “It’s GitHub for {{insert non-code document}}” has become commonplace. There are many inventive projects which use GitHub as more than just a collection of code (more on this later).

Perhaps GitHub’s popularity is due to Git’s own popularity, though similar sites host Git repositories too.[2] Perhaps the GitHub website simply implements better features than its competitors. Whatever the reason, it’s certain that GitHub does a marvelous job of allowing multiple people to manage and work on a project.

Fork It, Bop It, Pull It

Let’s focus two nice features of GitHub—Forking and the Pull Request [3]—to see exactly why GitHub is so great for collaboration.

If you recall our prior post on Git, we cloned a public repository from GitHub and made some minor changes. Then, when reviewing the results of git log, we could see that our changes were present in the project’s history. That’s great, but how would we go about getting our changes back into the original project?

For the actual step-by-step process, see the LibCodeYear GitHub Project’s instructions. There are basically only two changes from our previous process, one at the very beginning and one at the end.

GItHub's Fork Button

First, start by forking the repository you want to work on. To do so, set up a GitHub account, sign in, visit the repository, and click the Fork button in the upper right. After a pretty sweet animation of a book being scanned, a new project (identical to the original in both name and files) will appear on your GitHub account. You can then clone this forked repository onto your local computer by running git clone on the command line and supplying the URL listed on GitHub.

Now you can do your editing. This part is the same as using Git without GitHub. As you change files and commit changes to the repository, the history of your cloned version and the one on your GitHub account diverge. By running git push you “push” your local changes up to GitHub’s remote server. Git will prompt you for your GitHub password, which can get annoying after a while so you may want to set up an SSH key on GitHub so that you don’t need to type it in each time. Once you’ve pushed, if you visit the repository on GitHub and click the “commits” tab right above the file browser, you can see that your local changes have been published to GitHub. However, they’re still not in the original repository, which is underneath someone else’s account. How do you add your changes to the original account?

GitHub's Pull Request Button

In your forked repository on GitHub, something is different: there’s a Pull Request button in the same upper right area where the Fork one is. Click that button to initiate a pull request. After you click it, you can choose which branches on your GitHub repository to push to the original GitHub repository, as well as write a note explaining your changes. When you submit the request, a message is sent to the project’s owners. Part of the beauty of GitHub is in how pull requests are implemented. When you send one, an issue is automatically opened in the receiving project’s Issues queue. Any GitHub account can comment on public pull requests, connecting them to open issues (e.g. “this fixes bug #43″) or calling upon other contributors to review the request. Then, when the request is approved, its changes are merged into the original repository.

diagram of forking & pulling on GitHub

“Pull Request” might seem like a strange term. “Push” is the name of the command that takes commits from your local computer and adds them to some remote server, such as your GitHub account. So shouldn’t it be called a “push request” since you’re essentially pushing from your GitHub account to another one? Think of it this way: you are requesting that your changes be pulled (e.g. the git pull command) into the original project. Honestly, “push request” might be just as descriptive, but for whatever reason GitHub went with “pull request.”

GitHub Applications

While hopefully we’ve convinced you that the command line is a fine way to do things, GitHub also offers Mac and Windows applications. These apps are well-designed and turn the entire process of creating and publishing a Git repository into a point-and-click affair. For instance, here is the fork-edit-pull request workflow from earlier except done entirely through a GitHub app:

  • Visit the original repository’s page, click Fork
  • On your repository’s page, select “Clone in Mac” or “Clone in Windows” depending on which OS you’re using. The repository will be cloned onto your computer
  • Make your changes and then, when you’re ready to commit, open up the GitHub app, selecting the repository from the list of your local ones
  • Type in a commit message and press Commit
    writing a commit message in GitHub for Windows
  • To sync changes with GitHub, click Sync
  • Return to the repository on GitHub, where you can click the Pull Request button and continue from there

GitHub without the command line, amazing! You can even work with local Git repositories, using the app to do commits and view previous changes, without ever pushing to GitHub. This is particularly useful on Windows, where installing Git can have a few more hurdles. Since the GitHub for Windows app comes bundled with Git, a simple installation and login can get you up-and-running. The apps also make the process of pushing a local repository to GitHub incredibly easy, whereas there are a few steps otherwise. The apps’ visual display of “diffs” (differences in a file between versions, with added and deleted lines highlighted) and handy shortcuts to revert to particular commits can appeal even to those of us that love the command line.

viewing a diff in GitHub for Windows

More than Code

In my previous post on Git, I noted that version control has applications far beyond coding. GitHub hosts a number of inventive projects that demonstrate this.

  • The Code4Lib community hosts an Antiharassment Policy on GitHub. Those in support can simply fork the repository and add their name to a text file, while the policy’s entire revision history is present online as well
  • The city of Philadelphia experimented with using GitHub for procurements with successful results
  • ProfHacker just wrapped up a series on GitHub, ending by discussing what it would mean to “fork the academy” and combine scholarly publishing with forking and pull requests
  • The Jekyll static-site generator makes it possible to generate a blog on GitHub
  • The Homebrew package manager for Mac makes extensive use of Git to manage the various formulae for its software packages. For instance, if you want to roll back to a previous version of an installed package, you run brew versions $PACKAGE where $PACKAGE is the name of the package. That command prints a list of Git commits associated with older versions of the package, so you can enter the Homebrew repository and run a Git command like git checkout 0476235 /usr/local/Library/Formula/gettext.rb to get the installation formula for version 0.17 of the gettext package.

These wonderful examples aside, GitHub is not a magic panacea for coding, collaboration, or any of the problems facing libraries. GitHub can be an impediment to those who are intimidated or simply not sold on the value of learning what’s traditionally been a software development tool. On the Code4Lib listserv, it was noted that the small number of signatories on the Antiharassment Policy might actually be due to its being hosted on GitHub. I struggle to sell people on my campus of the value of Google Docs with its collaborative editing features. So, as much as I’d like the Strategic Plan the college is producing to be on GitHub where everyone could submit pull requests and comment on commits, it’s not necessarily the best platform. It is important, however, not to think of it as limited purely to versioning code written by professional developers. GitHub has uses for amateurs and non-coders alike.

Footnotes

[1]^ GitHub Has Passed SourceForge, (June 2, 2011), ReadWrite.

[2]^ Previously-mentioned SourceForge also supports Git, as does Bitbucket.

[3]^ I think this would make an excellent band name, by the way.

Taking a trek with SCVNGR: Developing asynchronous, mobile orientations and instruction for campus

Embedding the library in campus-wide orientations, as well as developing standalone library orientations, is often part of outreach and first year experience work. Reaching all students can be a challenge, so finding opportunities for better engaging campus helps to promote the library and increase student awareness. Using a mobile app for orientations can provide many benefits such as increasing interactivity and offering an asynchronous option for students to learn about the library on their own time. We have been trying out SCVNGR at the University of Arizona (UA) Libraries and are finding it is a more fun and engaging way to deliver orientations and instruction to students.

Why use game design for library orientations and instruction?

Game-based learning can be a good match for orientations, just as it can be for instruction (I have explored this before with ACRL TechConnect previously, looking at badges). Rather than just presenting a large amount of information to students or having them fill out a paper-based scavenger hunt activity, using something like SCVNGR can get students interacting more with the library in a way that offers more engagement in real time and with feedback. However, simply adding a layer of points and badges or other game mechanics to a non-game situation doesn’t automatically make it fun and engaging for students. In fact, doing this ineffectively can cause more harm than good (Nicholson, 2012). Finding a way to use the game design to motivate participants beyond simply acquiring points tends to be the common goal in using game design in orientations and instruction. Thinking of the WIIFM (What’s In It For Me) principle from a students’ perspective can help, and in the game design we used at the University of Arizona with SCVNGR for a class orientation, we created activities based on common questions and concerns of students.

Why SCVNGR?
scvngr home screen

scvngr home screen

 

SCVNGR is a mobile app game for iPhone and Android where players can complete challenges in specific locations. Rather than getting clues and hints like in a traditional scavenger hunt, this game is more focused on activities within a location instead of finding the location. Although this takes some of the mystery away, it works very well for simply informing people about locations that are new to them and having them interact with the space.

Students need to physically be in the location for the app to work, where they use the location to search for “challenges” (single activities to complete) or “treks” (a series of single activities that make up the full experience for a location), and then complete the challenges or treks to earn points, badges, and recognition.

Some libraries have made their own mobile scavenger hunt activities without the aid of a paid app. For example, North Carolina State University uses the NCSU Libraries’ Mobile Scavenger Hunt, which is a combination of students recording responses in Evernote, real time interaction, and tracking by librarians.  One of the reasons we went with SCVNGR, however, is because this sort of mobile orientation requires a good amount of librarian time and is synchronous, whereas SCVNGR does not require as much face-to-face librarian time and allows for asynchronous student participation. Although we do use more synchronous instruction for some of our classes, we also wanted to have the option for asynchronous activities, and in particular for the large-scale orientations where many different groups will come in at many different times. Although SCVNGR is not free for us, the app is free to students. They offer 24/7 support and other academic institutions offer insight and ideas in a community for universities.

Other academic libraries have used SCVNGR for orientations and even library instruction. A few examples are:

 

How did the UA Libraries use SCVNGR?

Because a lot of instruction has moved online and there are so many students to reach, we are working on SCVNGR treks for both instruction and basic orientations at the University of Arizona (UA). We are in the process of setting up treks for large-scale campus orientations (New Student Orientation, UA Up Close for both parents and students, etc.) that take place during the summer, and we have tested SCVNGR  out on a smaller scale as a pilot for individual classes. There tends to be greater success and engagement if the Trek is tied to something, such as a class assignment or a required portion of an orientation session that must be completed. One concern for an app-based activity is that not all students will have smartphones. This was alleviated by putting students into groups ahead of time, ensuring that at least one person in the group did have a device compatible to use SCVNGR. However, we do lend technology at the UA Libraries, and so if a group was without a smartphone or tablet, they would be able to check one out from the library.

trek page for ais197b at ua libraries

trek page for ais197b at ua libraries

We first piloted a trek on an American Indian Studies student success course (AIS197b). This course for freshmen introduces students to services on campus that will be useful to them while they are at the UA. Last year, we presented a quick information session on library services, and then had the students complete a scavenger hunt for a class grade (participation points) with pencil and paper throughout the library. Although they seemed glad to be able to get out and move around, it didn’t seem particularly fun and engaging. On top of that, every time the students got stuck or had a question, they had to come back to the main floor to find librarians and get help.  In contrast, when students get an answer wrong in SCVNGR, feedback is programmed in to guide them to the correct information. And, because they don’t need clues to make it to the next step (they just go back and select the next challenge in the trek), they are able to continue without one mistake preventing them from moving on to the next activity. This semester, we first presented a brief instruction session (approximately 15-20 min) and then let students get started on SCVNGR.

You can see in the screenshot below how question design works, where you can select the location, how many points count toward the activity, type of activity (taking a photo, answering with text, or scanning a QR code), and then providing feedback. If a student answers a question incorrectly, as I mention above, they will receive feedback to help them in figuring out the correct answer. I really like that when students get answers right, they know instantly. This is positive reinforcement for them to continue.

scvngr answer feedback

scvngr answer feedback

The activities designed for students in this class were focused on photo and text-based challenges. We stayed away from QR codes because they can be finicky with some phones, and simply taking a picture of the QR code meets the challenge requirement for that option of activity. Our challenges included:

  • Meet the reference desk (above): Students meet desk staff and ask how they can get in touch for reference assistance; answers are by text and students type in which method they think they would use the most: email, chat, phone, or in person.
  • Prints for a day: Students find out about printing (a frequent question of new students), and text in how to pay for printing after finding the information at the Express Documents Center.
  • Playing favorites: Students wander around the library and find their favorite study spot. Taking a picture completes the challenge, and all images are collected in the Trek’s statistics.
  • Found in the stacks: After learning how to use the catalog (we provided a brief instruction session to this class before setting them loose), students search the catalog for books on a topic they are interested in, then locate the book on the shelf and take a picture. One student used this time to find books for another class and was really glad he got some practice.
  • A room of one’s own: The UA Libraries implemented online study room reservations as of a year ago. In order to introduce this new option to students, this challenge had them use their smartphones to go to the mobile reservation page and find out what the maximum amount of hours study rooms can be reserved for and text that in.

SCVNGR worked great with this class for simple tasks, such as meeting people at the reference desk, finding a book, or taking a picture of a favorite study spot, but for tasks that might require more critical thinking or more intricate work, this would not be the best platform to use in that level of instruction. SCVNGR’s assessment options are limited for students to respond to questions or complete an activity. Texting in detailed answers or engaging in tasks like searching a database would be much harder to record. Likewise, because more instruction that is tied to critical thinking is not so much location-based (evaluating a source or exploring copyright issues, for example), and so it would be hard to tie these tasks and acquisition of skill to an actual location-based activity to track. One instance of this was with the Found in the Stacks challenge; students were supposed to search for a book in the catalog and then locate it on the shelf, but there would be nothing stopping them from just finding a random book on the shelf and taking a picture of it to complete the challenge. SCVNGR provides a style guide to help in game design, and the overall understanding from this document is that simplicity is most effective for this platform.

Another feature that works well is being able to choose if the Trek is competitive or not, and also use “SmartRoute,” which is the ability to have challenges show up for participants based on distance and least-crowded areas. This is wonderful, particularly as students get sort of congested at certain points in a scavenger hunt: they all crowd around the same materials or locations simultaneously because they’re making the same progress through the activity. We chose to use SmartRoute for this class so they would be spread out during the game.

scvngr trek settings

scvngr trek settings

When trying to assess student effort and impact of the trek, you can look at stats and rankings. It’s possible to view specific student progress, all activity by all participants, and rankings organized by points.

scvngr statistics

scvngr statistics

Another feature is the ability to collect items submitted for challenges (particularly pictures). One of our challenges is for students to find their favorite study spot in the library and take a picture of it. This should be fun for them to think about and is fairly easy, and it helps us do some space assessment. It’s then possible to collect pictures like the following (student’s privacy protected via purple blob).

student images of ua main library via scvngr

student images of ua main library via scvngr

On the topic of privacy, students enter in their name to set up an account, but only their first name and first initial of their last name appear as their username. Although last names are then hidden, SCVNGR data is viewable by anyone who is within the geographical range to access the challenge: it is not closed to an institution. If students choose to take pictures of themselves, their identity may be revealed, but it is possible to maintain some privacy by not sharing images of specific individuals or sharing any personal information through text responses. On the flip side of  not wanting to associate individual students with their specific activities, it gets trickier when an instructor plans to award points for student participation. In that case, it’s possible to request reports from SCVNGR for instructors so they can see how much and which students participated. In a large class of over 100 students, looking at the data can be messier, particularly if students have the same first name and last initial. Because of this issue, SCVNGR might be better used for large-scale orientations where participation does not need to be tracked, and small classes where instructors would be easily able to know who is who in the data for activity.

Lessons learned

Both student and instructor feedback was very positive. Students seemed to be having fun, laughing, and were not getting stuck nearly as much as the previous year’s pencil-and-paper hunt. The instructor noted it seemed a lot more streamlined and engaging for the class. When students checked in with us at the end before heading out, they said they enjoyed the activity and although there were a couple of hiccups with the software and/or how we designed the trek, they said it was a good experience and they felt more comfortable with using the library.

Next time, I would be more careful about using text responses. I had gone down to our printing center to tell the current student worker what answers students in the class would be looking for so she could answer it for them, but they wound up speaking with someone else and getting different answers. Otherwise, the level of questions seemed appropriate for this class and it was a good way to pilot how SCVNGR works, if students might like it, and how long different types of questions take for bringing this to campus on a larger scale. I would also be cautious about using SCVNGR too heavily for instruction, since it doesn’t seem to have capabilities for more complex tasks or a great deal of critical thinking. It is more suited to basic instruction and getting students more comfortable in using the library.

Pros

  • Ability to reach many students and asynchronously
  • Anyone can complete challenges and treks; this is great for prospective students and families, community groups, and any programs doing outreach or partnerships outside of campus since a university login is not required.
  • Can be coordinate with campus treks if other units have accounts or a university-wide license is purchased.
  • WYSIWYG interface, no programming skills necessary
  • Order of challenges in a trek can be assigned staggered so not everyone is competing for the same resources at the same time.
  • Can collect useful data through users submitting photos and comments (for example, we can examine library space and student use by seeing where students’ favorite spots to study are).

Cons

  • SCVNGR is not free to use, an annual fee applies (in the $900-range for a library-only license, which is not institution-wide).
  • Privacy is a concern since anyone can see activity in a location; it’s not possible to close this to campus.
  • When completing a trek, users do not get automatic prompts to proceed to the next challenge; instead, they must go back to the home location screen and choose the next challenge (this can get a little confusing for students).
  • SCVNGR is more difficult to use with instruction, especially when looking to incorporate critical thinking and more complex activities
  • Instructors might have a harder time figuring out how to grade participation because treks are open to anyone; only students’ first name and last initial appear, so if either a large class completes a trek for an assignment or if an orientation trek for the public is used, a special report must be requested from SCVNGR that the library could send to the instructor for grading purposes.

 

Conclusion

SCVNGR is a good way to increase awareness and get students and other groups comfortable in using the library. One of the main benefits is that it’s asynchronous, so a great deal of library staff time is not required to get people interacting with services, collections, and space. Although this platform is not perfect for more in-depth instruction, it does work at the basic orientation level, and students and the instructor in the course we piloted it on had a good experience.

 

References

Nicholson, S. (2012). A user-centered theoretical framework for meaningful gamification. Paper Presented at Games+Learning+Society 8.0, Madison, WI. Retrieved from http://scottnicholson.com/pubs/meaningfulframework.pdf.

—-

About Our Guest Author: Nicole Pagowsky is an Instructional Services Librarian at the University of Arizona where she explores game-based learning, student retention, and UX. You can find her on Twitter, @pumpedlibrarian.

A Librarian’s Guide to OpenRefine

Academic librarians working in technical roles may rarely see stacks of books, but they doubtless see messy digital data on a daily basis. OpenRefine is an extremely useful tool for dealing with this data without sophisticated scripting skills and with a very low learning curve. Once you learn a few tricks with it, you may never need to force a student worker to copy and paste items onto Excel spreadsheets.

As this comparison by the creator of OpenRefine shows, the best use for the tool is to explore and transform data, and it allows you to make edits to many cells and rows at once while still seeing your data. This allows you to experiment and undo mistakes easily, which is a great advantage over databases or scripting where you can’t always see what’s happening or undo the typo you made. It’s also a lot faster than editing cell by cell like you would do with a spreadsheet.

Here’s an example of a project that I did in a spreadsheet and took hours, but then I redid in Google Refine and took a lot less time. One of the quickest things to do with OpenRefine is spot words or phrases that are almost the same, and possibly are the same thing. Recently I needed to turn a large export of data from the catalog into data that I could load into my institutional repository. There were only certain allowed values that could be used in the controlled vocabulary in the repository, so I had to modify the bibliographic data from the catalog (which was of course in more or less proper AACR2 style) to match the vocabularies available in the repository. The problem was that the data I had wasn’t consistent–there were multiple types of abbreviations, extra spaces, extra punctuation, and outright misspellings. An example is the History Department. I can look at “Department of History”, “Dep. of History”, “Dep of Hist.” and tell these are probably all referring to the same thing, but it’s difficult to predict those potential spellings. While I could deal with much of this with regular expressions in a text editor and find and replace in Excel, I kept running into additional problems that I couldn’t spot until I got an error. It took several attempts of loading the data until I cleared out all the errors.

In OpenRefine this is a much simpler task, since you can use it to find everything that probably is the same thing despite the slight differences in spelling, punctuation and spelling. So rather than trying to write a regular expression that accounts for all the differences between “Department of History”, “Dep. of History”, “Dep of Hist.”, you can find all the clusters of text that include those elements and change them all in one shot to “History”. I will have more detailed instructions on how to do this below.

Installation and Basics

OpenRefine was called, until last October, Google Refine, and while the content from the Google Refine page is being moved to the Open Refine page you should plan to look at both sites. Documentation and video tutorials refer interchangeably to Google Refine and OpenRefine. The official and current documentation is on the OpenRefine GitHub wiki. For specific questions you will probably want to use the OpenRefine Custom Search Engine, which brings together all the mix of documentation and tutorials on the web. OpenRefine is a web app that runs on your computer, so you don’t need an internet connection to run it. You can get the installation instructions on this page.

While you can jump in right away and get started playing around, it is well worth your time to watch the tutorial videos, which will cover the basic actions you need to take to start working with data. As I said, the learning curve is low, but not all of the commands will make sense until you see them in action. These videos will also give you an idea of what you might be able to do with a data set you have lying around. You may also want to browse the “recipes” on the OpenRefine site, as well search online for additional interesting things people have done. You will probably think of more ideas about what to try. The most important thing to know about OpenRefine is that you can undo anything, and go back to the beginning of the project before you messed up.

A basic understanding of the Google Refine Expression Language, or GREL will improve your ability to work with data. There isn’t a whole lot of detailed documentation, so you should feel free to experiment and see what happens when you try different functions. You will see from the tutorial videos the basics you need to know. Another essential tool is regular expressions. So much of the data you will be starting with is structured data (even if it’s not perfectly structured) that you will need to turn into something else. Regular expressions help you find patterns which you can use to break apart strings into something else. Spending a few minutes understanding regular expression syntax will save hours of inefficient find and replace. There are many tutorials–my go-to source is this one. The good news for librarians is that if you can construct a Dewey Decimal call number, you can construct a regular expression!

Some ideas for librarians

 

(A) Typos

Above I described how you would use OpenRefine to clean up messy and inconsistent catalog data. Here’s how to do it. Load in the data, and select “Text Facet” on the column in question. OpenRefine will show clusters of text that is similar and probably the same thing.

AcademicDept Text Facet

AcademicDept Text Facet

 

Click on Cluster to get a menu for working with multiple values. You can click on the “Merge” check box and then edit the text to whatever you need it to be. You can also edit each text cluster to be the correct text.

Cluster and Edit

Cluster and Edit

You can merge and re-cluster until you have fixed all the typos. Back on the first Text Facet, you can hover over any value to edit it. That way even if the automatic clustering misses some you can edit the errors, or change anything that is the same but you need to look different–for instance, change “Dept. of English” to just “English”.

(B) Bibliographies

The main thing that I have used OpenRefine for in my daily work is to change a bibliography in plain text into columns in a spreadsheet that I can run against an API. This was inspired by this article in the Code4Lib Journal: “Using XSLT and Google Scripts to Streamline Populating an Institutional Repository” by Stephen X. Flynn, Catalina Oyler, and Marsha Miles. I wanted to find a way to turn a text CV into something that would work with the SHERPA/RoMEO API, so that I could find out which past faculty publications could be posted in the institutional repository. Since CVs are lists of data presented in a structured format but with some inconsistencies, OpenRefine makes it very easy to present the data in a certain way as well as remove the inconsistencies, and then to extend the data with a web service. This is a very basic set of instructions for how to accomplish this.

The main thing to accomplish is to put the journal title in its own column. Here’s an example citation in APA format, in which I’ve colored all the “separator” punctuation in red:

Heller, M. (2011). A Review of “Strategic Planning for Social Media in Libraries”. Journal of Electronic Resources Librarianship, 24 (4), 339-240)

From the drop-down menu at the top of the column click on “Split into several columns…” from the “Edit Column” menu. You will get a menu like the one below. This example finds the opening parenthesis and removes that in creating a new column. The author’s name is its own column, and the rest of the text is in another column.

Spit into columns

 

The rest of the column works the same way–find the next text, punctuation, or spacing that indicates a separation. You can then rename the column to be something that makes sense. In the end, you will end up with something like this:

Split columns

When you have the journal titles separate, you may want to cluster the text and make sure that the journals have consistent titles or anything else to clean up the titles. Now you are a ready to build on this data with fetching data from a web service. The third video tutorial posted above will explain the basic idea, and this tutorial is also helpful. Use the pull-down menu at the top of the journal column to select “Edit column” and then “Add column by fetching URLs…”. You will get a box that will help you construct the right URL. You need to format your URL in the way required by SHERPA/RoMEO, and will need a free API key. For the purposes of this example, you can use 'http://www.sherpa.ac.uk/romeo/api29.php?ak=[YOUR API KEY HERE]&qtype=starts&jtitle=' + escape(value,'url'). Note that it will give you a preview to see if the URL is formatted in the way you expect. Give your column a name, and set the Throttle delay, which will keep the service from rejecting too many requests in a short time. I found 1000 worked fine.

refine7

After this runs, you will get a new column with the XML returned by SHERPA/RoMEO. You can use this to pull out anything you need, but for this example I want to get pre-archiving and post-archiving policies, as well as the conditions. A quick way to to this is to use the Googe Refine Expression Language parseHtml function. To use this, click on “Add column based on this column” from the “Edit Column” menu, and you will get a menu to fill in an expression.

refine91

In this example I use the code value.parseHtml().select("prearchiving")[0].htmlText(), which selects just the text from within the prearchving element. Conditions are a little different, since there are multiple conditions for each journal. In that case, you would use the following syntax (after join you can put whatever separator you want): forEach(value.parseHtml().select("condition"),v,v.htmlText()).join(". ")"

So in the end, you will end up with a neatly structured spreadsheet from your original CV with all the bibliographic information in its own column and the publisher conditions listed. You can imagine the possibilities for additional APIs to use–for instance, the WorldCat API could help you determine which faculty published books the library owns.

Once you find a set of actions that gets your desired result, you can save them for the future or to share with others. Click on Undo/Redo and then the Extract option. You will get a description of the actions you took, plus those actions represented in JSON.

refine13

Unselect the checkboxes next to any mistakes you made, and then copy and paste the text somewhere you can find it again. I have the full JSON for the example above in a Gist here. Make sure that if you save your JSON publicly you remove your personal API key! When you want to run the same recipe in the future, click on the Undo/Redo tab and then choose Apply. It will run through the steps for you. Note that if you have a mistake in your data you won’t catch it until it’s all finished, so make sure that you check the formatting of the data before running this script.

Learning More and Giving Back

Hopefully this quick tutorial got you excited about OpenRefine and thinking about what you can do. I encourage you to read through the list of External Resources to get additional ideas, some of which are library related. There is lots more to learn and lots of recipes you can create to share with the library community.

Have you used OpenRefine? Share how you’ve used it, and post your recipes.

 

My #HuntLibrary: Using Instagram to Crowdsource the Story of a New Library

[Updated to reflect open-source availability. May 13th, 2013]
 
Introduction

North Carolina State University opened the James B. Hunt Jr. Library in January of 2013, creating a heart for our Centennial Campus that defines the research library of the future. My #HuntLibrary was created as a platform to foster student and community engagement with the new building via social media imagery and to preserve and archive these images as part of the record of the Hunt Library launch. My #HuntLibrary is a Ruby on Rails application that harvests images from Instagram and provides several browsing views, mechanisms for sharing, tools for users to select their favorite images, an administrative interface for moderating images, and a system for harvesting images for inclusion in the NCSU Libraries digital archives. Built according to the principles of “responsive design,” My #HuntLibrary is usable on mobile devices, tablets, desktops, e-boards, and the massive MicroTiles displays in the Hunt Library.

In the three months since the launch of My #HuntLibrary (coinciding with the opening of the Hunt Library building), we received nearly 1700 images from over 600 different users, over 6800 “like” votes, and over 53,000 “battle” votes. This post will detail some of the risks involved with the project, the technical challenges we faced, how student engagement strengthened the project, and the potential benefits of giving students and community members a voice in the documentation of the Hunt Library.

The code that drives My #HuntLibrary has been extracted into an open-source Rails Engine called “lentil“ that is available on GitHub.

My #HuntLibrary front page

My #HuntLibrary

Planning for Risk

Most projects carry some level of risk and My #HuntLibrary was no different. It was difficult to predict the level of engagement we would be able to achieve with various application features. The timeline for development was short, carried a firm deadline (due to the need to launch alongside the new library), and included work with several technologies that were new to the development team. Additionally, the application relied on a third-party API that could change at any time. In order to mitigate project risks, we structured the project around goals with short and long (and more speculative) timelines that would each individually justify the project effort.

  1. Utilize social media to increase engagement with a new library

Social media engagement with students was a linchpin of our opening strategy. Before the Hunt Library came online, NC State students already had a high degree of ownership over existing Libraries spaces and we sought to extend that to our new library. My #HuntLibrary could contribute to that sense of ownership by providing a platform for users of the new library to document and share their experience, learn about the experiences of their peers, and to collectively curate the images using voting tools. Furthermore, My #HuntLibrary is an opportunity for staff to learn about important and unexpected uses of the building during the critical post-launch period.

  1. Provide a mechanism for students to contribute to digital collections

We felt that the Hunt Library opening could be an opportunity for students to add their voices to the documentation of campus history that is preserved in our extensive digital collections. My #HuntLibrary could also allow us to leverage social technologies to diversify the perspectives reflected in our archival collections. This is our first major social media preservation effort and we hope that our project, along with others (such as GWU Libraries’ Social Feed Manager, or the State of North Carolina’s Social Media Archive), may begin to contribute possible answers to several questions related to social media archives, including:

  • Can we utilize existing streams of social media content to integrate additional student perspectives in our documentation of the history of their university? Does this enhance our special collections?

  • Can an invitation to participate in core library practices, such as the development of special collections, serve as an effective engagement strategy?

  • What is the research value of social media collections? How does this value vary based on media, users, and harvesting methods?
  1. Explore new technologies

The developers involved with the project created a support structure that included pair programming, code reviews, and tutorial sessions that mitigated many of the technical risks, including the integration of new software frameworks and libraries and the coordination of work on a tight schedule. This project also provided an opportunity to learn more about the design of interfaces for the large-scale displays described later in this article.

Student Engagement

Although we knew it would be possible to utilize the Instagram API to collect and display photographs about the Hunt Library, we needed to have a reasonable expectation that people (and students in particular) would participate in the project. This question hinged on the likelihood that a person would tag a photograph of the new library with a hashtag that would allow us to capture it. The Libraries had previous experience trying to engage students through Twitter around the question “What are you doing in the library right now?” We looked back on that project’s limitations to inform our engagement strategy. The chosen hashtag (#whyncsulib) was unique, but in order to answer our question, students had to be aware of the hashtag and willing to deviate somewhat from their normal social media communication patterns. However, we found that it was already common for students to use the tag #DHHill to visually depict their activities in our D. H. Hill Library on Instagram. 

Example #DHHill Instagram images

Example #DHHill Instagram images

Assuming that students would continue this tagging behavior at the new library, we chose the hashtag “#HuntLibrary” in hopes that it would see widespread adoption regardless of the level of awareness of our project.

As we began to design the application and develop a social media plan, another milestone in the project came with the opportunity to present the idea to actual students. The NCSU Libraries Student Advisory Board is charged with providing guidance and input on the programs and services the Libraries offers. This regular open meeting (fueled by free food) allowed us to collect feedback on specific questions about the project (e.g. do students want images to “Battle?”). The feedback from this presentation varied widely, from useful (e.g. roughly two-thirds of the students present had Instagram installed on their phones and yes, they want to battle) to unsanctionable (“If you want cute photographs you should let us bring cats into the library”). However, the general reaction from the students was that it seemed like a good idea, and we continued work with increased confidence.

The Student Advisory Board meeting also led to another breakthrough: our Director’s commitment of funds to award an iPad Mini to the photographer of the best image. Prior to the Advisory Board meeting, our only participation incentive was an assurance that the best photographs would be ingested into the University’s permanent digital archives. While this is a thrilling idea to a roomful of librarians, we were uncertain that students would have the same reaction. Perhaps unsurprisingly, when our Director asked the gathered students if they would take more pictures if there were an iPad Mini at stake, the students were unanimous in their response. Although we later learned in usability tests that students reacted very positively to the idea of contributing to their University’s story, the tablet prize gave the project a focal point, and the contest became the cornerstone of our student engagement strategy.

Display Technology

The NCSU Libraries’ vision is to be NC State’s competitive advantage. This vision is often operationalized by putting cutting-edge technology in the hands of our students and faculty. For the Hunt Library, we made a strategic investment in large-scale, architecturally integrated visualization spaces such as ultra-high definition video walls and virtual environment studios. These visualization spaces serve as large canvases to reflect the research and activities of our campus in new interactive ways. The Hunt Library is, in short, a storytelling building.

We anticipated that My #HuntLibrary would produce a visually compelling record of the new library, and so we chose to display the photographic activity in one of the library’s most accessible visualization spaces: the iPearl Immersion Theater. The Theater features a curved video wall that is twenty-one feet wide and seven feet tall. The wall uses Christie MicroTiles, a modular display system based on LED and DLP technologies that gives the wall an effective resolution of 6824 pixels by 2240 pixels. MicroTiles feature high color saturation and a wide color spectrum, making them ideal for Instagram photographs of the colorful library. A key part of the technology behind the MicroTiles is a Christie Vista Spyder. The Spyder is a hardware-based video processor that allows for 12-bit scaling. This upsampling capability was important for our application, as it allowed small (612 pixels square) images to be enlarged to two-foot images in the Theater with very few noticeable compression artifacts. 

Viewing My #HuntLibrary in the Immersion Theater. Photo by Instagram user crmelvin14.

Viewing My #HuntLibrary in the Immersion Theater. Photo by Instagram user crmelvin14. 

As a public, physical space, the iPearl Immersion Theater allowed us to create embodied and shared user experiences that were fundamentally different from the web and mobile views of My #HuntLibrary. The Theater is a semi-open space near the entrance to the library, adjacent to an expansive reading lounge. The video wall installation had an attractive presence that invited passers-by inside to examine the images. Once inside the Theater, the content could be appreciated more fully by moving around in the space. Standing close to the wall enabled the user to see more detail about a particular photograph while moving farther away gave an impressionistic sense of the library’s spaces. While dwell times for the installation were sometimes low because users often dropped in for a moment before heading to their intended destination, seating in the Theater allowed for a more leisurely viewing experience as new photographs rotated into the display. Small groups of people gathered in the Theater to discuss the merits of their favorite photographs, point out their own photographs to their friends, and engage in conversations with strangers about the images.

Responsive Web Design

With the large MicroTiles displays in the Hunt Library we now face the challenge of designing for very small (mobile device) and very large displays and many sizes in between (tablets, laptops, desktops, e-boards). The growing popularity of responsive web design techniques have helped developers and designers meet the challenge of building applications that work well on a wide range of device screen sizes. Responsive web design generally means using a combination of CSS3 media queries, fluid grids, and flexible images to progressively enhance a single web design for optimal display and use on a wide range of screen sizes and devices (Marcotte 2010). Most of the discussion of responsive design centers around building for devices ranging from phone-sized to desktop-sized displays. However, there is no technical reason why responsive design cannot work for even wider ranges of display sizes.

Our final design for My #HuntLibrary includes two different responsive designs, one of which supports mouse and touch interactions and display sizes ranging from phones to desktops, and another for non-interactive public display of the photographs on displays ranging from large eboards to more than twenty-foot wide Christie MicroTiles arrays. Our decision to build two different responsive designs for the smaller and larger sets of displays has more to do with the context in which these displays are used (personal, interactive devices versus public, non-interactive displays) than any technical limitations imposed by responsive web design techniques. In our case, the design of My #HuntLibrary for phones, tablets, and laptop and desktop computers has features to support interactive browsing, sharing photos, and a photo competition “Battle View” for people to compare sets of images and pick their favorites. These features would not translate well to the Libraries’ larger public displays, which range in size from a large eboard to huge Christie MicroTiles video walls, and which are, for now, mostly non-interactive. It made sense to develop a different view optimized to support a non-interactive display of the My #HuntLibrary photos. For the eboard-sized and larger public displays we developed a grid of images that are periodically replaced by new images, a few at a time.

Mobile view of My #HuntLibrary.

Mobile view of My #HuntLibrary.

My #HuntLibrary on Christie MicroTiles in the Immersion Theater.

My #HuntLibrary on Christie MicroTiles in the Immersion Theater.

Collecting Social Media

Although the initial development push was heavily focused on the core data management and display infrastructure, the longer-term goal of content preservation (for the sake of historical documentation rather than personal archives) influenced most aspects of the project. In particular, we have attempted and are continuing to address three major preservation-related themes: harvesting, crowdsourced curation, and legal clearance.

For short-term use of the images, we harvest only the metadata, leaving the images on the Instagram servers. Clearly, for long-term preservation we would need to collect the images themselves. This harvesting is complicated by the necessity to declare an arbitrary “break” from the source materials, at which point any changes to the metadata (or removal of the images) would not be reflected by our system. We are currently developing a milestone-based harvesting schedule that takes into account both the length of time the image is in the system and the submission of a donor agreement.

While we are currently planning on collecting all “#huntlibrary” images, we are very interested in the potential to allow our users to influence the selection process for certain parts of our archival collection. In order to test and support this goal, we developed two voting tools: individual image “like” voting and this-or-that “battle” voting. Our hope (which early usage metrics seem to support) is that we could use the data from these tools to select images for preservation, or at least to promote a subset of preserved images, that reflect the interests of our community. In addition to improving our selection processes, this may be an opportunity to promote archival selection as a student engagement tool by promoting opportunities for students to influence the historical record of their own experiences.

Image battle interface.

Image battle interface.

Finally, we worked with a lawyer and copyright specialist at our library to develop a donor agreement that was short and clear enough to be submitted as a comment on an image. Instagram users retain rights to their own images and thus the ability to grant the limited rights that we are requesting. Furthermore, the use of the Instagram comment system will allow us to automate this process, provided that we are responsive to takedown requests.

Conclusion

In the three months since the launch of My #HuntLibrary (coinciding with the opening of the Hunt Library building), we received nearly 1700 images from over 600 different users, over 6800 “like” votes, and over 53,000 “battle” votes. In addition to these measures of user contributions (of either images or vote-based reviews), My #HuntLibrary recorded 135,908 pageviews from 10,421 unique visitors (according to Google Analytics) during this period. Furthermore, the project was regularly cited by students, staff, and institutional partners on social media channels, and was featured (with an emphasis on historical documentation) during the Hunt Library Dedication events.

The evaluation of the archival components of this application will take place on a longer timeline. We are currently extending the long-term content harvesting features in order to support these activities in a more automated way. We have received several indications of the value of pursuing image preservation features, including surprisingly enthusiastic reactions to questions about the preservation of images from students taking part in a My #HuntLibrary user study. As a particularly encouraging example, when an undergraduate student contributor to My #HuntLibrary was asked “How would you feel if one of your Instagram photos were selected by the library to be kept as a permanent record of what students did in 2013?” they responded, “I would be so excited. For me, I think it would be better than winning an iPad.”

About our guest authors:

Jason Casden is the Lead Librarian for the Digital Services Development group at the North Carolina State University Libraries, where he helps to develop and implement scalable digital library applications. He is the project manager and a software developer for “My #HuntLibrary,” and has served as a project or technical lead for projects including the Suma physical space and service usage assessment toolkit, the WolfWalk geo-enhanced mobile historical guide, and Library Course Tools.

Mike Nutt is a Fellow at NCSU Libraries, where he leads a strategic initiative called “Networked Library: Marketing the 21st Century Library.” He is the product lead for My #HuntLibrary, and also facilitates content strategies for the large video walls in NC State’s new Hunt Library. He founded the University of North Carolina at Chapel Hill student group Carolina Digital Story Lab and was a research assistant at the UNC-CH Carolina Digital Library and Archives.

Cory Lown is Digital Technologies Development Librarian at North Carolina State University Libraries where he works collaboratively to design and develop applications to improve end-user resource discovery and use of library services. He has contributed as a developer and/or interface designer to a number of projects, including My #HuntLibrary, WolfWalk, QuickSearch, and the latest version of the library’s mobile website.

Bret Davidson is currently a Digital Technologies Development Librarian at the North Carolina State University Libraries. Previously, Bret worked as an NCSU Libraries Fellow on visualization tools and resources to support the new James B. Hunt, Jr. Library. Prior to becoming a librarian, Bret was a music educator in the public schools of Pennsylvania and Illinois, as well as a performing musician with the River City Brass Band in Pittsburgh, PA.

Adventures with Raspberry Pi: A Librarian’s Introduction

Raspberry Pi
A Raspberry Pi computer

A Raspberry Pi computer (image credit: Wikimedia Commons)

Raspberry Pi, a $35 fully-functional desktop computer about the size of a credit card, is currently enjoying a high level of buzz, popularity, and media exposure. Librarians are, of course, also getting in on the action. I have been working with a Raspberry Pi to act as a low-power web server for a project delivering media-rich web content for museum exhibits in places without access to the internet. I’ve found working with the little Linux machine to be a lot of fun and I’m very excited about doing more with Raspberry Pi. However, as with many things librarians get excited about, it can be difficult to see through the enthusiasm to the core of the issue. Is the appeal of these cute little computers universal or niche? Do I need a Raspberry Pi in order to offer core services to my patrons? In other words: do we all need to run out and buy a Raspberry Pi, are they of interest to a certain niche of librarians, or are Raspberry Pi just the next library technology fad and soon to go the way of offering reference service in Second Life? 1 To help us answer this question, I’d like to take a moment to explain what a Raspberry Pi device is, speculate who will be interested in one, provide examples of some library projects that use Raspberry Pi, and offer a shopping list for those who want to get started.

What is Raspberry Pi

From the FAQ at raspberrypi.org:

The Raspberry Pi is a credit-card sized computer that plugs into your TV and a keyboard. It’s a capable little PC which can be used for many of the things that your desktop PC does, like spreadsheets, word-processing and games. It also plays high-definition video. We want to see it being used by kids all over the world to learn programming.

This description from Raspberry Pi covers the basics. (H2G2 has a more detailed history of the project.) A Raspberry Pi (also known as a Raspi, or an RPi) is a small and inexpensive computer designed to extend technology education to young students who don’t currently have access to more expensive traditional computers. The Raspberry Pi project counteracts a movement away from general-purpose computing devices and toward internet appliances and mobile devices. The Pew Internet and American Life Project notes that: “smartphone owners, young adults, minorities, those with no college experience, and those with lower household income levels are more likely than other groups to say that their phone is their main source of internet access.2 Access to the internet today is pervasive and less expensive than ever before, but also more likely to come from an appliance or mobile device and without the programming tools and command-line control that were standard for previous generations of computer users. This means a smaller percentage of computer users are likely to pick up these skills on their own. Raspberry Pi offers a very-low cost solution to this lack of access to programming and command-line tools.

In addition to the stated goal of the Raspberry Pi organization, a lot of adults who already have access to technology are also very excited about the possibilities enabled by the small and cheap computing platform. What sets the Raspberry Pi apart from other computers is its combination of small size and low price. While you can do very similar things with a re-purposed or salvaged computer system running Linux, the Raspberry Pi is much smaller and uses less power. Similarly, you can do some of these things with a similarly-sized smart-phone, but those are much more expensive than a Raspberry Pi. For the technology hobbyist and amateur mad scientist, the Raspberry Pi seems to hit a sweet spot on both physical size and cost of entry.

The heart of the Raspberry Pi (or RPi) Model B is a Broadcom system-on-a-chip that includes a 700mhz ARM processor, 512mb RAM, USB and Ethernet controllers, and a graphics processor capable of HD resolutions. According to the FAQ its real-world performance is on par with a first generation Xbox or a 300mhz Pentium II computer. In my personal experience it is powerful enough for typical web browsing tasks or to host a WordPress based web site. Raspberry Pi devices also come with a GPIO (general purpose input and output) port, which enables an RPi to control electronic circuits. This makes the RPi a very flexible tool, but it doesn’t quite provide the full functionality of an Arduino or similar micro-controller3.

Out of the box, a Raspberry Pi will require some extra equipment to get up and running. There is a shopping list included at the bottom of the article that contains known working parts. If you keep boxes of spare parts and accessories around, just in case, you likely already have some of these parts. In addition to a $35 Raspberry Pi model b computer, you will definitely need an SD card with at least 4gb storage and a 5 volt 1 amp (minimum) micro-usb power supply. An extra cell phone charger looks like the right part, but probably does not put out the minimum amperage to run an RPi, but a tablet charger likely will. You can read the fine print on the ‘wall wart’ part of the charger for its amperage rating.  If you want to use your Raspberry Pi as a workstation4, you’ll also need an HDMI cable, a digital monitor and a USB keyboard and mouse. Any USB keyboard or mouse will work, but the monitor will need to have an HDMI input. 5 Additionally, you may also want to use a USB wifi adapter to connect to wireless networks and since the Raspberry Pi has only two USB ports, you may also want a powered USB hub so you can connect more peripherals. The Raspberry Pi unit ships as a bare board, so you may want to keep your RPi in a case to protect it from rough handling.

Who is the Raspberry Pi for?

Now that we’ve covered what kind of kit is needed to get started, we can ask: are you the kind of librarian who is likely to be interested in a Raspberry Pi? I’ve noticed some “enthusiasm fatigue” out there, or librarians who are weary of overhyped tools that don’t provide the promised revolution. I love my Raspberry Pi units, but I don’t think they have universal appeal, so I’ve made a little quiz that may help you decide whether you are ready to order one today or pass on the fad, for now.

  1. Are you excited to work in a Linux operating system?
  2. Are you willing to use trial and error analysis to discover just right configuration for your needs?
  3. Do you enjoy the challenge of solving a living problem more than the security of a well-polished system?

If the answer to all three of these questions is an enthusiastic YES, then you are just the kind of librarian who will love experimenting with a Raspberry Pi. If your enthusiasm is more tempered or if you answered no to one or more of the questions, then it is not likely that a Raspberry Pi will meet your immediate needs. RPi are projects not products. They make great prototypes or test-boxes, but they aren’t really a turn-key solution to any existing large-scale library problems. Not every library or librarian needs a Raspberry Pi, but I think a significant number of geeky and DIY librarians will be left asking: “Where have you been all my life?”

If you are a librarian looking to learn Linux, programming, or server administration and you’d rather do this on a cheap dedicated machine than on your work machine, Raspberry Pi is going to make your day. If you want to learn how to install and configure something like WordPress or Drupal and you don’t have a web server to practice on (and local AMP tools aren’t what you are looking for) a Raspberry Pi is an ideal tool to develop that part of your professional skill set. If you want to learn code, learn robotics, or build DIY projects then you’ll love Raspberry Pi. RPi are great for learning more about computers, networks, and coding. They are very educational, but at the end of the day they fall a bit more on the hobby end of the spectrum then on the professional product end.

Raspberry Pi Projects for Librarians

So, if you’ve taken the quiz and are still interested in getting started with Raspberry Pi, there are a few good starting points. If you prefer printed books O’Reilly Media’s Getting Started with Raspberry Pi is fantastic. On the web. I’ve found the Raspberry Pi wiki at elinux.org to be an indispensable resource and their list of tutorials is worth a special mention. Adafruit (an electronics kit vendor and education provider) also has some very good tutorials and project guides. For library specific projects, I have three suggestions, but there are many directions you may want to go with your Rasberry Pi. I’m currently working to set mine up as a web server for local content, so museums can offer rich interpretive media about their exhibits without having to supply free broadband to the public. When this is finished, I’m going to build projects two and three.

  • Project One: Get your RPi set up.

This is the out-of-the-box experience and will take you through the set up of your hardware and software. RaspberryPi.org has a basic getting started guide, Adafruit has a more detailed walkthrough, and there are some good YouTube tutorials as well. In this project you’ll download the operating system for your Raspberry Pi, transfer it to your SD card, and boot up your machine, and perform the first time setup. Once you’re device is up and running you can spend some time familiarizing yourself with it and getting comfortable with the operating system.

  • Project One-Point-Five: Play with your Raspberry Pi

Once your credit card sized computer is up and functional, kick the tires. Check out the graphical interface, use the command line, and try running it headless. Take baby steps if baby steps are what is fun and comfortable, or run headlong into a project that is big and crazy; the idea here is to have fun, get used to the environment, and learn enough to ask useful questions about what to do next. This is a good time to check out the Adafruit series of tutorials or elinux.org’s tutorial list.

  • Project Two: Build an Information Kiosk to Display Local Mass Transit Information

http://blog.bn.ee/2013/01/11/building-a-real-time-transit-information-kiosk-with-raspberry-pi/

I found this on the elinux list of tutorials and I think it is great for libraries, provided they are in an area served by NextBus or a similar service. The tutorial walks users through the process of building a dedicated information kiosk for transit information. The steps are clear and documented with photographs and code examples. Beginning users may want to refer to other references, such as the O’Reilly Book or a Linux Tutorial to fill in some gaps.  I suspect the tricky bit will be finding a source for real-time GPS telemetry from the local transit service, but this is a great project for those who have worked through basic projects and are ready to build something practical for their library.

  • Project Three: Build a Dedicated OPAC Terminal.

While dedicated OPAC terminals may no longer be the cutting edge of library technology, our patrons still need to find books on the shelves. Library Journal’s Digital Shift blog and John Lolis from the White Plains public library describe a project that uses the Raspbian OS to power a catalog-only public terminal. The concept is straight-forward and working prototypes have been completed, but as of yet I do not see a step-by-step set of instructions for the beginner or novice. As a follow up to this post, I will document the build process for TechConnect. The gist of this project is to set up a kiosk-type browser, or a browser that only does a set task or visits a limited range of sites, on the Raspberry Pi. Eli Neiberger has raised some good questions on Twitter about the suitability of RPi hardware for rough-and-tumble public abuse use, but this is the sort of issue testing may resolve. If librarians can crowd-source a durable low-cost OPAC kiosk using Lolis’ original design, we’ll have done something significant.

Raspberry Pi Shopping List

As mentioned above, you may have many of these items already. If not, I’ve purchased and tested the following accessories for a couple of Raspberry Pi projects.

Basic Kit: (parts sourced through Amazon for ease of institutional purchase. Other sources may be preferable or less expensive.)

Accessories:

Raspberry Pi kits (Some vendors have put together full kits with a wide range of parts and accessories. These kits include breadboards and parts for arduino-type projects.)

Notes

  1. Good and necessary work is still being done in Second Life, but it has become a niche service, not a revolution in the way we provide library services.
  2. http://www.pewinternet.org/~/media//Files/Reports/2012/PIP_Digital_differences_041312.pdf
  3. Check out this forum thread for a basic distinction between Arduino and Raspberry Pi.
  4. The alternative is to run it ‘headless’ over your network using SSH.
  5. Monitors with DVI input will work with a small and cheap HDMI to DVI adaptor. Analog monitors–the ones with blue VGA connectors–will work if you purchase an HDMI to VGA converter-adapter which start around $20.

Learn to Love the Command Line

“Then the interface-makers went to work on their GUIs, and introduced a new semiotic layer between people and machines. People who use such systems have abdicated the responsibility, and surrendered the power, of sending bits directly to the chip that’s doing the arithmetic, and handed that responsibility and power over to the OS.”
—Neal Stephenson, In the Beginning was the Command Line

Many of us here at Tech Connect are fans of the command line. We’ve written posts on configuring a local server, renaming files en masse, & using the Git version control system that are full of command line incantations, some mysterious and some magical. No doubt; the command line is intimidating. I’m sure most computer users, when they see it, think “Didn’t we move beyond this already? Can’t someone just write an app for that?” Up until about a year ago, I felt that way, but I’ve come to love the command line like Big Brother. And I’m here to convince you that you should love the command line, too.

Scripting

So why use a command line when you can probably accomplish almost everything in a graphical user interface (GUI)? Consider the most repetitive, dreary task you do on a daily basis. It might be copying text back-and-forth between applications over and over. You might periodically back up several different folders by copying them to an external drive. We all have repetitive workflows in dire need of automation. Sure, you could write some macros, but macros can be brittle, breaking when the slightest change is introduced. They’re often tricky to write correctly, so tricky that the blinking square at the start of the command prompt is starting to look promising.

One of the first joys of the command line is that everything you do can be scripted. Any set of steps, no matter how lengthy and intricate, can be compiled into a script which completes the process in a matter of seconds. Copy a dozen folders in disparate locations to a backup drive? No problem. Optimize a web app for deployment? A script can minify your JavaScript and CSS, concatenate files, optimize images, test your code for bugs, and even push it out to a remote server.

Available Software

It may seem odd, but moving to the Neanderthal command line can actually increase the amount of software available to you. There are lots of programs that don’t come with a graphical interface, either because they’re lightweight tools that don’t require a GUI or because their author knew that they’d be used almost exclusively by people comfortable with the command line. There are also many software packages that, while they have GUIs available, are more powerful on the command line. Git is a good example: there are numerous graphical interfaces and most are quite good. But learning the commands opens up a wealth of options, configurations, and customizations that just do not exist graphically.

Tying It All Together

There are many wonderful GUIs that allow you to do complex things: generate visualizations, debug code, edit videos. But most applications are in their own separate silos and work you do in one app cannot be easily connected to any other. On the command line, output from one command can easily be “piped” into another, letting you create long chains of commands. For instance, let’s say I want to create a text document with all the filenames in a particular directory in it. With a file manager GUI, this is a royal pain: I can see a list of files but I can only copy their names one by one. If I click-and-drag to select all the names, the GUI thinks I want to select the files themselves and won’t let me paste the text of their names.

On the command line, I simply write the output of the ls command to a file: [1]

ls -a > filenames.txt

Now filenames.txt will list all the files and directories in the current folder. The > writes the output of ls -a (list all files) and it’s one of a few different methods that redirects output. Now what if I want only filenames that contain a number in them?

ls -a | grep [0-9] > filenames-with-numbers.txt

I already have a list of all the file names, so I “pipe” the output of that command using the vertical bar | to grep, which in turn outputs only lines that have a number zero through nine in them, finally writing the text to filenames-with-numbers.txt. This is a contrived example but it illustrates something incredibly powerful about the command line: the text output of any command can easily be used as input for another command. While it may look like a lot of punctuated gibberish, it’s actually pretty intuitive to work with. Anyone who has tried copying GUI-formatted text into an environment with different formatting should be envious.

REPLs

So you want to play around with a programming language. You’ve written a file named “hello-world.py” or “hello-world.rb” or “hello-world.php” but you have no idea how to get the code to actually run. Command line to the rescue! If you have the programming language installed and in your path, you can run python hello-world.py or ruby hello-world.rb or php hello-world.php and the output of your script will print right in your terminal. But wait, there’s more!

Many modern scripting languages come with a REPL built-in, which stands for “Read-Eval-Print loop.” In English, this means you write text that’s instantly evaluated as code in the programing language. For instance, below I enter the Python REPL and do some simple math:

$ python
Python 2.7.2
Type "help", "copyright", "credits" or "license" for more information.
>>> 1 + 2
3
>>> 54 * 34
1836
>>> 64 % 3
1
>>> exit()

The $ represents my command prompt, so I simply ran the command python which entered the REPL, printing out some basic information like the version number of the language I’m using. Inside the REPL, I did some addition, multiplication, and a modulus. The exit() function call at the end exited the REPL and put me back in my command prompt. There’s really no better way to try out a programming language than with a REPL. [2] The REPL commands for Ruby and PHP are irb and php -a respectively.

Stumbling Blocks

Everyone who starts out working on the command line will run into a bunch of common hangups. It’s frustrating, but it doesn’t need to be. It’s really like learning common user interface conventions: how would you know an anachronistic floppy disk means “save this file” if you hadn’t already clicked it a million times? Below is my attempt to alleviate some of the most common quirks of the command line.

Where Is It?

Before we get too far, it would probably be good to know how to get to a command prompt in the first place. You use a terminal emulator to open a command prompt in a window on your operating system. On a Mac, the terminal emulator is the aptly-named Terminal.app, which is located in Applications\Utilities. On Ubuntu Linux, there’s also a Terminal application which you can find using the Dash or with the handy Ctrl+Alt+T shortcut. [3] KDE Linux distributions use Konsole as the default command line application instead. Finally, Windows has a couple terminal emulators and, sadly, they are incompatible with *NIX shells like those found on Mac and Linux machines. Windows PowerShell can be found in Start > All Programs > Accessories or by searching after clicking the Start button. You can open PowerShell on Windows 8 by searching as well.

Escaping Spaces

Spaces are a meaningful character on the command line: they separate one command from the next. So when you leave spaces in filenames or text strings, commands tend to return errors. You need to escape spaces in one of two ways: precede a space with a backslash, “\”, which tells the command line to interpret the following character literally (i.e. not as a directive), or by wrapping the string with spaces in quotes. So mv File Name.txt New Name.txt will be greeted with the usage information for the mv command because the program assumes you don’t understand how to use it, while mv "Sad Cats.txt" "LOL Cats.txt" will successfully rename “Sad Cats.txt” to “LOL Cats.txt”.

Luckily, you won’t need to type quotes or slashes very often due to the miracle that is tab completion. If you start typing a command or file name, you can hit the tab key and your shell will try to fill in the rest. If there are two names that begin identically then you’ll have to provide enough to disambiguate between the two: if “This is my file.txt” and “This is my second file.txt” are both in the same folder, you’ll have to type at least “This is my ” and then, depending on whether your next letter is an F or an S, the shell can tab complete whatever follows to the appropriate name.

Copy & Paste

Command line interfaces were invented before common GUI applications and their keyboard shortcuts like Ctrl+V and Ctrl+C. Those shortcuts were already assigned different actions on the command line and so they typically do not do what you’d expect, since for backwards compatibility they need to stick to their original meanings. So does that mean you have to type every long URL or string of text into the terminal? No! You can still copy-paste but it works a bit different on most terminals. On Ubuntu Linux, Ctrl+Shift+C or V will perform copy and paste respectively, while I’ve found that right-clicking in Windows PowerShell will paste. Mac OS X’s Terminal.app can actually use the conventional ⌘+C or ⌘+V because they don’t conflict with Ctrl.

Moving Around the Line

Too many times I’ve typed out a long command, perhaps one with a URL or other pasted string of text in it, only to spot a typo dozens of characters back. On the command line, you cannot simply click to move your cursor to a different position, you have to press the back arrow dozens of times to go back and correct a mistake.

Or so I thought. On Mac’s Terminal.app, option-click will move the cursor. Unfortunately, most other terminal applications don’t provide any mouse navigation. Luckily, there’s a series of keyboard shortcuts that work in many popular shells:

  • Ctrl+A jumps to the beginning of the line
  • Ctrl+E jumps to the end of the line
  • Ctrl+U deletes to beginning of line
  • Ctrl+K deletes to end of line
  • Ctrl+W deletes the word next to cursor

Those shortcuts can save you a lot time and are often quicker than using the mouse. Typing Ctrl+W to delete a lengthy URL is much more convenient than shift-clicking with the mouse to select it all, then hitting the delete key.

Make It Stop!!!

One of the first tips for learning the command line is to “read the friendly manual.” You can run the man command (short for manual) and pass it any other command to learn more about its usage, e.g. man cp will give you the manual of the copy command. However, the manual is often presented in a special format; it doesn’t just print the manual, it gives you a scrollable interface that replaces the command prompt. But how the heck do you exit the manual to get back to the command line? I’ll admit, when I was first learning, I used to simply close the terminal and re-open because I had no idea how to get out of the all-too-friendly manual.

But that’s unnecessary: pressing the letter q will quit the manual, while battering away on the ESC key or typing “exit please dear lord let me exit” won’t do a thing. q exits a few other commands, too.

Another good trick is Ctrl+C which causes a keyboard interrupt, canceling whatever process is running. I use this all the time because I frequently run a test server from the command line, or a SASS command that watches for file changes, or do something really stupid that will execute forever. Ctrl+C is always the exit strategy.

The PATH

So you installed the “awesomesauce” software, but every time you run awesomesauce in your command prompt you get a message like “command not found.” What gives?

All shells come with a PATH variable that specifies where the shell looks for executable programs. You can’t simply type the name of a script or executable anywhere on your system and expect the shell to know about it. Instead, you have to tell the command line where to look. Let’s say I just installed awesomesauce to ~/bin/awesomesauce where ~ stands for my user’s home folder (on Mac OS X this will be /Users/MyUsername, for example—you can run echo ~ to see where your home folder is). Here’s how I get it working:

$ # command isn't in my path yet - this is a comment by the way
$ awesomesauce
bash: awesomesauce: command not found
$ export PATH=$PATH:~/bin
$ awesomesauce
You executed the Awesome Sauce command! Congratulations!

The export command lets me modify my PATH variable, appending the ~/bin directory to the list of other places in the PATH. Now that the shell is looking in ~/bin, it sees the awesomesauce command and lets me run it from the command line.

It quickly gets tedious appending directories to your PATH every time you want to use something, so it’s wise to use a startup script that runs every time you open a new Terminal. In BASH, the common shell that comes with Mac OS X and is the default in most Linux distributions, you can do this by adding the appropriate export commands to a file named .bash_profile in your home file. The commands in .bash_profile are executed every time a new Terminal window is opened.

Use the Google, my Friend

There are certainly other hangups not covered above, but a tremendous amount of good information exists on the web. People have been using command line interfaces for quite a while now and there is documentation for almost everything. There are great question-and-answer forums, like StackExchange’s Superuser section, with tons of content on the command line and writing shell scripts. I’ve basically self-taught myself the command line using Google and a few select sources. In fact, the man command alone is one of the shining advantages of the command line: image if you could just type text like man spot healing brush in PhotoShop to figure out how all those crazy tools work?

Learning the command line is a challenge but it’s well worth the investment. Once you have a few basics under your belt, it opens up vast possibilities and can greatly increase your productivity. Still, I wouldn’t say that everyone needs to know the command line. Not everyone needs to learn coding either, but everyone can benefit from it. With a little practice, some trial and error, and many, many Google searches, you’ll be well on your way to commandeering like a boss.

Further Reading

wiki.bash-hackers.org – a great wiki for learning more about the common BASH shell

ss64.com – command line reference

Using the Terminal – Ubuntu’s guide to the command line

In the Beginning was the Command Line – Neal Stephenson’s treatise about the command line, GUIs, Windows, Linux, & BeOS. It actually isn’t that much about the command line but it’s an interesting read.

Footnotes

[1]^ The commands listed in this post will not work on Windows, but that doesn’t mean you can’t do the same things: the names and syntax of the commands are just different. It’s worth noting that Windows users can use the Cygwin project to get a shell experience comparable to *NIX systems.

[2]^ If you’re still too scared to try the command line after this post, the great repl.it site provides REPLs for over a dozen different programming languages.

[3]^ The default terminal on Ubuntu, and many other Linuxes, is technically “GNOME Terminal” but it may show up as just Terminal in search results. While these are the default terminals, most systems have more advanced alternatives that offer a few niceties like arranging terminal windows in a grid, paste history, and configurable keyboard shortcuts. On Mac, iTerm2 is an excellent choice. Lifehacker recommends Terminator for Linux, and it is also available for Windows and Mac. Wikipedia has an unnecessarily long list of terminal emulators for the truly insane.

Playing with JavaScript and JQuery – the Ebook link HTML string generator and the EZproxy bookmarklet generator

In this post, I will describe two cases in which I solved a practical problem with a little bit of JavaScript and JQuery. Check them out first here before reading the rest of the post which will explain how the code works.

  1. Library ebook link HTML string generator
  2. EZproxy bookmarklet generator – Longer version (with EZproxy Suffix)
  3. EZproxy bookmarklet generator – Shorter version (with EZproxy Prefix)

Source: http://www.flickr.com/photos/albaum/448573998/

1. Library ebook link HTML string generator

If you are managing a library website, you will be using a lot of hyperlinks for library resources. Sometimes you can distribute some of the repetitive tasks to student workers, but they are usually not familiar with HTML. I had a situation in which I needed to add a number of links for library e-books for my library’s Course E-book LibGuide page, when I was swamped with many other projects at the same time. So I wondered if I could somehow still use the library’s student assistant’s help by creating an providing a simple tool, so that the student only needs to input the link title and url and get me the result as HTML. This way, I can still delegate some work when I am swamped with other projects that require my attention. (N.B. Needless to say, this doesn’t mean that what I did was the best way to use the student assistance for this type of work. I didn’t want them to edit the page directly because this page had tabs tabs and the student using the WYSWYG editor might inadvertently remove part of the tabbed box code.)

The following code exactly does that.

This HTML form takes an e-book title and the link to the book as input and spits out a hyperlink as a list item as a result. For example, if you fill in the title field with ‘Bradley’s Neurology in Clinical Practice’ and the link field with its url: http://ezproxy.fiu.edu/login?url=http://www.mdconsult.com/public/book/view?title=Daroff:+Bradley’s+Neurology+in+Clinical+Practice, then the result would be shown in the text area : <li><a href=”http://ezproxy.fiu.edu/login?url=http://www.mdconsult.com/public/book/view?title=Daroff:+Bradley’s+Neurology+in+Clinical+Practice”> Bradley’s Neurology in Clinical Practice</a></li>  I also wanted the library student assistant to be able to do this for many e-books at once and just send me the whole set of HTML snippets that cover all ebooks. So after running the form once, if one fills out the title and the link field with another e-book information, the result would be added to the end of the previous HTML string and be displayed in the text area. The result would be like this: <li><a href=”http://ezproxy.fiu.edu/login?url=http://www.mdconsult.com/public/book/view?title=Daroff:+Bradley’s+Neurology+in+Clinical+Practice”> Bradley’s Neurology in Clinical Practice</a></li><li><a href=”http://ezproxy.fiu.edu/login?url=http://www.accessmedicine.com/resourceTOC.aspx?resourceID=64″>Cardiovascular Physiology</a></li>. Since the code is in the text area, the student can also edit if there was any error when s/he was filling out the form after clicking the button ‘Send to Text Area’.

Now, let’s take a look at what is going on behind the scene. This is the entire html file. The Javascript/JQuery code that is generating the html string in the text area is from line 22-32.

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
</head>
<body>
	<p>
		This page creates the html-friendly string for a link with a title and a url. 
		<ul>
		<li>Fill out the form below and click the button. </li>
		<li>If the link is messy, clean up first by using the <a href="http://meyerweb.com/eric/tools/dencoder/">URL decoder</a>.</li>
		<li>Copy and paste the result inside the text area after you are done.</li>
		</ul>	
	</p>
	<p>
		Title: <input type="text" id="title1" size="100"/><br/>
		Link: <input type="text" id="link1" size="100"/><br/>
		<button id="b1">Send to Text Area</button>
	</p>
	<p id="result1"></p>
	<textarea rows="20" cols="80"></textarea>

	<script type="text/javascript">
	$(document).ready(function(){	
	  $("#b1").click(function(){
	  //  alert('<a href="'+$("#link").val()+'">' + $("#title").val()+"</a>");
	    $('#result1').text('<li><a href="'+$("#link1").val()+'">' + $("#title1").val()+"</a></li>");
	    var res1='<li><a href="'+$("#link1").val()+'">' + $("#title1").val()+"</a></li>";
	    $('textarea').val($('textarea').val()+res1);
	 //   $('textarea').text(res1);
	  });
	}); // doc ready
	</script>

</body>
</html>

Since I am using JQuery I am starting with the obligatory $(document).ready in line 2. In line 3,  I am giving a callback function that will be executed when the #b1 – the button with the id of b1 in line 17 above- is clicked.  Line 4 is commented out. I used this initially to test if I am getting the right string out of the input from the title and the link field using the JS alert. Line 5 is filling the p tag with the id of result 1 in line 19 above with the thus-created string. The string is also saved in variable res1 in line 7. Then it is attached to the content of the textarea field in line 8. Line 9 is commented out. If you use line 9 instead of line 8, any existing content in the textarea will be removed and only the new string created from the title and the link field will show up in the text area.

<script type="text/javascript">
	$(document).ready(function(){	
	  $("#b1").click(function(){
	  //  alert('<a href="'+$("#link").val()+'">' + $("#title").val()+"</a>");
	    $('#result1').text('<li><a href="'+$("#link1").val()+'">' + $("#title1").val()+"</a></li>");
	    var res1='<li><a href="'+$("#link1").val()+'">' + $("#title1").val()+"</a></li>";
	    $('textarea').val($('textarea').val()+res1);
	 //   $('textarea').text(res1);
	  });
	}); // doc ready
</script>

You do not have to know a lot about scripting to solve a simple task like this!

2. EZproxy bookmarklet generator – Longer version

My second example is a bookmarklet that reloads the current page through a specific EZproxy system.

If you think that this bookmarklet reinvents the wheel since the LibX toolbar already does this, you are correct. And also if you are a librarian working with e-resources, you already know to add the EZproxy suffix at the end of the domain name of the url when a patron asks if a certain article on a web page is available through the library or not. But I found that no matter how many times I explain this trick of adding the EZproxy suffix to patrons, the trick doesn’t seem to stick in their busy minds. Also, many doctors and medical students, who are the primary patrons of my library, work at the computers in hospitals and they do not have the necessary privilege to install a toolbar on those computers. But they can create a bookmark.

Similarly, many students asked me why there is no LibX toolbar for their mobile devices unlike in their school laptops. (In the medical school where I work, all students are required to purchase a school-designated laptop; this laptop is pre-configured with all the necessary programs including the library LibX toolbar.) Well, mobile devices are not exactly computers and so the browser toolbar doesn’t work. But students want an alternative and they can create a bookmark on their tablets and smartphones. So the proxy bookmarklet is still a worthwhile tool for the mobile device users.

This is where the bookmarklet is: http://htmlpreview.github.com/?https://github.com/bohyunkim/examples/blob/master/bkmklt.html. To test, drag the link on the top that says Full-Text from FIU Library to your bookmark toolbar. Then go to http://jama.jamanetwork.com/Issue.aspx?journalid=67&issueID=4452&direction=P. Click the new bookmarklet you got on your toolbar. The page will reload and you will be asked to log in through the Florida International University EZproxy system. When you are authenticated, you will be seeing the page proxied: http://jama.jamanetwork.com.ezproxy.fiu.edu/Issue.aspx?journalid=67&issueID=4452&direction=P.

You will be surprised to see how simple the bookmarklet is (and there is even a shorter version than this which I will show in the next section). It is a JavaScript function wrapped inside a hyperlink. Lines 2-5 each takes the domain name, the path name, and any search string after the url path from the current window location object. So in the case of http://jama.jamanetwork.com.ezproxy.fiu.edu/Issue.aspx?journalid=67&issueID=4452&direction=P, location.host is http://jama.jamanetwork.com and location.pathname is Issue.aspx . The rest of the url ?journalid=67&issueID=4452&direction=P – is location.search. In line 4, I am putting my institution’s ezproxy suffix between these two, and in line 5, I am asking the browser load this new link.

<a href="javascript:(function(){
	var host=location.host;
	var path=location.pathname;
	var srch=location.search;
	var newlink='http://'+host+'.ezproxy.fiu.edu'+path+srch;
	window.open(newlink);
})();">Full-Text from FIU Library</a>

Now let’s take a look at the whole form. I created this form for those who want to create a ready-made bookmarklet recipe. All they need is their institution’s EZproxy suffix and whatever name they want to give to the bookmarklet. Once one fills out those two fields and click ‘Customize’ button, one will get the full HTML page code with the bookmarklet as a link in it.

<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
</head>
<body>
<h1>EZproxy Bookmarklet</h1>	
<p><ul><li>
	<a href="javascript:(function(){
		var host=location.host;
		var path=location.pathname;
                var srch=location.search;
                var newlink='http://'+host+'.ezproxy.fiu.edu'+path+srch;
		window.open(newlink);
	})();">Full-Text from FIU Library</a> 
	(Drag the link to the bookmark toolbar!)
</li></ul></p>
<p>This is a bookmarket that will reroute a current page through FIU EZproxy.
	<br/>
If you have the LibX toolbark installed, you do not need this bookmarklet. Simply select 'Reload Page via XYZ EZproxy' on the menu that appears when you right click.
	<br/>
Created by Bohyun Kim on March, 2013. 	
</p>
<h2>How to Test</h2>
<ul>
	<li>Drag the link above to the bookmark toolbar of your web browser.</li>
	<li>Click the bookmark when you are on a webpage that has an academic article.</li>
	<li>It will ask you to log in through the FIU EZproxy.</li>
	<li>Once you are authenticated and the library has a subscription to the journal, you will will able to get the full-text article on the page.</li>
	<li>Look at the url and see if it contains .ezproxy.fiu.edu. If it does, the bookmarklet is working.</li>
</ul>	

<h2>Make One for Your Library</h2>
	<p>
		Bookmark title: <input type="text" id="title1" size="40" placeholder="e.g. Full-Text ABC Library"/>
		<em>e.g. Full-text ABC Library</em>
		<br/>
		Library EZproxy Suffix: <input type="text" id="link1" size="31" placeholder="e.g. ezproxy.abc.edu"/>
		<em>e.g. ezproxy.abc.edu
		<br/>
		<button id="b1">Customize</button></em>
	</p>
	<p><strong>Copy the following into a text editor and save it as an html file.</strong></p>
	<ul>
		<li>Open the file in a web browser and drag your link to the bookmark toolbar.</li>
	</ul>	
	<p id="result1" style="color:#F7704F;">**Customized code will appear here.**</p>
	<p><strong>If you want to make any changes to the code:</strong></p>
	<textarea rows="10" cols="60"></textarea>

	<script type="text/javascript">
	$(document).ready(function(){	
	  $("#b1").click(function(){
		var pre="&lt;html&gt; &lt;head&gt; &lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js&quot;&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;a href=&quot;javascript:(function(){ var hst=location.host; var path=location.pathname; var srch=location.search; var newlink='http://'+hst";
		var link1=$('#link1').val();
		var post="'+path+srch; window.open(newlink); })();">";
	  	var title=$("#title1").val();
	  	var end="&lt;/a&gt; &lt;/body&gt; &lt;/html&gt;";
	  	var final=$('<div />').html(pre+"+'."+link1+post+title+end).text()
	  	$('#result1').text(final);
	    $('textarea').val(final);
	  });
	}); // doc ready
	</script>

</body>
</html>

That ‘customize’ part is done here with several lines of JQuery. You will notice that the process is quite similar to what I did in my first example. In lines 4-8, I am just stitching together a bunch of text strings to spit out the whole code in the text area eventually when the ‘Customize’ button is clicked. All special characters used in HTML tags such as ‘<’ and ‘>’ have been changed to html enities. In line 9, I am taking the entire string saved in the variable end –I hope you name your variables a little more carefully than I do!–  and adding it to an empty div so that the string would be set as the inner HTML property of that div. And then I retrieve it using the .text() method. The result is the HTML code with the html entities decoded.

<script type="text/javascript">
	$(document).ready(function(){	
	  $("#b1").click(function(){
		var pre="&lt;html&gt; &lt;head&gt; &lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js&quot;&gt;&lt;/script&gt; &lt;/head&gt; &lt;body&gt; &lt;a href=&quot;javascript:(function(){ var hst=location.host; alert(hst); var path=location.pathname; var srch=location.search; var newlink='http://'+hst";
		var link1=$('#link1').val();
		var post="'+path+srch; window.open(newlink); })();">";
	  	var title=$("#title1").val();
	  	var end="&lt;/a&gt; &lt;/body&gt; &lt;/html&gt;";
	  	var final=$('<div />').html(pre+"+'."+link1+post+title+end).text()
	  	$('#result1').text(final);
	    $('textarea').val(final);
	  });
	}); // doc ready
</script>

Not too bad, right? I hope these examples show how just a few or several lines of code can be used to solve your practical problems at work. Coding is there for you to automate time-consuming and/or repetitive tasks.

3. EZproxy bookmarklet generator – Shorter version

There is a simpler way to create a EZproxy bookmarklet than the one sketched above. If you simply add EZproxy prefix in front of the entire url of the page where a user is is, you achieve the same result. In this case, you do not have to break the url with host, pathname, search string, etc.

<a href="javascript:void(location.href=%22http://ezproxy.fiu.edu/login?url=%22+location.href)">Full-Text from FIU Library</a>

Here are the code for this much simpler EZproxy bookmarklet and the bookmarklet generator. If you know the prefix of you library’s EZproxy prefix, you can make one for your library.

So there are many ways to get the same thing done. Some are more elegant and some are less so. Usually a shorter one is a more elegant solution. The lesson is that you usually get to the most elegant solution after coming up with many less elegant solutions first.

Do you have a problem that can be solved by creating several lines of code? Have you ever solved a practical problem using a bit of code? Share your experience in the comments!

 

Making Your Website Accessible Part 3: Content WCAG Compliance

Welcome to part 3 of the web accessibility series. While part 1 explained a bit about web accessibility and the web consortium accessibility guidelines (WCAG) and part 2 covered implementing WCAG on the development side, part 3 will cover the content side of things.

The main goal is that you walk away with a set of guidelines you can give to staff. I’ll start with the easier stuff that apply to all staff that have access to editing content, and then I’ll move on to more complicated content, namely media and forms, where the guidelines may be for technical staff either for content creation or for evaluating add-ons/plugins.

Headers

Use headings 1-6 to structure information so people using assistive technologies can navigate web pages easier (2.4.6). If your page were displayed with only headers or with headers and content indented, would it make sense? Will your headers be in the right place? Many screen readers and tools use an “Outline View”, which shows only the headings of a page.

Header 1 is the Title of the Webpage
Header 2 is a Subtopic of the Webpage
Header 3 is a Specific Sub-topic of Header 2 (and 1)
Another Header 2 would be a Subtopic of Header 1
(but separate from the  first Header 2)

Example:

<h1>E-Resources in Engineering</h1> = title of your page.
  <h2>Standards and Codes</h2> = topic 1
    <h3>International Standards Organization</h3> = 1st subtopic of topic 1
    <h3>Canadian Standards Association</h3> = 2nd subtopic of h2 topic 1
  <h2>Journal Databases</h2> = topic 2
    <h3>Compendex</h3> = subtopic of topic 2

Enter your HTML or the URL of your page into HTML5 Outliner to see an outline view.

Links

The text for every link should be descriptive (2.4.4) and unique (within a single page). Imagine there was no other text around it (except the title of the page). Would you understand what that link is for? Many assistive technologies have a “links only” option for viewing.

While many CMS provide the option to add additional text to a link through the title attribute (and is described as a sufficient technique, H33), the title attribute is generally not read by screen readers 1 as reading the title attribute on links (and images) is off by default. 2

Text in a Foreign Language

While each page should already be marked with a ‘default’ language (3.1.1), chunks of text (e.g. quotes, titles) in another language should be marked (3.1.2) with the ‘lang’ attribute and the appropriate language code, which can be applied to any HTML element. 3

Tables

Only use tables for information and data that should be presented in a tabular format. For example, a calendar, a list of contact information, or data sets should be presented in a table (1.3.1). Tables should not be used for layout, such as presenting content in columns.

If you need to use a table, then the information must be presented in a way that is accessible to users with disabilities and allows the table information to still be understood by the user even if they can’t see the table’s layout.

Elements

<table> : This element defines an HTML table
<tr> : This element defines a table row
<th> : This element defines a table header and should have the appropriate scope
<td> : This element defines a table cell
<caption> : This element identifies the table and acts as a title for the table. A caption is shown to all.

Example using Code for a Simple Table (Technique H63)

<table>
  <caption>Overdue Fines for Library Materials On Loan</caption>
  <tr>
    <th scope="col">Type of Item</th>
    <th scope="col">Amount per Day</th>
  </tr>
  <tr>
    <td>Books</td>
    <td>$0.50</td>
  </tr>
  <tr>
    <td>DVDs</td>
    <td>$1.00</td>
  </tr>
</table>

For examples of more complex tables, take a look at Technique H43.

Images
  • Alternate Text

When you include image elements on your website, you also need to include alternate or alt text, which allows you to include descriptive information about the image. While the text is not visible to most users, assistive technologies will read the alternate text as a description of the image, so write concisely, while still providing an accurate description of the image.

However, if your image has been included for purely decorative purposes, leave the alternate text empty. Assistive technology will ignore the image completely.

For example:

<img src="/6th-floorplan.jpg" alt="floor plan of the library's 6th floor">

If decorative only:

<img src="/example.jpg" alt="">
  • Title for Images

The title field allows you to provide additional information about an image in addition to the alternate text (meaning the title should not repeat alternate text). The title will also typically appear if users hover over an image with a title. However, as already noted, the title is typically not seen or read, so the use of title is discouraged 4.

  • Use Text Whenever Possible

Basically, don’t use an image of text instead of just text – use CSS instead (1.4.5). The one exception is for logos.

The logo of this website is an image, but all other text you see in this screenshot is just text

The logo of this website is an image, but all other text you see in this screenshot is just text

  • Meaning through Text

In a similar vein, understanding information and instructions should not be dependent on any sensory characteristics, such as sound, colour, or shape (1.3.3, 1.4.1). Think about it as: your message should be understood in text-only mode.

Audio/Video, Animations & Interactions
  • Autoplay

In general, audio and visual content should not play automatically. Instead, users should be able to hit a play button when they are ready for the content. Audio that autoplays for more than 3 seconds must have a pause/stop control or independent volume control (1.4.2).

  • Alternatives to Media

All non-text content, including audio and visual materials should have an alternate (1.1.1), typically a text transcript and/or descriptive audio (1.2.1, 1.2.3). At the AA level, WCAG requires audio descriptions for all videos as well (1.2.5), but the Ontario legislation (AODA) excludes it.

Example of Audio Description in a Movie

Much like images, if the audio/video is actually an alternate to text, such as in a tutorial where an explanation is already fully explained in text form, then no alternate is required.

  • Captions

All audio/video should have captions (aka subtitles) again unless the actual audio/video is an alternative to text (1.2.2). At the AA level, WCAG requires captions for live (streaming) audio/video as well (1.2.4), but this is the one other exception to the AODA.

  • Timing

Timing issues are particularly important in media and interactive elements, although it applies to any session based activity, such as bookings and forms. The basic idea is that anything that is on a timer can be extended and in some cases, users have to be warned (2.2.1). The exceptions are when it’s in real time (e.g. auction) or it’s essential (e.g. timed quiz).

Toronto Public Library gives this session time out warning to users

Toronto Public Library gives this session time out warning to users

  • Moving, Blinking, & Flashing

While this applies to websites in general, particularly for interactive elements or animations, the simplified version is that anything that starts automatically should have an accessible mechanism to pause, stop, or hide it (2.2.2). Additionally, nothing on the website should flash more than 3 times within 1 second so as not to cause seizures (2.3.1).

WARNING: Epilepsy inducing website(please don't ever do anything like this, ever)

WARNING: Epilepsy inducing website
(please don’t ever do anything like this, ever)

  • Keyboard Accessible

Again, this applies to the website as a whole, but particularly with more interactive elements, everything on a website should have the ability to be used through a keyboard (2.1.1).

One of the major issues with web based media is that they tend to live in a Flash-based container, which is not usually accessible. (This may shortly prove to be less of a problem with accessible controls in Flash videos by default built into Flash CS6 5.) YouTube videos are a prime example.

One alternative is to provide a link to an accessible player. For YouTube videos, you can create a link that will load a video (or playlist) into an online accessible player, such as Easy YouTube Player or the Accessible Interface to YouTube.

The other common method is to wrap the Flash object with accessible controls (see Keyboard Accessible YouTube Controls for example). However, wrapping an embedded video may remove existing functionality, such as full screen or volume control.

If you host your own videos, consider having accessible controls load for all your videos, such as using the JW Player Controls.

I also emphasize that you should be careful to never have a keyboard trap (2.1.2) though this is uncommon these days. See the following section for more on keyboard accessibility.

Forms

Keyboard accessibility along with many guidelines talked about here may apply to any similar element in a website, but the rest of the guidelines are covered here as they are commonly related or encountered with form elements.

  • Tab Order

Not surprisingly, users should be tabbing through fields in the meaningful order, which is not always the same as the default browser order (2.4.3).

annotated screenshot of an incorrect tab order on a form

Default order based on the code, which is obviously confusing to a user.

To fix the (above) problem, you can use tab index attribute.

For simplicity, I’ve left out some coding such as the form attributes.

<form>
  <label for="realname">name: <input id="realname" tabindex=1>
  <label for="comments">comments
  <textarea id="comments" cols=25 rows=5 tabindex=4></textarea>
  <label for="email">email: <input id="email" tabindex=2>
  <label for="dep">department: <select id="dep" tabindex=3>
  <option value="">...</select>
</form>
  • On Focus & Input Behaviour

Whenever an element can take input or interaction from the user, the current focus should be visible (2.4.7). The most basic example is the border/shadow effect when your cursor is in a text box, which is already built into the latest webkit browsers. (Some of the other browsers do show a minimal effect, but nothing that would pass the colour contract guidelines.)

screenshot of default field focus styling in Chrome and Safari

Source: http://monstertut.com/2012/04/remove-outline-input-forms-chrome-onfocus/

Since the default behaviour only covers the webkit browser, some simple CSS will do the trick.6

input:focus, textarea:focus, select:focus {
  border: 2px solid #8AADE1;
  box-shadow: 0 0 3px #8AADE1; /* not supported pre-IE9, but border still applies */
  outline: medium none;
}

Putting focus on or entering something into an element should also not change the context (3.2.1, 3.2.2). Finally, submission should be manual, not automatic (though I’ve never encountered an automatic one).

  • Avoiding and Correcting Mistakes

Appropriate labels (and possibly instructions) should always go along with user input (3.3.2). Form elements in particular should generally each have a label element attached (though not used for buttons 7), such as in the basic code example above.

Any errors in input should always be identified and described (3.3.1), with corrections suggested whenever possible (3.3.3). For business transactions, particularly related financial or legal transactions, all data should be given to the user to be reviewed first (3.3.4).

With HTML5, marking required elements is now simpler than ever with the required attribute, such as:

<input type="text" name="name" required>

The browser will automatically identify whether the field was left blank and inform the user.

screenshot of popup when field required in chrome, firefox, and opera

Similarly, there are now more input types you can use for browser-based form validation, such as the email input type:

<input type="email" id="user_email">
Captcha

Do not use recaptcha. It irks me to no ends that recaptcha claims it is accessible, because they provide an audio alternative. While that’s true, next time you encounter one, try listening to it.

The alternative is to use a captcha that is more accessible. The wikipedia article on captcha can give you some ideas and example. Personally, I like the simple questions, such as ‘If you write 5 followed directly by 2, what number did you write?’

HTML5 Accessibility Support

Unfortunately, accessibility support for HTML5 is only partially there. Even basic elements, such as header and footer, are not supported across browsers. Based on various sources that I have read, for assistive technology purposes, your website should be accessible through the latest IE and Firefox on Windows, and Safari on OSX. Check out the HTML5 Accessibility website to see which HTML5 elements and attributes have accessibility support in the various browsers.

In the mean time, while in part 2, I mentioned that WAI-ARIA should only be used for custom interfaces, since not all browsers support all the new HTML5 elements and attributes, it has been suggested to use ARIA roles during this transitional phase. If you find something you’re using isn’t supported in the recommended browsers, check out Using WAI-ARIA in HTML, which talks about which ARIA role you should use.

Conclusion

This is the last of the series. I’ve made sure to cover all the guidelines, and while I haven’t specifically covered scripting, there’s almost no difference. Flash, Silverlight, and PDF are fairly different things, so I point you to the WCAG guidelines and other resources (see the next section).

Awareness of web accessibility has increased, but we can do more, a lot more, and there is no better place to start than with our own institution’s website. While web technologies are forging ahead and making it easier for people to interact with the web, adaptive or assistive technologies are frequently playing catch up, so we need to be aware of what works for everyone and what doesn’t. Make the web friendlier, for everyone.

Resources & More Information

If you want more information and resources, check out:

Notes

Revisiting PeerJ

A few months ago as part of a discussion on open peer review, I described the early stages of planning for a new type of journal, called PeerJ. Last month on February 12 PeerJ launched with its first 30 articles. By last week, the journal had published 53 articles. There are a number of remarkable attributes of the journal so far, so in this post I want to look at what PeerJ is actually doing, and some lessons that academic libraries can take away–particularly for those who are getting into publishing.

What PeerJ is Doing

On the opening day blog post (since there are no editorials or issues in PeerJ, communication from the editors has to be done via blog post 1), the PeerJ team outlined their mission under four headings: to make their content open and help to make that standard practice, to practice constant innovation, to “serve academia”, and to make this happen at minimal cost to researchers and no cost to the public. The list of advisory board and academic editors is impressive–it is global and diverse, and includes some big names and Nobel laureates. To someone judging the quality of the work likely to be published, this is a good indication. The members of PeerJ range in disciplines, with the majority in Molecular Biology. To submit and/or publish work requires a fee, but there is a free plan that allows one pre-print to be posted on the forthcoming PeerJ PrePrints.

PeerJ’s publication methods are based on PLoS ONE, which publishes articles based on subjective scientific and methodological soundness rather with no emphasis placed on subjective measures of novelty or interest (see more on this). Like all peer-reviewed journals, articles are sent to an academic editor in the field, who then sends the article to peer reviewers. Everything is kept confidential until the article actually is published, but authors are free to talk about their work in other venues like blogs.

Look and Feel
PeerJ on an iPhone size screen

PeerJ on an iPhone size screen

There are several striking dissimilarities between PeerJ and standard academic journals. The home page of the journal emphasizes striking visuals and is responsive to devices, so the large image scales to a small screen for easy reading. The “timeline” display emphasizes new and interesting content. 2 The code they used to make this all happen is available openly on the PeerJ Github account. The design of the page reflects best practices for non-profit web design, as described by the non-profit social media guide Nonprofit Tech 2.0. The page tells a story, makes it easy to get updates, works on all devices, and integrates social media. The design of the page has changed iteratively even in the first month to reflect the realities of what was actually being published and how people were accessing it. 3 PDFs of articles were designed to be readable on screens, especially tablets, so rather than trying to fit as much text as possible on one page as many PDFs are designed, they have single columns with left margins, fewer words per line, and references hyperlinked in the text. 4

How Open Peer Review Works

One of the most notable features of PeerJ is open peer review. This is not mandatory, but approximately half the reviewers and authors have chosen to participate. 5 This article is an example of open peer review in practice. You can read the original article, the (in this case anonymous) reviewer’s comments, the editors comments and the author’s rebuttal letter. Anyone who has submitted an article to a peer reviewed journal before will recognize this structure, but if you have not, this might be an exciting glimpse of something you have never seen before. As a non-scientist, I personally find this more useful as a didactic tool to show the peer review process in action, but I can imagine how helpful it would be to see this process for articles about areas of library science in which I am knowledgeable.

With only 53 articles and in existence for such a short time, it is difficult to measure what impact open peer review has on articles, or to generalize about which authors and reviewers choose an open process. So far, however, PeerJ reports that several authors have been very positive about their experience publishing with the journal. The speed of review is very fast, and reviewers have been constructive and kind in their language. One author goes into more detail in his original post, “One of the reviewers even signed his real name. Now, I’m not totally sure why they were so nice to me. They were obvious experts in the system that I studied …. But they were nice, which was refreshing and encouraging.” He also points out that the exciting thing about PeerJ for him is that all it requires are projects that were technically well-executed and carefully described, so that this encourages publication of negative or unexpected results, thus avoiding the file drawer effect.6

This last point is perhaps the most important to note. We often talk of peer-reviewed articles as being particularly significant and “high-impact.” But in the case of PeerJ, the impact is not necessarily due to the results of the research or the type of research, but that it was well done. One great example of this is the article “Significant Changes in the Skin Microbiome Mediated by the Sport of Roller Derby”. 7 This was a study about the transfer of bacteria during roller derby matches, and the study was able to prove its hypothesis that contact sports are a good environment in which to study movements of bacteria among people. The (very humorous) review history indicates that the reviewers were positive about the article, and felt that it had promise for setting a research paradigm. (Incidentally, one of the reviewers remained anonymous , since he/she felt that this could “[free] junior researchers to openly and honestly critique works by senior researchers in their field,” and signed the letter “Diligent but human postdoc reviewer”.) This article was published the beginning of March, and already has 2,307 unique visits to the page, and has been shared widely on social media. We can assume that one of the motivations for sharing this article was the potential for roller derby jokes or similar, but will this ultimately make the article’s long term impact stronger? This will be something to watch.

What Can Academic Libraries Learn?

A recent article In the Library With the Lead Pipe discussed the open ethos in two library publications, In the Library With the Lead Pipe and Code4Lib Journal. 8 This article concluded that more LIS publications need to open the peer review process, though the publications mentioned are not peer reviewed in the traditional sense. There are very few, if any, open peer reviewed publications in the nature of PeerJ outside of the sciences. Could libraries or library-related publications match this process? Would they want to?

I think we can learn a few things from PeerJ. First, the rapid publication cycle means that more work is getting published more quickly. This is partly because they have so many reviewers and so any one reviewer isn’t overburdened–and due to their membership model, it is in the best financial interests of potential future authors to be current reviewers. As In the Library With the Lead Pipe points out that a central academic library journal, College & Research Libraries, is now open access and early content is available as a pre-print, the pre-prints reflect content that will be published in some cases well over a year from now. A year is a long time to wait, particularly for work that looks at current technology. Information Technology in Libraries (ITAL), the LITA journal is also open access and provides pre-prints as well–but this page appears to be out of date.

Another thing we can learn is making reading easier and more convenient while still maintaining a professional appearance and clean visuals. Blogs like ACRL Tech Connect and In the Library with the Lead Pipe deliver quality content fairly quickly, but look like blogs. Journals like the Journal of Librarianship and Scholarly Communication have a faster turnaround time for review and publication (though still could take several months), but even this online journal is geared for a print world. Viewing the article requires downloading a PDF with text presented in two columns–hardly the ideal online reading experience. In these cases, the publication is somewhat at the mercy of the platform (WordPress in the former, BePress Digital Commons in the latter), but as libraries become publishers, they will have to develop platforms that meet the needs of modern researchers.

A question put to the ACRL Tech Connect contributors about preferred reading methods for articles suggests that there is no one right answer, and so the safest course is to release content in a variety of formats or make it flexible enough for readers to transform to a preferred format. A new journal to watch is Weave: Journal of Library User Experience, which will use the Digital Commons platform but present content in innovative ways. 9 Any libraries starting new journals or working with their campuses to create new journals should be aware of who their readers are and make sure that the solutions they choose work for those readers.

 

 

  1. “The Launch of PeerJ – PeerJ Blog.” Accessed February 19, 2013. http://blog.peerj.com/post/42920112598/launch-of-peerj.
  2. “Some of the Innovations of the PeerJ Publication Platform – PeerJ Blog.” Accessed February 19, 2013. http://blog.peerj.com/post/42920094844/peerj-functionality.
  3. http://blog.peerj.com/post/45264465544/evolution-of-timeline-design-at-peerj
  4. “The Thinking Behind the Design of PeerJ’s PDFs.” Accessed March 18, 2013. http://blog.peerj.com/post/43558508113/the-thinking-behind-the-design-of-peerjs-pdfs.
  5. http://blog.peerj.com/post/43139131280/the-reception-to-peerjs-open-peer-review
  6. “PeerJ Delivers: The Review Process.” Accessed March 18, 2013. http://edaphics.blogspot.co.uk/2013/02/peerj-delivers-review-process.html.
  7. Meadow, James F., Ashley C. Bateman, Keith M. Herkert, Timothy K. O’Connor, and Jessica L. Green. “Significant Changes in the Skin Microbiome Mediated by the Sport of Roller Derby.” PeerJ 1 (March 12, 2013): e53. doi:10.7717/peerj.53.
  8. Ford, Emily, and Carol Bean. “Open Ethos Publishing at Code4Lib Journal and In the Library with the Lead Pipe.” In the Library with the Lead Pipe (December 12, 2012). http://www.inthelibrarywiththeleadpipe.org/2012/open-ethos-publishing/.
  9. Personal communication with Matthew Reidsma, March 19, 2013.