Using Plex with Nextcloud

After hearing about it for years, I finally got around to installing plex on my nuc. I’m impressed with everything about Plex. It was easy to install, and mostly works out of the box. I am using it to manage my ever growing movie collection and massive music library.

All of my files were already on the nuc since I am using Nextcloud. Rather than duplicating the files, I pointed my media library to the same directory where my files are in my nextcloud installation.

This poses a couple of permissions problems. On Ubuntu, this directory is owned by the www-data (apache) user and group. In order to get plex to be able to see the files at all I had to add the plex user to the www-data group and then restart the plex service. The following commands will make that happen:

sudo usermod -aG www-data plex
sudo systemctl restart plexmediaserver.service

My biggest complaint with most “home media servers” is that once you point the files to the right place, you cannot really “manage” most of them. For instance, I have a massive (50+ GB) music collection that I have built up over the years. When I am listening on shuffle I want to prune out some of the songs that I hate. Luckily, with plex this is very simple. The only catch is that the www-data group needs to have read/write/execute access to those files.

In order to make this happen you can run the following command against your data file. Be sure to replace the directory I have below to whatever you are using for your own Nextcloud files.

chmod -R 775 /var/www/nextcloud/data/levlaz/files

Doing these two things makes the Plex + Nextcloud integration work very well. Now whenever I add or remove files from my many different computers everything stays in sync.

Terminal Reader Mode with Pandoc and Less

The other day Aosheng send me an article to read from the verge. When I tried to read it, it took about 5 minutes to load because of the 15 various JavaScript things that were running in addition to ads loading in the background. Firefox was unhappy, and even when I tried to turn on “Reader View” (which strips out all of the junk) it took another minute to load. I’ve been on a UNIX binge lately so I figured there had to be a clever hack to make my own reader view in a terminal. This is where pandoc comes to the rescue. I’ve written about this tool in the past discussing how to easily convert Markdown to PDF. It turns out that pandoc also supports arbitrary URL arguments which means that you can convert HTML files on the fly without having to download them first. This means that we can take an arbitrary URL, pass it into pandoc, and spit out plain text. Furthermore, we can pipe this into less to get a nice pager for longer documents. The full string is shown below:

pandoc -f html -t plain
https://www.theverge.com/2017/5/4/15547314/edward-snowden-cory-doctorow-nypl-talk-walkaway
| less

In the example above, -f specifies the input filetype, in this case HTML. -t specifies the conversion filetype, in this case plain text. Pandoc supports a ton of different formats, you can read the man pagefor more info.

The next logical step is to make a script like my wordpress mutt posterto make this even easier. You could make a simple program called readerand put it in /usr/local/bin/reader. The contents of this script are:

1
2
3
4
5
6
#!/bin/bash
# Terminal Reader Mode using Pandoc and Less

url="$1"

pandoc -f html -t plain $url | less

You can then use this  by typing reader $URL.

Posting to WordPress via Email with Mutt

Soemtimes you are hanging out in your terminal and you just want to be able to post something to your blog quickly. I was pretty inspired by Derek Siver’s OpenBSD post [1] where he really embraces the unix philosophy of having one tool to do a job correctly and putting together various small tools like this to come up with a solution for the problem that you are trying to solve with your computer. WordPress with Jetpack makes it dead simple to post to your blog via email [2], even if you do not have a mail server configured. I was able to write a three line bash script to “automate” creating a new post from my command line.’

#!/bin/bash
# Bash Utility to Post to WordPress using Mutt

subject="$1"
WP_ADDRESS=

mutt -s "${subject}" $WP_ADDRESS

I saved this file in /usr/local/bin/wp and whenever I am inspired to fire off some quick thoughts to this blog I can run wp "Blog Post Title" which dumps me into a vim buffer that once I complete is sent off via mutt to wordpress. [1] https://sivers.org/openbsd [2]https://jetpack.com/support/post-by-email/#examples

Using Owncloud Client for Nextcloud Server on Debian Stable

