It’s easy to add a “url” or “slug” field to your rails app, and override the to_param function to report that field. A route can then look for an alphanumeric parameter, like this:
match "pages/:slug" => "purchases#show_by_slug"
But how to generate them without too much manual labour? [manual labour is a good thing, relying on well written gems is sometimes better]
I previously mentioned how simple it would be for Twitter to use OpenGraph to grab images off Instagram to restore the user experience removed when Instagram stopped posting image meta data to twitter.
Last week Instagram stopped posting direct image information to Twitter when you shared an image. It means that instead of seeing a picture inline with your tweets you need to click the Instagram link to load the image in a browser window. Most other image services use Twitter’s “media” tag to allow the image to be shown inline.
Instagram, now owned by Facebook, have clearly got a reason for doing this: whether it’s to do with tracking user activity more closely, a future addition of advertising on the Instagram pages, or to more closely integrate the Instagram web pages with Facebook.
Heroku have just introduced a limit on their free database of 10,000 rows. As their robots convert each of their Rails 3 apps to a new database architecture, any database approaching 10,000 rows will send out an email warning the user.
GiantsLive which is hosted on the new heroku Rails 3/Cedar platform a single ‘dyno’. If you don’t know what heroku is, essentially it’s a cloud web hosting platform, and one of it’s finest features is that your first 750 ‘computation hours’ in a month are absolutely free. Properly free, like a lunch at that church on Stranmillis Road on a Thursday.
Step 1 in the “Moving my blog” process is “Extract the current site’s data into a manageable format”
Frankly, that’s easy! WordPress has a functionality to export the site’s content to a single XML file containing all the published Categories, Tags, Posts, Pages and Comments. To do this (WordPress v2.9.2) click Tools > Export and save the file. In previous versions of the software I believe it’s under the Manage menu.
I’m aware I could import the data directly from the WordPress database (to wherever it goes in the end) but let’s imagine we can’t. Anyway, database access would be tediously slow and inefficient to test against and implement.
A quick google for “import wordpress xml ruby” threw up nothing helpful so I turned to the Ruby XML libraries. John Nunemaker “feverishly posts everything he learns” at railstips.org and has two articles of use here:
The latter deals with three different ruby xml libraries and compares their speed, ease of use and how nice their names are to say. He puts REXML, hpricot and libxml-ruby. I’ll save you the pleasure of reading the article (if you like) and ccv John’s summary:
“Libxml is blisteringly fast, [but] Hpricot has cooler name, REXML and Hpricot both feel easier to use out of the box”
And there you go. Hpricot it is!
Now to get the data into Ruby. After a quick glance at the rubytips article and The RDocs I put together this code as a starting point:
cats_hierarchy={}
(doc/"wp:category").each do |category|
cat_name = category.at("wp:category_nicename").innerHTML
cat_parent = category.at("wp:category_parent").innerHTML
if cats_hierarchy.include? cat_parent
cats_hierarchy[cat_parent] = cat_name
else
cats_hierarchy[cat_name] = []
end
end
cats = cats_hierarchy.to_a.flatten
That gives me two each to use Ruby objects each containing all of my category data: a hash which preserves the hierarchy of the structure and all the names in a linear array.
To get a ‘num_reqd’ array of random objects, you can use something like this.
named_scope :large, :conditions => ['image_file_name IS NOT ?', nil]
named_scope :small, :conditions => ['small_image_file_name IS NOT ?', nil]
def self.get(num_reqd,features_arr=[],size="large")
if size=="small"
collection = Feature.small
elsif size=="large"
collection = Feature.large
end
return collection if collection.size <= num_reqd
# num_reqd.times{feature=self.random(collection); features_arr.push(feature) unless features_arr.include?(feature)}
features_arr = collection.find(:all, :limit => num_reqd, :order => 'rand()')
if features_arr.size < num_reqd
return Feature.get(num_reqd, features_arr, size)
else
return features_arr
end
end
EDIT: It's much cleaner and easier to use something in the form below, though the following is probably useful in some cases and is possibly interesting as a code snippet.
User.find(:all, :order => 'rand()')
---- end edit.
Working from a baseline of the code found here at almosteffortless.com I've extended a 'random record grabber' to get a specific number of unique records from a Rails data table.
Basically - the random method makes a database call to get the ids of a table, and sends back a random entry. self.get is a recursive method which provides a 'total number required' and a base array to start from (if you wish to specify entries to appear in the otherwise 'random' list). First year computer science should help get your head around the rest!
def self.random
ids = connection.select_all("SELECT id FROM features")
find(ids[rand(ids.length)]["id"].to_i) unless ids.blank?
end
def self.get(num_reqd,features_arr=[])
num_reqd.times{feature=self.random; features_arr.push(feature) unless features_arr.include?(feature)}
if features_arr.size < num_reqd
return Feature.get(num_reqd, features_arr)
else
return features_arr
end
end
Be aware, there is more efficiency to be found in the database call (i.e. it should be cached). Also, you'll want to be sure there are at least 'num_reqd' items in the database.
The last few days I’ve been putting the finishing touches to the CMS behind Harry Ferguson Memorial.com. Initially completely in hand-coded HTML (to get it looking right without distracting myself hacking around in a CMS template styling system), it was time to choose a CMS to allow a certain amount of user updating to be done on the site.
I first experienced the Textpattern CMS through my participation in the TextDriveJoyent Mixed Grill “Venture Capitalist” life-time subscription. I was initially baffled by it’s usage of ‘forms’ ‘pages’ and ‘sections’ to categorise different design and structural hierarchy. Mostly using WordPress over the last few years onvarioussites and most recently developing a custom Rails CMS for the upcoming Bible Society of Northern Ireland website (note: current site is *not* of my creation) (launching in the next few weeks) I decided I needed to hunt around a bit. A quick play with Drupal left me unimpressed, I wasn’t going to touch Joomla (is it just me or does every site that uses it scream “look, it’s a site built using Joomla!”) and so I thought I’d take Textpattern out for another try.
Impressed by the fact it’s finally had an update (version 4.2.0 was released just a week ago (28th August) — after, I believe, a long hiatus — time to give it a spin once more.
Installation is pretty simple, quite lightweight; doesn’t require much in the way of configuration if you have a bog standard *AMP setup, just create or associate the database you wish to use (you can use a ‘_txp’ style suffix to append onto your existing DB) and create the .htaccess requested – it’s all explained on the linked instruction page.
I’m not going to do any sort of tutorial on the installation process, that’s been covered so many times, by so many people, I’d only do it a disservice. However, I have been using the YAB_Shop plugin, which is seriously lacking in documentation, with a 27 page forum post over at Textpattern.org. I’ll be putting together a few thoughts and instructions (which I found difficult to find) on the e-commerce plugin in the next few days and hopefully that’ll help someone out (and help me process and learn further!).
—-
Edit: I realise I didn’t really ‘review’ the experience, which I intend to do more so when I write about the plugin, most of my gripes are with the plugin workflow!