SyntaxHighlighter

Thursday, June 18, 2015

Create a Github Project Page with a Custom Domain

I found the instructions on Github to be a little difficult to understand at first as they covered all possibilities.  It turns out to be very easy to create a static website on github and attach a custom domain.

From the top:

For Github

Create a directory on your mac to hold your sites locally - I called mine /pages.

Create a repository on github, it doesn't matter what it is named, but pick a name that will match your domain at some level.

Clone the github repository from your pages directory.

git clone git@github.com:github-username/repository-name.git

Go into that directory.

cd repository-name

Create a new branch called "gh-pages".  Use this command:

git checkout --orphan gh-pages

In this directory, create a text file named "CNAME".  Put the url of the domain in it.  That's the only content.  Include the subdomain.  For example: www.example.com

Create a file called "index.html".  Just to have something there to see.  Put whatever you like in it.


Hello!



Commit and push this to github.

git add .
git commit -m 'First commit'
git push

Multiple domains?

Just add another repository and follow the same path.

For your registrar

At your registrar, forward your Apex domain to a subdomain, like www.  At godaddy, this was easy enough.  Choose forwarding when managing your domain, choose 301 (permanent) and enter the entire host (www.example.com).

Edit the zone file - create a CNAME where the subdomain ('www' in this case), points to this domain:

github-username.github.io

Multiple domains?

All domains hosted on github (if you have others) will have a CNAME in the zone file point to the same location at github.io.

Finished!

Wait a little while - at godaddy is was only a couple seconds.  At 101domain.com it took over 24 hours.

Whenever you push your site to github, you will see your updates.

One more thing

Forwarding email

There was one more thing I wanted.  I wanted an email at that domain to forward to my personal email.  So I could temporarily use it and post it on the site.

In Godaddy, there is an easy enough way to forward email.  I used these instructions.  Note, you probably don't need to change the MX records.  I didn't, I just created the forwarding email address and made it a "catch all".

Testing email

And, lastly, you can't test it from the email address you are forwarding to.  This means you need a 3rd email address to test from.  That took a little while to figure out.


Wednesday, September 10, 2014

Heroku Hipchat deploy hook

If you have a heroku account and want to post your latest update to HipChat, here's something to go by:

First you need an Auth Token, you get this in Hipchat, you need to be a Group Admin.  Just click on the Group Admin tab and select 'API'.

Then, create a 'notification' token.  Make sure it is an API1 (not API2) token.

heroku addons:add deployhooks:hipchat \
    --auth_token=YOUR_AUTH_TOKEN \
    --room="ROOM_NAME" \
    --message="{{user}} deployed {{app}}\r\n{{url}}\r\n{{git_log}}" \
    --app=APP_NAME


Saturday, March 22, 2014

Collect funds for your group projects

I've been working on a project to help classrooms at my son's school collect funds for end of year gifts, team dues, etc. It's called Sidejar, and it's been working really well. It's motivating to hear the comments from the parents that would not have donated without a credit card interface.

"I love the convenience of this site. Thanks for coordinating and for the reminder!"

It's somewhat obvious, if you think about it, the more convenient it is to pay, the more people pay. It's been especially great to see it used by parents and teachers. It's a great cause to contribute too. Teachers give so much of their personal time and money, it's great for parents to have a chance to show their appreciation.

Sidejar - Money between Friends

Given a string to build a Rails object relationship

In situations where you want to take in a string - like when you are taking the results of an autocomplete, to form a relationship with another object - this is a pattern I like to use...

For example, say you wanted to credit an article to an author. There are many authors in the system, and their names are known. You might want to edit an article and change the name of the author...

In that situation, to build the relationship with the author (and set the foreign key), it takes a little effort to find the author by name, if he's not there, create a new author using the entered name.

attr_accessible :body, :title, :author_name
attr_accessor :body, :title, :author_name

before_validation :set_author
after_initialize :set_author_name

def set_author_name
  self.author_name ||= author.try(:name)
end

def set_author
  self.author = Author.where(:name => author_name).first_or_initialize
end

Friday, August 02, 2013

Cookie Collection Objects

Web developers will often have situations where we want to store something, usually a collection, temporarily - like the last few pages a user has visited, or a list of things to compare.  In my case, I wanted to store recent restaurants - pages the user visited, so they could return to them later.  This is often accomplished with cookies, but this is a way to hide the cookies and simply interact with the collection.

Using cookies to store and retrieve

At it's simplest, a cookie collection object needs to do the following.

Add items
Retrieve all items

In this example, I want to be able to show a list of recent restaurants on the side of the page.

Do do this, I would like an interface that allows me to add a recent restaurant.

 recent_restaurants.push(@restaurant)

Or, to retrieve recent restaurants...

 recent_restaurants

I'd like to avoid making direct calls using the 'cookies' hash, instead interact with the collection and hold the list between requests in the cookie.