There is no official debian package for the nextcloud client. There have been a handful of RFP bugs reported but it looks like no one has taken this on yet. I want to get more involved with debian packaging so this might be a great first package to maintain. For the time being, the owncloud client is still backwards compatible with nextcloud. Unfortunately, the version that ships with Debian stable (8, jessie at the time of writing) is a bit old. When I tried to connect to my nextcloud instance it complained that my password was incorrect. Luckily, there is a slightly newer version available in jessie-backports  which has no trouble connecting to nextcloud. The steps to get a working version of owncloud-client to work with the latest stable version of Nextcloud are as follows:

  1. If you have not already, enable jessie-backports
    1. Open up /etc/apt/sources.list
    2. Append deb http://ftp.debian.org/debian jessie-backports mainto that file.
  2. Run sudo apt-get update
  3. Install the latest version of owncloud-client with sudo apt-get install -t jessie-backports owncloud-client

You should now be able to connect to nextcloud without any issues.

Testing Syntax Errors in Apache Config

If you spend any time mucking around config files in Linux you are likely to run into some syntax errors sooner or later. Recently I was setting up cgit on Debian 8 and was banging my head against the wall for a few minutes trying to figure out why apache was so unhappy.

Symptoms

The key issue was when I restarted apache2 like I normally would after adding a new configuration it spat out an angry message at me.

root@nuc:/etc/apache2# sudo service apache2 restart
Job for apache2.service failed. See 'systemctl status apache2.service' and 'journalctl -xn' for details.

Troubleshooting

The first place that I would look is the error logs. However, in this particular case they were not very helpful.

root@nuc:/etc/apache2# tail -f /var/log/apache2/error.log
[Mon May 01 21:00:11.922943 2017] [mpm_prefork:notice] [pid 20454] AH00169: caught SIGTERM, shutting down

Next, I read the error message per the suggestion from the restart command. This was also not very helpful.

root@nuc:/etc/apache2# systemctl status apache2.service
 apache2.service - LSB: Apache2 web server
 Loaded: loaded (/etc/init.d/apache2)
 Drop-In: /lib/systemd/system/apache2.service.d
 └─forking.conf
 Active: failed (Result: exit-code) since Mon 2017-05-01 21:05:58 PDT; 1min 45s ago
 Process: 20746 ExecStop=/etc/init.d/apache2 stop (code=exited, status=0/SUCCESS)
 Process: 20697 ExecReload=/etc/init.d/apache2 reload (code=exited, status=1/FAILURE)
 Process: 20920 ExecStart=/etc/init.d/apache2 start (code=exited, status=1/FAILURE)

May 01 21:05:58 nuc apache2[20920]: Starting web server: apache2 failed!
May 01 21:05:58 nuc apache2[20920]: The apache2 configtest failed. ... (warning).
May 01 21:05:58 nuc apache2[20920]: Output of config test was:
May 01 21:05:58 nuc apache2[20920]: apache2: Syntax error on line 219 of /etc/apache2/apache2.conf: Syntax error on line 22 of /etc/a... section
May 01 21:05:58 nuc apache2[20920]: Action 'configtest' failed.
May 01 21:05:58 nuc apache2[20920]: The Apache error log may have more information.
May 01 21:05:58 nuc systemd[1]: apache2.service: control process exited, code=exited status=1
May 01 21:05:58 nuc systemd[1]: Failed to start LSB: Apache2 web server.
May 01 21:05:58 nuc systemd[1]: Unit apache2.service entered failed state.
Hint: Some lines were ellipsized, use -l to show in full.

Inspecting the error message, we see that it is unhappy with line 219 of the main /etc/apache2/apache2.conf file. Looking at that line we can see that it is simply loading all of the other config files in sites-enabled which means that before it even gets to load my new cgit config file it fails.

Help

So now that we have done some basic troubleshooting. It’s time to dig into the manual for further information. I know that the config file is failing to load, and knowing my fat fingers it is very likely a config error on my part. Before reading 200 pages of documentation on the apache website we should take a look at the built in help to see if we can find something of value.

root@nuc:/etc/apache2# apache2 -help
Usage: apache2 [-D name] [-d directory] [-f file]
 [-C "directive"] [-c "directive"]
 [-k start|restart|graceful|graceful-stop|stop]
 [-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S] [-X]
Options:
 -D name : define a name for use in <IfDefine name> directives
 -d directory : specify an alternate initial ServerRoot
 -f file : specify an alternate ServerConfigFile
 -C "directive" : process directive before reading config files
 -c "directive" : process directive after reading config files
 -e level : show startup errors of level (see LogLevel)
 -E file : log startup errors to file
 -v : show version number
 -V : show compile settings
 -h : list available command line options (this page)
 -l : list compiled in modules
 -L : list available configuration directives
 -t -D DUMP_VHOSTS : show parsed vhost settings
 -t -D DUMP_RUN_CFG : show parsed run settings
 -S : a synonym for -t -D DUMP_VHOSTS -D DUMP_RUN_CFG
 -t -D DUMP_MODULES : show all loaded modules
 -M : a synonym for -t -D DUMP_MODULES
 -t : run syntax check for config files
 -T : start without DocumentRoot(s) check
 -X : debug mode (only one worker, do not detach)

