Archives

Category: TIL

  • Basic Logging with PHP and Syntax Highlighting in Jekyll


    Today I learned:

    Basic Logging to CSV in PHP

    I asked Eric Davis about logging for debugging and usage stats on my Toggl Slack slash command and he suggested that I look into writing to a CSV or JSON file. I opted for CSV.

    Here I build the array from the information I get back from Slack (plus a datetime stamp) and pass it to a file called log.csv via fputcsv().

     $log_array = array($date,$user_id,$user_name,$command,$text,$response_url,$channel_id,$channel_name,$token,$team_id,$team_domain); $output = fopen('log.csv', 'a'); fputcsv($output, $log_array); fclose($output);

    A note on fopen() – A lot of tutorials replace that 'a' with a 'w'. According to the docs, w writes at the beginning of the file, which is why my first couple tries overwrote each other. The a starts writing at the end of the file, which is always a new line since fputcsv() always ends with a line break.


    Syntax Highlighting

    I finally found a good solution for syntax highlighting in code blocks with Jekyll: Kramdown with Pygments plugin.

    Installation is simple: Clone the project to your _plugins folder and add it to the Plugins section of your _config.yaml, then you are ready to go.

    Usage is equally as simple: Specify the language at the end of the first line of your code blocks and the plugin will add the proper classes and highlight the code according to the language.

    Example:

    ~~~~ php echo "Hello world!"; ~~~~ 

    Will output:

    echo "Hello world!"; 
  • Thoughts on Providing Solutions, Learning, Culture, and Distractions


    I didn’t do much technical work today besides some front-end debugging. Instead I did a lot of administrative and project management work and ended up thinking a lot about how I work.

    Here is what I thought about.

    Always provide a solution

    As a consultant, you aren’t paid to tell people they have problems. They already know that and chose to hire you. It is your job to provide solutions.

    Instead of being negative or saying that a proposal can’t be done, try to get at the heart of the request and offer an alternative solution. You and your clients will be much happier.

    As things get frustrating, it is easy to take the, “look how messed up this thing is” route. But that isn’t your job. You need to roll up your sleeves, brew some coffee, and come up with a solution.

    Learning

    I find time and time again that I retain so much more of what I learn if I’m applying it as I’m learning. So why do I continue to use books with pre-designed activities that I mindlessly copy? Because it is a lot easier than coming up with a project from scratch.

    From now on I’m applying what I learn in my own way. No more copying examples. I’m going to figure it out and learn it the hard way.

    Culture

    • Sometimes you need to find software that is a better fit for your culture. But sometimes you need to take a hard look at the culture and its ability to adapt if there doesn’t seem to be any good solution.
    • Like learning, sometimes cultural change only comes the hard way: Adapting because it is necessary.

    Distractions

    • Second screens are great for productivity when you are in the zone. Unfortunately they are also great for procrastination when you aren’t in the zone. Sometimes you need to turn that second screen off and focus on one thing at a time.
    • Filter, filter, filter. Reduce the number of things that can distract you. If you don’t need to make a decision on it, don’t let yourself see it. For example, in Excel, if you only need to read items that have a specific attribute, filter your view by that specific attribute and hide the rest.

    Idea for a Slack bot: What is distracting you right now?

    • Regular messages (10, 2, and 4?) via Slack
    • Respond with comma separated items that are distracting me.
    • Save those responses in a database for later analysis
  • Unicode Conversions in PHP and Remote Git Repos


    Today I learned:

    Converting Unicode quotation marks in PHP

    Unicode quotation marks (sometimes called smart quotes) are those curved/slanted single and double quotation marks: “ ” ‘ ’. The ASCII ones look like this: " '. They are usually interchangeable in word processing, but the stylized ones sometimes cause issues on the web (in a parser, for example).

    To convert one to the other in PHP, use iconv():

     $output = iconv('UTF-8', 'ASCII//TRANSLIT', $input);

    If you use OS X and want to turn off smart quotes, go to System Preferences > Keyboard > Text and uncheck “Use smart quotes and dashes.”


    Remote git repositories

    Using git locally is one thing, but it is far more powerful (and exciting!) to push that code to a remote repository like Github for display and collaboration.

    Assuming you have a local repository that wasn’t cloned from a remote one, you’ll need to hook it up to a remote repository:

    $ git remote add origin 

    If there is code already on the remote repository, you’ll need to merge it in to your local:

    $ git pull $ git merge origin/master

    Then push your committed files to the remote repository:

    $ git push origin master

    For a great beginner’s guide to git, check out Roger Dudler’s git – the simple guide.


    Toggl Slash Command for Slack

    Today I released my first personal project on Github: Toggl Slash Command for Slack.

    It is a custom slash command that enables users to put time entries into Toggl from Slack.

    If you use it, I’d love to know! It is in its rough early stages, but I have some future additions planned for it, so stay tuned.

  • CSS Inheritance, Datetime Conversions in PHP


    Today I learned:

    CSS Inheritance

    • In CSS some styles are automatically inherited from their ancestors (i.e. elements which contain that element). For example, if you set body {color: red;}, all text inside the body element, regardless of what other elements the text is in, will be red unless the color style is set on one of those other elements later in the .css file.
    • This simultaneously makes writing CSS a breeze and debugging it a bit of a headache. There isn’t a great way to tell if a style is inheritable without looking at the docs.
    • If you encounter an issue where your style isn’t displaying as it should and it is not responding to changes, check the docs to see if the style can be automatically inherited. If so, check the ancestors of the element you are working on.

    The issue I ran into today was that my

     snippets kept wrapping no matter what overflow and width were set to. It turns out that word-wrap is automatically inherited and I had it set on an ancestor element.


    Date/time conversions in PHP

    Date conversions are tricky. Thankfully, PHP has some built-in functions to make this easier.

    Example: date("c", time()) will take the current time (provided as a Unix timestamp) and convert it to ISO 8601 format.

    Unix timestamps are the number of seconds that have elapsed since the Unix Epoch (00:00:00 Coordinated Universal Time (UTC), Thursday, 1 January 1970). They can be frustrating at first because they are so foreign looking, but they are really useful because:

    1. They are not subject to timezones.
    2. Since they are simply seconds, time math with Unix timestamps is pretty simple: Convert the time you wand to add or subtract into seconds and do the direct calculation. Then if you want to get it back into a recognizable format, use one of the functions above.

    I’ve been working on a custom Slack command to input time into Toggl, so I’ve been doing quite a bit with time conversions to get everything right.

  • Doing the Work, Flipping the Status Quo, and Alphabetizing in Liquid


    Today I learned:

    Doing the Work

    I used to be really interested in how people worked. When they get up, what their morning rituals are, what tools they use, how they use them, etc. While these things are interesting and tell a story about a person, they miss the point.

    How someone works isn’t nearly as important as the fact that they are doing the work. They made the choice to do what it takes each day to practice their craft. The rest is minutiae.

    If using the GTD method or having morning rituals works for you, great. But don’t think that those things are what really matter. If you’ve committed yourself to doing the work, you’ll find a way. If you haven’t committed yourself, none of the rituals or methods will make a difference.

    This commitment is very difficult, but necessary.


    Flipping the Status Quo

    We all suffer from status quo bias. How do we overcome it? We can get 80% of the way there by:

    • Instead of asking, “Why should this be different?” ask “Why should this stay the same?” – This is especially powerful when confronting clutter. (By the way, the answer, “because it gives me joy” is a valid reason for keeping something. Change for change’s sake isn’t helpful.)
    • Recognize the difference between acknowledging a feeling and rationalizing that feeling to keep the status quo.

    Source: Planet Money episode #683


    Sorting tags alphabetically in Liquid

    It was starting to annoy me that my tags were not in alphabetical order on my Today I learned page. So I learned how to sort them alphabetically with Liquid and I added anchor links with counts for each tag.

    Here is my updated template code:

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 
      	{% assign sorted_tags = (site.tags | sort:0) %} 	 	 	{% for tag in sorted_tags %} 	  {% assign t = tag | first %} 	  {% assign posts = tag | last %} 	 	

    {{ t | downcase }}">{{ t }}

    {% endfor %}

    Sources: I cobbled this together from Michael Lanyon’s blog, Joe Kampschmidt’s blog, and the Liquid docs.

  • How to keep track of files and requests in Slack


    Today I learned:

    How to keep track of files and requests in Slack

    Slack is wonderful for collaborating with remote teams, but if there is a lot of activity at once, it can be easy to lose files and requests.

    • If I’ve seen the request or file, I acknowledge by marking it with , then I put it on my to-do list of choice, WunderlistArchived Link. (They have a great Slack commandArchived Link to make this easy: /wunderlist add)
    • If I’ve fulfilled the request or processed the file, I mark it with
    • If the request/file is no longer needed or I’ve tried to process it, encountered an error, and notified the appropriate parties, I mark it with so that I know in the future that there was an issue with it instead of assuming it was done and I moved on.
    • Using Slack’s great search functionality, I can easily visually figure out what I’ve processed and what is still outstanding.
    • If I get a request when I’m in the middle of something else, I copy the link and use Slack’s /remind command to remind me about it later in the day.
  • Useful Analytics, Scalability, and RSI


    Today I learned:

    Useful Analytics

    • There are a lot of things that are easy to track that are completely useless to track.
    • Make sure the things you track relate directly to your goals.
    • Sometimes the things you want to track aren’t easy (or possible) to track and you need proxies instead. This is okay.

    Visible statistics like Facebook likes and Twitter followers, etc, are easy to obsess over because they are public and they are so easy to find. But don’t fall into to the trap of thinking these numbers are what really matter. Getting more followers is unlikely to be your actual goal. Purchases, downloads, or donations and what directly affects those things are what you should really focus on. The closer the things you test are to your actual goals the better.

    • Instead of Twitter followers, test and track your click-through rate for specific types of content at different times of day.
    • Instead of website pageviews, track the length of time on page and how far people scroll down through your content.
    • Instead of likes on a Facebook status track how many people see that status and follow your calls to action.

    Scalability

    You can always scale with more people or by working more hours. The trick is to design your business to scale the amount of products and services you provide without a 1:1 (or worse) increase in costs, labor or otherwise. In order to scale you want to become more efficient and more automated. When building your product/service, bake in efficiency and automation from the beginning so you can eventually move on to the next thing (or next version) while it sustains itself.


    RSI

    I’ve been experiencing some RSI lately in my right wrist, just below my thumb. It primarily hits when I use my mouse for an extended period. I read a number of sources and asked some friends today about how to cope with it. Here are some solutions:

    • Stretching and regularly stopping to do so during the day
    • An ergonomic mouse like the Anker Vertical or the Logitech MX Master
    • Varying input devices, such as switching between a trackpad and a mouse or a Wacom tablet and a mouse
    • Switching to a trackpad (like the Magic Trackpad 2) to minimize wrist movements.

    I decided to buy a Magic Trackpad 2 and try it. The reason I went with that over a tablet or ergonomic mouse is that I can’t stand the idea of using my computer without gestures. I’d have to change all of my workflows. If the trackpad doesn’t help, I can return it within 14 days for a full refund and try one of the other mice. The past hour of use has been promising. We’ll see.

  • Meteor Basics, Secure Hash Algorithms, and 404 Error Pages


    Today I learned:

    Meteor Basics

    • Meteor is a platform for building real-time web apps that sits between your app’s database and its user interface and makes sure both are kept in-sync. It is built on Node.js, so it uses javascript on both the client and the server.
    • If you want to go above and beyond the Meteor documentation, the Discover Meteor bookArchived Link is a good place to start.
    • If you want to start learning Meteor but are fuzzy on the basics of Javascript, here is an 80/20 primerArchived Link.

    Basic Usage

    • To create a new project:
     $ meteor create [project name] 
    • To then run that new app at http://localhost:3000/:
     $ cd [project directory] $ meteor 
    • To stop the app from running, press ctrl+c
    • Adding a package like Twitter Bootstrap to a Meteor app is incredibly simple. No files to link up, Meteor takes care of all of that out of the box:
     $ meteor add twbs:bootstrap 

    Structure

    Meteor has five types of packages. most can be seen in [project directory]/.meteor/packages:

    1. meteor-base is Meteor’s set of core components.
    2. First-party packages that come bundled with Meteor that can be removed, such as mongo (the database) and session (a client-side reactive dictionary).
    3. Local packages specific to your app, which are stored in /packages
    4. Third-party packages available at Meteor’s online package repo, AtmosphereArchived Link. These are named in the author:package convention.
    5. NPM packages in Node.js. They aren’t listed with other Meteor packages, but can be imported and used by other Meteor packages.

    Meteor has some special directories:

    • /.meteor/ is where Meteor stoes its own code. Don’t modify it.
    • Code in /server only runs on the server
    • Code in /client only runs on the client
    • Everything else runs in both places
    • Static assets should be stored in /public (The exception is CSS. Meteor automatically loads and minifies CSS, so it should be stored in /client)

    Meteor loads files in a specific order:

    • Before anything: Files in /lib
    • After everything else: Any files named main.*
    • Everything else is loaded in alphabetical order by file name.

    Deployment

    • To quickly set up a staging server, you can create a Meteor account and deploy to a Meteor subdomain for free:
     $ meteor deploy yourappname.meteor.com 
    • For deploying to your own server, check out Meteor Up, a command line utility that automates setup and deployment for you.

    404 Error Pages

    • Making a 404 error page isn’t enough, you have to tell Apache where to find it. I’m used to working on WordPress, which takes care of that automatically. Turns out I’ve been running this site for a few months without my 404 page working. Whoops!
    • To do so, add ErrorDocument 404 /404.html to your .htaccess file. Replace /404.html with the path to your 404 page.

    Secure Hash Algorithms

    What are they and what is the difference between SHA1 and SHA2?

    • SHA stands for Secure Hash Algorithm. The short story about how is works is that a mathematical operation is run on a given input and a unique output, or hash, is generated. By comparing the output to an expected output, you can verify the data’s integrity. The theory is that no two different input values should result in the same hash output (called a collision).
    • SHA1 algorithms produce a 160-bit hash value, while SHA2 algorithms can produce 224, 256, 384 or 512 bit hash values depending on the function used.
    • The very short explanation is that SHA2 hashes larger and are theoretically much less likely to have a collision than SHA1 hashes due to the underlying algorithmic changes.

    What is it used for?

    • Generally, SHA is used for verification. If the hash you calculate matches the expected result, your data has most likely not been tampered with or corrupted.
    • Git uses SHA1 to verify data has not changed due to accidental corruption.
    • SHA is used to sign SSL certificates.
    • Bitcoin uses SHA2 to verify transactions
    • SHA2 is used in the DKIM message signing standard (i.e. what checks to make sure someone isn’t spoofing your email account)
    • Some software vendors are adopting SHA2 for password hashing.

    Why should I care?

    • SHA1 is on its way out. Chrome is showing errors on sites with SHA1 SSL certificates that expire past Jan 1, 2016. All major browsers will stop accepting SHA1 SSL certificates by 2017.
    • Every site using SSL signed with SHA1 needs to update their certificates.
    • Most certificate authorities have instructions for migrating to SHA2.
  • Readable Code Snippets, VPN Clients, and Privacy


    Today I learned:

    Making code snippets prettier

    • I did some research for Sean Nelson about making code snippets prettier without using Github’s Gist.
    • This problem is already solved. Google’s Code Prettify is javascript that works parses your code pretty well and colors it.
    • Put the prettyprint class on your
      
      

      tags and put this script in your document:

    "https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js">
    • I might start using this for my code snippets in the future. Right now I have some CSS styles that conflict with it, so I need to sort those out first.

    VPN Connection issues


    Privacy Policies

    I’ve been having a lot of discussions about privacy and data collection recently, both at work and with friends. This episode of What’s the Point on privacy with Kashmir Hill cleared up some common misconceptions. The main points:

    • If a company’s fundamental business model is collecting data and figuring out things about you (i.e. Google and Facebook), they aren’t selling your data, but rather selling access to your attention to advertisers. They don’t want to give up your data to other people because it is such a valuable resource to them.
    • Some companies who sell you physical products have a side-business selling data on what you bought and when to others.
    • Privacy has become a genuine concern for companies recently, as evidenced by the rise in end-to-end encryption in consumer products like iMessage. This is worrying to some government agencies.
    • If you read privacy policies, they actually tell you all the ways a company is going to violate your privacy. As long as a company doesn’t do anything they didn’t say they were going to do, they are protected.
  • Photoshop Patterns, Homestead Provisioning, Composer Basics


    Today I learned:

    Tiling Photoshop Patterns

    I’ve been making some patterns for the header images on these TIL posts in my down time the past few days. There are two ways to tile patterns in Photoshop. One is manual and time consuming, the other is fast, easy, and less prone to error.

    • The manual, time consuming way is to open a pattern in one layer, duplicate the layer multiple times, and move the layers so that they line up in a tiling pattern. While PS is pretty great at snapping items to a grid, sometimes they don’t always line up and you only find out after you export the image.
    • The fast and easy way is to open the pattern in PS, go to Edit > Define Pattern…, then use the Pattern Stamp Tool to paint the pattern you just created across a large canvas.

    This would have saved me a lot of time on the first nine headers, but c’est la vie. This will definitely save me time going forward.


    Homestead Provisioning

    I use Laravel Homestead for my local PHP environment. Provisioning a new site is something I’ve done multiple times, but I do it so infrequently that I have to look it up each time. So here are my quick notes:

    • Create the site folder in ~/Projects/
    • Map the folder and domain in ~/.homestead/Homestead.yaml
    • Map the domain to 192.168.10.10 in /etc/hosts/ (reminder: $ sudo nano /etc/hosts/)
    • Run $ cd ~/Homestead
    • Run $ vagrant up --provision or $ vagrant reload --provision if vagrant is already running.
    • Site should now be accessible locally.

    If you need a new database for this site and load it from a SQL dump:

    $ vagrant ssh $ mysql -u homestead -p -e 'create database DBNAME;' $ mysql -u homestead -p  DBNAME < path/to/file.sql

    Composer Basics

    Composer is a dependency manager for PHP. I’ve used Composer, but like Homestead provisioning above, I’m a little rusty. Writing it down helps me remember.

    After you’ve installed it (I have it installed globally), the basic usage is:

    • Set up composer.json in the directory you are working on. A basic structure looks something like this:
    {     "require": {         "ajt/guzzle-toggl": "^0.10.0",         "corneltek/getoptionkit": "~2"     } }
    • In that directory, run $ composer install to install the dependencies listed in composer.json. They will be in a file called vendor.
  • Automating Drudgery, Project Planning, Parent Selectors, and Find and Replace


    Today I learned:

    Automating the tedious parts of these TIL posts

    When writing these TIL posts, I want to eliminate as much resistance as possible so I can get straight to writing. The more steps I have to take, the less likely I am to follow through. So I took some time today to automate the one of the tedious parts: Setting up the markdown file I write these posts in with most of the specs already filled out.

    I created 3 TextExpander snippets to help with this process:

    • One with today’s date string and extension separated by dashes for the file name: %Y-%m-%d-.md (I tried a fill-in for the title, but the filename doesn’t stay selected in Coda when another window launches)
    • One with Javascript randomly picking one of the 7 default header images I use (this is used in the next snippet):
    var random = Math.floor(Math.random() * 7) + 1; TextExpander.appendOutput(random + ".jpg");
    --- layout: post title:  author: Chuck Grimmett date: %Y-%m-%d category: TIL feature-img: "/img/defaults/%snippet:;random-img%" tags:  -  excerpt: 

    ---

    Better Project Planning

    Besides for the normal scope, budget, platform, dependencies, timeline, and underlying technologies, here are a few things you need to consider when architecting and planning out a software development project:

    • After delivery, what resources will we have available to maintain the system and handle emergencies?
    • What impact will maintenance and support have on our ability to sell and develop new projects in the future?
    • What is the opportunity cost of using one developer over another?

    Parent Selectors in CSS

    There are no parent selectors in CSS.

    There are two ways around this:

    1. Use the jQuery parents() selector to return the appropriate parent element, then use the css() method to set the style you want. For example, ("a i").parents("li").css({"margin-right": "5px"}); finds list items who are the ancestors of icons wrapped in links and makes their right margin 5px.
    2. Change the structure of your code and add specific classes that you can apply your desired styles to. For example, instead of applying a right margin to all list items and then a different right margin (via parent selector) for all list items that contain icons, make two classes with the proper margins and apply one to the plain list items and the other to list items that contain icons.

    I opted for #2. It makes your CSS cleaner, keeps you from having to load new dependencies like jQuery, and keeps the styles in one place so you don’t have to search 6 months from now for where that extra margin is coming from. I’d only use the first option in cases where you have complex rules that can’t be accomplished by restructuring your code and/or adding classes to make your desired change possible.


    Project-wide Find and Replace in Coda

    I do the vast majority of my code-writing in Coda. I used to have to open up TextWrangler to do find and replace across multiple files, but apparently Panic added this feature into Coda sometime between v1 and v2.5. I got used to having to switch and didn’t look for it again until today.

    It is buried in the sidebar under “Find In” instead of in the regular find and replace bar, so I never saw it. You can search across open files, the entire site, or in a specific directory on your local machine.

    Find In is buried under the sidebar in Coda

  • Jekyll Upgrades and Liquid Templates


    Today I learned:

    Upgrading Jekyll from 2.x to 3.x

    • The upgrade itself is simple: In Terminal, run gem update jekyll. Use sudo if you run into permissions issues like I did.
    • If you use pagination in any of your templates, you’ll now have to add gems: [jekyll-paginate] to the # Plugins section of your _config.yaml or else your site won’t compile. This wasn’t necessary in 2.x.

    Making an index for my TIL posts in Liquid

    I wanted to have an index for my TIL posts that was organized in two ways: reverse chronologically and by tag. Here is how I’m handling that with Liquid:

    	### Recent TIL Posts 	 	 	 	--- 	 	### TIL posts by category 	 	{% for tag in site.tags %} 	  {% assign t = tag | first %} 	  {% assign posts = tag | last %} 	 	#### {{ t }} 	 	{% endfor %}

    Notes:

    • The general structure of the tags method comes from Joe Kampschmidt. I started searching when it didn’t work the same way as the categories method I wrote earlier.
    • This method for displaying tags works because I’m only tagging my TIL posts. Everything else goes into categories. If I were to tag other kinds of posts, I’d need to first limit by posts in site.categories['TIL']
    • Category names are case sensitive.
    • You can display raw Liquid markup without it rendering by wrapping it in {%raw%} and {%endraw%}.
  • Pull requests, scraping Reddit, and flexbox quirks


    Today I learned:

    How to contribute to an open-source project on Github

    1. Fork a project
    2. Make the changes, commit, and push back up to Github.
    3. Go to the repo on Github you want to propose a change to.
    4. On the page: Choose your branch. Compare and review. Create pull request.

    Pulling Reddit data with Python

    • Connect to Reddit and grab data with PRAW
    • Store the retreived information in a MySQL database with PyMySQL

    The above two items came together in one learning experience. I helped Seth Millerd debug a Python script he was working on (with considerable help from Eric Davis!Archived Link). It is the first public repo I’ve contributed to, and the first time I’ve made a pull request. We use git at work, but we use a shared repo model instead of the fork & pull model.


    Image scaling quirks with flexbox

    All about flexbox (CSS)

    Eric DavisArchived Link and I ran into a strange CSS issue where an image was scaling in a funky way when we resized the browser. The height was staying fixed while the width was changing, but there was nothing in the CSS setting a specific height.

    It turns out that one of the parent

    s had display: flex; flex-direction: column; specified for layout order purposes, and when we turned that off the problem went away. So then we went searching and the quick-and-dirty fix is wrapping the image in a vanilla

    . That is working for us for now, but I want to read through the W3 docs and see if there is something bigger we are missing or if this is a known bug.