With a CookieCollection class, we can use this to handle the common additions and deletes.  We also get all the power that comes with the Array class.  This class is meant to be subclassed.

class CookieCollection < Array

  attr_accessor :ids

  def initialize(cookies)
    super(0)
    @_cookies = cookies
    if @_cookies[cookie_name].present?
      self.ids = @_cookies[cookie_name].split(',')
    else
      self.ids = []
    end
  end

  def push(object)
    super(object) 
    update_cookie
  end

  private

  def update_cookie
    ids = map(&:id)
    @_cookies[cookie_name] = {:value => ids.join(','), :expires => 20.years.from_now}
  end

  def cookie_name
    self.class.name.parameterize
  end

end

Note - the cookie value is only the ids of the object.

In a RecentRestaurants subclass, we can make the specific updates to our list of recent restaurants. In this case, I wanted to limit my list to the last 5 items.

class RecentRestaurants < CookieCollection

  def initialize(cookies)
    super(cookies)
    self.ids = ids.last(5)
    ids.each{ |r_id| push(Restaurant.find(r_id)) }
  end

  def push(restaurant)
    delete(restaurant)
    while length > 4
      delete_at(0)
    end
    super(restaurant)
  end

end

In the application controller, I exposed a helper method to allow access to recent_restaurants

 
  def recent_restaurants
    @_recent_restaurants ||= RecentRestaurants.new(cookies)
  end
  helper_method :recent_restaurants

And then, in a view or controller, you can easily do things like

class RestaurantsController < ApplicationController
  def show
    @restaurant = Restaurant.find(params[:id])

    # Add a restaurant
    recent_restaurants.push(@restaurant)

    # Access all recent restaurants easily
    recent_restaurants
  end
end

This cleans things up quite a bit and makes it easier to work with in a consistent way.  It could easily be extended to be used with Sessions, as well.

Monday, July 29, 2013

A Bookmarklet for switching between localhost and production

If you are often going between production and localhost:3000 - you can easily change the domain name with a simple javascriptlet - something like this...

javascript:a=document.location.href.match(/http:\/\/([^\/]+)\/(.+)/);if(a[1].match(%22exampledomain%22)){document.location=%22http://localhost:3000/%22%20+%20a[2]}else{document.location=%22http://www.exampledomain.com/%22%20+%20a[2]}

 Make this the content of a bookmark, and add it to your bookmark menu.  Easy flipping.

Adjust further if you need to go between a staging environment or another localhost domain.

Tuesday, July 05, 2011

Set a default expires_in value for memcache

I bet there is an easier way to do this, but here's what I came up with. I didn't want to cache items forever (which is the default with memcache and rails). I wanted to cache items for 6 hours, max. To do this, I wrote a patch and if the :expires_in option is missing, it will set it to 21600. I would love to hear if there is a better way...


module ActiveSupport
module Cache
class Store

private

# Original code from ActiveSupport::Cache::Store
#
# def expires_in(options)
# expires_in = options && options[:expires_in]
# raise ":expires_in must be a number" if expires_in && !expires_in.is_a?(Numeric)
# expires_in || 0
# end

def expires_in(options)
expires_in = options && options[:expires_in]
raise ":expires_in must be a number" if expires_in && !expires_in.is_a?(Numeric)
expires_in || 6.hours
end

end
end
end

Monday, May 02, 2011

Brew/RVM/PSQL/Bundler Installation for a MacBook Pro

Install XCode - if you do this from disc, you'll need to upgrade later (version 3.2 that comes on snow leopard disc has bugs). You can download and start with the new one. It's 3.2 GB and could take a while to download. Do this first.

Install Brew. Follow the instructions here (https://github.com/mxcl/homebrew). I used the ruby script. If you have permission errors, you may need to do the following:

sudo chown -R $USER /usr/local


If you're OK, then install git

brew install git


If you have errors at this point, it may be due to XCode not being installed properly.

brew install postgresql

If you have an older system you may run into conflicts. Try 'brew doctor'

Follow all the instructions that show up after the postgres build. This will force the db to start up right away and set the psql function so you can access the db from command line.

# install rvm

bash < <( curl http://rvm.beginrescueend.com/releases/rvm-install-head ) # The first time you install RVM, you must put the following line into your ~/.bash_profile at the very end, after all path loads etc: [[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # This loads RVM into a shell session. # Add ruby rvm install 1.9.2 rvm install 1.8.7 rvm install ree For each project, create a .rvmrc file - this goes in the root of the rails app directory. More Show hidden files on your mac defaults write com.apple.Finder AppleShowAllFiles YES restart launcher

RVM configuration


.rvmrc files - add ruby version and gemset per project

gem install bundler - bundler should be a gem that you can access from any rvm configuration - used to generate Gemfile and Gemfile.lock.

* rvm instructions for 10.10 http://giantflyingsaucer.com/blog/wp-trackback.php?p=1792