Success! It turns out we can run a linter on a specific config file using the -t flag.

Solution

root@nuc:/etc/apache2# apache2 -t -f sites-available/git.levlaz.org.conf
apache2: Syntax error on line 22 of /etc/apache2/sites-available/git.levlaz.org.conf: </VirtualHost> without matching <VirtualHost> section

Doh! Such a silly mistake with a missing </VirtualHost> closing bracket. Fixing this syntax error resolved the issue. The main takeaway for me is that the best part about most Linux tools is that they usually give you everything you need in order to succeed. We were able to troubleshoot and resolve this issue without resorting to google and running random commands that stranger posted on the internet 5 years ago.

Standard Notes is a Better Project than Braindump

released braindump to the world last year to much fanfare. After the initial excitement from being on HN died down, and the PR’s stopped rolling in, it became a personal project once again with very few users. Over the last few weeks I have made several attempts to fix the spaghetti mess that is the current code base by refactoring the current Flask implementation, then rewriting it completely in Django, and even started a branch to investigate rewriting the whole app in PHP using Laravel. Other commitments took precedence and Braindump remains in a fairly usable but not that special state.

Today on HN I read about a new project called Standard Notes which is the most exciting note related project that I have seen in a long time. It solves so many of the problems around cross platform compatibility that plague many other note tools. In addition its goals are to create a standard file format for simple, secure, and durable notes. Even more it has already created a platform, an ecosystem, that allows anyone to come and create additional applications, plugins, and use cases for notes.

These are some of the problems that I set out to tackle when I started braindump. After reading about Standard Notes, and using it for a few hours, I have decided that my time would be better spent contributing to that project instead of continuing to work on Braindump.

Working on Braindump has been amazing. I learned a ton, became a better programmer, and most of all had a lot of fun. I want to thank everyone who tried it, provided feedback, and sent patches. The source code for braindump will remain on GitHub but I would encourage you to try and contribute to the Standard Notes project along with me.

Polarr; Professional Photo Editing on Linux

One of the most frustrating things about being a desktop Linux user is that a lot of software is either:

  1. Half Baked, Buggy, and Free
  2. Half Baked, Buggy, and Completely Overpriced
  3. Unavailable

This is why I was so pleased when Aosheng introduced me to Polarr. This app is written in Electron and is a very simple and powerful tool. As I continue to make abundantly clear, I am not an artist, designer or photographer. Despite this, I keep taking a ton of photos during my adventures and I need a tool to edit them with.

On Ubuntu the choices are either to use the built in Shotwell app which is just OK. You can fumble through GIMPs incomprehensible menus and feature sets, or you can move sliders around in darktable. I don’t mean to poke fun at these tools. I truly appreciate all of the hard work that has gone into developing them, and I am certian that for a professional designer who actually understands what they are doing they are worth learning. But for someone like me, who just wants to click a button and make a photo not look awful nothing on Linux comes close to Polarr.

I love how Electron has made creating cross platform desktop applications completely painless. I think it allows application developers to enable Linux support by default and opens them up to a huge and often overlooked market.

Polarr is free to use with a basic feature set, and you can get the full version for an astonishingly low price of $9.99. If you do anything with Photos on Linux, go buy this right now.

Recovering from Syntax Errors in /etc/rc.conf in FreeBSD

I have been exploring FreeBSD over the last few weeks. In fact, I moved this blog over to a server running FreeBSD tonight. Naturally, while fiddling around with /etc/rc.conf (the default init file of FreeBSD) with vi I made a syntax error. Upon rebooting, FreeBSD yells at me and starts a shell in a read only file system.

Loading configuration files.
/etc/rc.conf: 16: Syntax error: Unterminated quoted string
Enter full pathname of shell or RETURN for /bin/sh:

At first, I was super sad and thought I had to reinstall everything (which would not have been so bad since the installation just takes a few minutes), but then I realized that it is not possible that I am the first person to ever make an error in this file, there has to be a way to recover. Sure enough, there is.

  1. Remount the Root File System First we must remount the root files system. Go ahead and press RETURN to pop into /bin/sh
    /sbin/mount -o rw /
    
  2. Edit /etc/rc.conf Now that we have a read/write file system mounted we can edit our /etc/rc.conf file and fix the syntax error using vi
  3. Reboot

    Reboot, and FreeBSD will be back in action.

Installing Nextcloud on a FreeBSD VPS

Introduction

Nextcloud is an exciting new fork of OwnCloud. I have been meaning to try it out lately and I finally got around to doing it. I picked Vultr{.add-link} for this instance since they have really affordable “Spinny Disk” instances starting at just \$5/mo for 125GB. The performance is noticeably slower than SSD, but if you are looking for a low cost place to store all of your files then this deal cannot be beat. Vultr also comes with full support for FreeBSD out of the box, which is a great choice for a system like this. The official Nextcloud documentation is wonderful, however it seems like it geared toward large multi-user installs. The purpose of this guide is to make it easy to install Nextcloud for a single (or just a few) user system. If you follow this guide you will have the latest stable version of Nextcloud with PHP7, Apache 2.4, MySQL 5.7 and Redis secured with LetsEncrypt on the latest stable version of FreeBSD.

Pre Requisites

In order to complete this guide successfully with a TLS enabled Nextcloud site you must have a domain name with DNS that successfully resolves to the IP address of your VPS Server.

Configuration Steps

  1. Launch a new Storage Instance in the DC of your choice. In my specific case I am running a 512MB RAM/125GB HD instance in the Los Angeles Data Center.
  2. SSH into the new VPS.
  3. Update and Upgrade BSD
    pkg update && pkg upgrade
    
    # [Optional] Install some helper packages
    pkg install vim-lite htop tmux
    
  4. Add some swap By default, the storage instance does not come with a swap partition, since I chose the smallest instance with 512MB of RAM, it is probably a good idea to add some swap because if the system ever runs out of memory the whole entire thing will come crashing down. You can read more about how to add swap in FreeBSD, but the gist of it is:
    # Create a 1GB sawp file
    dd if=/dev/zero of=/swap bs=1m count=1024
    
    # Set proper permissions on swap file
    chmod 600 /swap
    
    # Add swap to /etc/fstab
    md99    none    swap    sw,file=/swap,late  0   0
    
    # Turn swap on
    swapon -aL
    

    If everything was successful, running htop you should now see some swap space.

  5. Install and Configure BAMP Stack (BSD, Apache, MySQL, PHP) and Redis
    • Install all packages and dependencies
      pkg install apache24 mysql57-server redis php70 mod_php70 php70-pdo_mysql \
      php70-redis php70-gd php70-curl php70-json php70-zip php70-dom \
      php70-xmlwriter php70-xmlreader php70-xml php70-mbstring php70-ctype \
      php70-zlib php70-simplexml php70-hash php70-fileinfo php70-posix \
      php70-iconv php70-filter php70-openssl
      
    • Add Services to /etc/rc.conf
      # /etc/rc.conf
      
      ...
      apache24_enable="yes"
      mysql_enable="yes"
      redis_enable="yes"
      
    • Configure Apache Ensure that the rewrite and ssl modules are enabled (uncommented) in /usr/local/etc/apache24/httpd.conf.
      # /usr/local/etc/apache24/httpd.conf
      
      ...
      
      LoadModule ssl_module libexec/apache24/mod_ssl.so
      LoadModule rewrite_module libexec/apache24/mod_rewrite.so
      
      ...
      

      Add a PHP handler to /usr/local/etc/apache24/modules.d

      # /usr/local/etc/apache24/modules.d/001_mod_php.conf
      
      <FilesMatch "\.php$">
      SetHandler application/x-httpd-php
      </FilesMatch>
      <FilesMatch "\.phps$">
      SetHandler application/x-httpd-php-source
      </FilesMatch>
      
    • Configure MySQL Once MySQL has been added to /etc/rc.conf you can start it up by executing the following command in your shell:
      /usr/local/etc/rc.d/mysql-server start
      

      The first time MySQL runs it will create a root password which can be found in $HOME/.mysql_secret, use this password to log into MySQL, change the root password, and then create a new admin user for Nextcloud.

      # Grab the Root Password
      cat ~/.mysql-secret
      
      # Log into MySQL
      mysql -u root -p $PASSWORD # Password from previous step
      
      # Change the Root Password
      ALTER USER 'root'@'localhost' IDENTIFIED BY '$NEW_PASSWORD';
      
      # Create New Schema for Nextcloud
      CREATE DATABASE nextcloud;
      
      # Create New Admin User for Nextcloud
      CREATE USER 'nextcloud_admin'@'localhost' IDENTIFIED BY '$OTHER_NEW_PASSWORD';
      
      # Grant Permissions to the new Admin user to the Nextcloud Schema
      GRANT ALL ON nextcloud.* TO 'nextcloud_admin'@'localhost';
      
      # Refresh all Privileges
      FLUSH PRIVILEGES;
      
    • Configure Redis There are many different memory caching strategies for Nextcloud. I like using Redis for this sort of thing, you can chose whichever strategy you prefer. The following (optional) configuration will make redis run on a local socket instead of over TCP. This is better from a security perspective. Update /usr/local/etc/redis.conf to run on local socket
      # /usr/local/etc/redis.conf
      
      ...
      
      port 0
      ...
      
      unixsocket /tmp/redis.sock
      unixsocketperm 750
      

      Add www user to the wheel group so that it has permission to access this socket.

      pw groupmod wheel -m www
      

      Start Redis

      /usr/local/etc/rc.d/redis start
      

      If everything went well, you should see the redis socket in/tmp

      # ls -al /tmp
      total 48
      drwxrwxrwt   7 root   wheel  512 Sep  1 23:02 .
      drwxr-xr-x  18 root   wheel  512 Sep  1 22:03 ..
      
      ...
      
      srwxr-x---   1 redis  wheel    0 Sep  1 23:02 redis.sock
      
      ...
      
  6. Download Nextcloud We are almost there! The last few steps are to actually download and configure Nextcloud. You can get the latest version of Nextcloud from here.
    # Go to the default apache data directory
    cd /usr/local/www/apache24/data
    
    # Download Nextcloud
    wget https://download.nextcloud.com/server/releases/nextcloud-10.0.0.zip
    
    # Unzip Nextcloud
    unzip nextcloud-10.0.0.zip
    
    # Make sure the www user owns this directory
    chown -R www:www nextcloud
    
  7. Install and run certbot by LetsEncrypt The full instructions are available here but the gist is:
    # Install the Package
    pkg install py27-certbot
    
    # Generate the Cert
    certbot certonly
    

    Go through the certbot UI and fill out your site specific details. If all goes well you should see a message that says:

    Congratulations! Your certificate and chain have been saved at/usr/local/etc/letsencrypt/live/$YOUR_SITE/fullchain.pem

  8. Create a VirtualHost Configuration for Nextcloud Create a new file called $YOUR_SITE.conf in /usr/local/etc/apache24/Includes, the contents of this file should have a VirtualHost specification for your new Nextcloud site. The first VirtualHost will listen on port 80 and redirect all requests to HTTPS. The second VirtualHost will listen on port 443 and serve your actual Nextcloud site.
    <VirtualHost *:80>
      ServerAdmin $YOUR_EMAIL
      ServerName $YOUR_SITE
    
      RewriteEngine on
      RewriteCond %{SERVER_NAME} =$YOUR_SITE
      RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,QSA,R=permanent]
      </VirtualHost>
    
    Listen 443
    
    <IfModule mod_ssl.c>
      <VirtualHost *:443>
        ServerAdmin $YOUR_EMAIL
        ServerName $YOUR_SITE
    
        DirectoryIndex index.php
        DocumentRoot /usr/local/www/apache24/data/nextcloud
        SSLCertificateFile /usr/local/etc/letsencrypt/live/$YOUR_SITE/fullchain.pem
        SSLCertificateKeyFile /usr/local/etc/letsencrypt/live/$YOUR_SITE/privkey.pem
    
        SSLEngine on
    
        # Intermediate configuration, tweak to your needs
        SSLProtocol             all -SSLv2 -SSLv3
        SSLCipherSuite          ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
        SSLHonorCipherOrder     on
        SSLCompression          off
    
        SSLOptions +StrictRequire
    
        <Directory /usr/local/www/apache24/data/nextcloud>
          AllowOverride all
        </Directory>
    
        <IfModule mod_headers.c>
          Header always set Strict-Transport-Security "max-age=15552000; includeSubDomains"
        </IfModule>
    
      </VirtualHost>
    </IfModule>
    

    Start apache with /usr/local/etc/rc.d/apache24 start

  9. Configure Nextcloud
    • Verify Installation Go to http://\$YOUR_SITE.com, verify that you get redirected to HTTPS and that the certificate shows up as valid.
    • Create Admin Account If this page loads properly, you should create an admin user, set the data directory location, and fill in the database credentials from step 5.
    • Tweak Config File We need to tweak the config file in order to enable Redis memory caching. Open up/usr/local/www/apache24/data/nextcloud/config/config.php and add:
      # /usr/local/www/apache24/data/nextcloud/config/config.php
      
      ...
      
      'memcache.locking' => '\\OC\\Memcache\\Redis',
      'memcache.local' => '\\OC\\Memcache\\Redis',
      'redis' =>
      array (
      'host' => '/tmp/redis.sock',
      'port' => 0,
      ),
      
    • Use System Cron Job By default NextCloud uses an AJAX cron, the performance is a bit better if you let the system cron handle this. Add the following to the crontab:
      # crontab -u www-data -e
      PATH=/usr/local/bin
      */15  *  *  *  * php -f /usr/local/www/apache24/data/nextcloud/cron.php
      

      Once this has been added, select Cron from Admin -> Settings

    • Enjoy Nextcloud That was a lot of steps, but now we have a private, self hosted, secure, and affordable Nextcloud instance. If you ran into any issues during installation please let me know in the comments below!

Next Steps

Notes on Steve Krug’s ‘Don’t Make Me Think’

I am working my way through Jeff Atwoods reading list and finally got around to reading Don’t Make Me Think{.add-link} by Steve Krug. This is one of the best books that I have read in quite some time. His writing style is amazing, and there is so much useful content in the book that I don’t even want to spoil it by talking about it here. As a completely unrelated side note, Steve Krug is a Usability Professional, the last time I read about this specific term was in Cory Doctorow’s Eastern Standard Tribe where the main character had the same career.

Hot Takes

  1. People don’t read your website, stop designing it like they do. Instead, learn how to make great billboards.
  2. Focus on the problem you are solving rather than the problem that has already been solved.

There is a common trope these days on Twitter where people joke about the fact that every product website looks the same. Jumbotron header, green call to action, and a three column list with icons that explain what your product does. For instance: Mockup of Every Website Ever
Made I see this now as a less of a problem, this model works, its clear, use it and focus on building your product instead of re-inveting the wheel of what product pages are supposed to look like.

  1. ~~Write Less. My favorite part of this book is the heading to Chapter 5; Omit Needless Words. I learned about this when I read On Writing Well{.add-link} during an expository research writing course in college, but based on how much text is in this paragraph, I seem to have forgotten the lessons that the book taught me~~.
  2. Write Less.
  3. Don’t punish users for not doing things your way. This is especially true for forms of all types.

Don’t make me jump through hoops just because you don’t want to write a bit of code.

  1. Think about Accessibility. I am guilty of this myself, but primarily because all of my projects are half finished. The main things to watch out for are color coded things, inability to adjust text size, and making things impossible to read via a screen reader. (Like by using HTML tables for structure). Ricardois famous for thinking about these types of things in his projects and it motivates me to do better.

Further Reading

I am one of those strange people that read the bibliography, further reading section, and hang on to each recommendation. This is partially why my current reading list is too long to even look at. With that being said, a couple books that I plan to read per Krug’s recommendation are:

  1. The Design of Everyday Things{.add-link} — Classic Book about design. If you look at some of my work (this blog, braindump) you will immediately realize that I am not a designer. I am OK with that, I hope this book will help me get a better understanding of the fundamentals.

Update: By the time I finished this post, I already bought the book at my local bookstore. Can’t wait to read it.

  1. Letting Go of the Words{.add-link} — how to become a better writer for the web.
  2. Forms that Work: Designing Web Forms for Usability{.add-link} — I have not heard about this book before, but as someone who has used and designed a bunch of awful forms this seems like a great use of my time.
  3. Rocket Surgery Made Easy{.add-link} — Don’t Make Me Think had a great overview of DIY usability testing, this is a follow up from Krug that dives deeper into Usability Testing for teams that cannot afford the \$5-10K cost of a professional usability test.
  4. A Web for Everyone: Designing Accessible User Experiences{.add-link} — The chapter about Accessibility in Don’t Make Me Think really hit home for me. I look forward to learning more about the accessibility problems that I do not think about that often and apply them to my own work.