No Wonder Rails Is Default in Mac OS X Server...
February 26th, 2008 — 3:47 pm —So I thought it was pretty cool Rails and Ruby were included by default in Mac OS X Server 10.5. We upgraded our Xserve last Thursday. A bit of work for me but that’s only because I forgot Rails was included by default and I caused myself some headaches working against that. So today I was working with Podcast Producer (the reason for upgrading to 10.5). Looking through some log files I thought they looked eerily familiar. Then I noticed a reference for .rxml. A look at some other logs showed mongrel_rails. Turns out Podcast Producer is a Rails app. The heavy lifting of encoding is done by Xgrid but still a cool use of Rails nonetheless. And now you know too :)
By the way, my one pet peeve with 10.5 was that getting Apache 2 to set-up proxies and rewrites is basically impossible from the GUI especially when they should know you need that stuff to deploy a Rails app. Now I understand that it wasn’t necessarily Apple saying, “Wow, a cool segment to serve.” but rather “Well, we need Rails here anyway so why not advertise it?”
Good News: An Open Sourced slate Is Coming
February 13th, 2008 — 9:30 am —For the last few months we’ve been working with the appropriate groups at the University to work out if we can really open source slate and, if so, what license we’d release it under. Yesterday we got official word that we can go forward. Yay!
The License: WVU Open Source License
I’ve just done a post for this so you can review the license yourselves. As I note in the post (for those to lazy to click the link) our license is based on the Illinois Open Source License which seems to be a derivative of the MIT License. I know it seems a little odd at first but review it and you’ll see it’s what most Rails folks are used to.
The Plan for Open Sourcing slate
Ok, I’m being a bit of tease by not providing a date but we’re in a bit of flux in the department at the moment so it’s tough for me to pick a date and be positive we can deliver. Stay tuned for a more exact release announcement in that vein. Much sooner rather than later though.
The version we’ll be releasing will be most likely be v0.5.1. This assumes we put the new release on our hardware first, find some bugs and fix them before releasing it into the wild. We’ll do an announcement on here for a release candidate of v0.5.1 and then go wild with a marketing blitz for the final edition.
v0.5.0 is a complete rewrite of slate based on all the stuff we’ve learned. The big fixes Chris has covered are making sure their are ways for folks to customize necessary parts (e.g. account authorization) and to create plugins to add their own functionality. It won’t be exactly like what you’ve seen in the screenshots so far.
Some Tech Details
Just in case folks want to check out some of the tech we’re using in the next release of slate.
- We’re running a self-contained version of Rails so once you download slate you’ll have the correct version within slate to run it. It’s essentially Rails 2.0.2.
- The plugin architecture is based on Rails 2.0’s plugin locator feature
- ImageScience for image manipulation
- jQuery as our JavaScript library
- RSpec for testing
- css_dryer for dynamic stylesheets
- attachment_fu for uploads
- slightly hacked implementation of jamis buck’s routing tricks
Conclusion
You’ll be hearing a lot more from us over the next few weeks as we put in place the infrastructure to support the open sourcing, get documentation online, and actually make the big announcement. We promise not to completely disappear again :)
The WVU Open Source License
February 13th, 2008 — 9:10 am —Below is the text for the license that we’ll be releasing slate under. It is based on the Illinois Open Source License and was developed and approved by the WVU Research Corp.. It’s in the same vein as the MIT license that most Rails folks are used to. Feel free to ask us questions or give us feedback. I’m not saying anything will change but if there’s a major concern we’ll get it reviewed by the WVU Research Corp.
If you’re a developer at WVU and you’d like to use this license you need to contact the WVU Research Corp. and not just copy what you see here. They need to review your product first, give you a written letter of authorization, and you need to be in a position to supply statistics of usage.
Not trying to scare anyone at WVU with the above. I can give you a contact if you need it.
Open Source License
West Virginia University
Copyright © 2008, West Virginia University Research Corporation. All rights reserved.Developed by:
West Virginia University Web Services
West Virginia University
http://www.wvu.edu/Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (?Software?), to deal with the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimers.
- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimers in the documentation and/or other materials provided with the distribution.
- Neither the names of West Virginia University or West Virginia University Research Corporation, nor the names of its contributors may be used to endorse or promote products derived from this Software without specific prior written permission.
THE SOFTWARE IS PROVIDED ?AS IS?, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
Implementation idea: .do templates
December 3rd, 2007 — 10:05 am —It’s been awhile since I’ve posted, so: “Hello everyone!”
I’m tossing around a new idea for slate, and I thought I’d post it here to get some feedback. The idea revolves around the concept of “behaviors” for pages in slate. Please bear with me as this is going to be a messy post – the ideas are still swirling around my head.
Current implementation
First, some background information: when a request comes in, slate extracts the path and attempts to find a page matching the path. If it can’t find a match, it attempts to find a “behavior” matching the path. If that succeeds, the behavior is executed (which handles rendering the page based on the path).
The idea is that you assign a page, say blog, the blog behavior, and slate will now know that the page has certain routes. That is, /blog/2007, etc.
Well, that’s all well and good, but there are problems with this implementation. In short, it’s messy. It’s also confusing for the user. So, I’m planning on doing away with the current implementation, opting for something a bit easier to manage.
The .do template
The new idea is this: specialized theme templates, say blog.do.rhtml that handle the behavior without configuration. How will this work? When a request comes in, slate will check to see if the path contains .do. If there’s a match, it will extract that portion of the path and render the associated template.
For example, /blog.do/1/2007 would render blog.do. I’m thinking there will also be a blog.do.rb file which will act as a pseudo-controller for handling these .do templates. Or, maybe the theme will support a blog.do directory, containing custom view templates. Obviously, the details haven’t been worked out yet ;-)
Pros and cons
- Pros
- Consistent URLs for behaviors (blogs will always reside at
/blog.do/:id) - Less configuration (no need to create a page and assign it a behavior)
- Consistent URLs for behaviors (blogs will always reside at
- Cons
- Less end-user control of (no more /something/blog)
- Slightly more ugly URLs
- How to provide editable areas for behaviour-driven pages?
Thoughts?
Clearly, this concept is still up in the air. But if you can understand at all what I’m going for, please feel free to post your thoughts :-)
Keeping slate Humming - Part 1
November 6th, 2007 — 12:51 pm —In the spirit of KYTCR article by John we’re offering some tips on what we do to manage our install. I’m not going to go into nearly the depth that John has already done and hopefully will continue to do. Why?
- We don’t do back-ups. Before you write to say we’re crazy, all the stuff related to slate is backed up. Just not by us so I can’t tell you anything about it.
- Problem analysis and resolution. This usually consists of some curses (if I’m around), gritting of teeth, whispers of “stupid users,” and eventual elegant solution courtesy of Chris.
- Log rotation. some time goes by “Chris, we might want to reset that production log.” We did try to automate this once but it blew up in our faces.
- Cache. We’re not exactly at a point where we have to be seriously worried about it.
The Hardware Setup
I was sort of surprised to find that slate is running on the smallest server we manage.
- The app server – a 3.2GHz Xeon box with 1GB of RAM running Windows Server 2003. It’s shared with a few low-use RoR apps and a PHP app.
- The database server – Multi-Xeon box with 2GB of RAM. We use Microsoft SQL Server for the DB.
Our Numbers
I made a post on this back on Oct. 4th. In the interest of giving up-to-date numbers I’ve redone them.
- From Oct. 5th to Nov. 4th we served 322,505 pages.
- From one install of slate we push out approx. 71 sites made up of:
- 3,850 pages
- 5,674 resources (user uploaded images, documents, etc.)
- 594 blog entries
- 39,746 comments with the vast, vast majority being spam
As a comparison, over the same time period the WVU home page had 1.86 million page views. Ok, with that background covered lets get into things we do to manage our install.
The Stack: Apache & Mongrel
We’re using Apache 2.2 with mod_proxy_balancer to proxy requests to a cluster of five Mongrel services to serve slate to the masses. I’ve written about our past experiences so I’m not going to rehash it too much. Nothing has really changed in a year. Suffice it to say we’re happy with the set-up and haven’t looked at anything more exotic. I also posted an article on the balance-manager. I’m not going to share our config but a couple of notes related to how we like to do things:
-
ProxyPassis better thanRewriteCondandRewriteRulefor serving static files. This is just my opinion. One of the great things with Rails is that it forces you into certain directories to deliver static vs. dynamic content. Why double-check? - Need to do a redirect? Make sure you’ve added it’s own
ProxyPass. We require SSL for the slate account login page. So if you request the unencrypted page you get bounced to the encrypted page. - Discourage access to .svn, .erb, or .rhtml files with
DirectoryMatchandFilesMatch. Since our themes are essentially public (for images and styles) and the templates are .rhtml files we’ve made sure to deny access to them. Not allowing access to .svn might be overkill but oh well.
<DirectoryMatch "\.svn"> ErrorDocument 403 /404.html Order allow,deny Deny from all Satisfy All </DirectoryMatch> <FilesMatch "\.rb"> Order allow,deny Deny from all </FilesMatch> <FilesMatch "\.rhtml"> Order allow,deny Deny from all </FilesMatch>
Rubykill: How We Manage Mongrel on Windows
I’ve never really taken the time to learn how to manage a Windows box properly. I’ve always focused strictly on software (e.g. PHP, Apache) and not the OS itself (others manage the OS). So when it became apparent that we were picking up more traffic and Mongrel liked RAM we had to find a solution to restart Mongrels just in case. The quick, dirty, and brute force solution? Rubykill.
Rubykill is just a scheduled task that takes out a Ruby process. We run it five times a night so essentially slate is restarted once a day. The significant downside to this solution is that you’ll get a proxy error for about 30 seconds before the proxy balancing kicks in. It takes about a minute for Mongrel to start back up again. In that time Apache realizes it’s out of commission and works around it.
And, yes, rubykill is overkill.
Working with RedCloth
Way back when I posted an article about slate and RedCloth/Textile. If you’re going to be using RedCloth for your markup and have a number of folks who will be using your system then learn from our experience. Read the article and then come back here for some more tips.
patiently waits
Ok, here you go:
- Change your code markup from one @ sign to two. If you don’t you’ll run into problems with folks trying to put email addresses on one line. It gets really funky. So, Ryan, that’s why you get @something@ in the comments instead of a code tag ;)
- People like dashes. We’ve had a number of folks submit comments to various blog articles and they’ve used dashes (e.g. trying to make an em dash). To RedCloth this means a strike-through and then people get a little huffy when their post has been supposedly “edited/censored.” Just be careful with this. I don’t think we’ve put a “fix” in other than making sure superadmins can edit comments in the next release.
- Use the Textile Editor Helper. Did you think I wouldn’t plug it? Check it out.
Next Article…
Chris will eventually follow this article up with one related to deployment and some of the stuff he’s done to future-proof slate a little. I’m not sure if there’s much more to really cover other than that. Let us know what you think.
Campfire for Design & Keeping Your Tag Cloud Running
October 31st, 2007 — 4:28 pm —I’m not usually into regurgitating links but two blog posts today that really caught my eye.
Behind the scenes at 37signals: Design
The post goes into some detail (and it’s supposedly the first in a series) about how Campfire helps the folks at 37signals with their design work. I was struck by how similar it is to how Chris and I use AIM. Though they’re passing files around and we don’t really do that. I had forgotten the subversion integration. I had tried to use Pyro for a bit but it lost out to ol’ reliable, AIM.
Keeping Your Tag Cloud Running: Intro
A post by John Nunemaker over at RailsTips.org. Looks like it’s the first in a series of posts on managing a growing Rails site. Nitty gritty server stuff which looks really cool. It’s inspired me to try to give a more abridged look at what we’re doing. There is some stuff (e.g. back-ups) which are magically taken care of for us by the technical elves in the data center so we don’t have info on it.
Considering it’s Halloween should I have said “ghouls and ghosts” rather than “elves”? Happy Halloween :)
Custom configuration settings made easy
October 29th, 2007 — 7:00 pm —I’m currently working on extracting some of the business rules and options from slate into a separate configuration block. My first stab at this involved creating a custom ConfigurationBuilder class and using instance_eval to get some fancy DSL working. But then I thought of a much simpler solution: a custom Hash class that supported method-based access to keys. That is, hash.some_key would be the same as hash[:some_key].
Turns out, this really wasn’t too complicated. The slightly tricky part was handling nesting: I wanted my configuration options to be grouped, such as passwords.min_length. All I had to do for this to work was override the default method for my custom hash class.
The end result is as follows:
require 'active_support' class Configuration cattr_accessor :settings # creates a new configuration object if # necessary def self.settings # !> redefine settings @@settings ||= ConfigurationHash.new end # returns the current configuration # by passing a block you can easily edit the # configuration values def self.config block_given? ? yield(self.settings) : self.settings end end # specialized hash for storing configuration settings class ConfigurationHash < Hash # ensure that default entries always produce # instances of the ConfigurationHash class def default(key=nil) include?(key) ? self[key] : self[key] = self.class.new end # provides member-based access to keys # i.e. params.id === params[:id] # note: all keys are converted to symbols def method_missing(name, *args) if name.to_s.ends_with? '=' send :[]=, name.to_s.chomp('=').to_sym, *args else send(:[], name.to_sym) end end end
Here’s an example of how it works (say, in the environment.rb file):
Configuration.config do |config| config.passwords.min_length = 8 config.passwords.ttl = 60 end Configuration.config.passwords.min_length # => 8 Configuration.config.passwords.ttl # => 60 # some alternate ways to access the settings Configuration.config[:passwords][:min_length] # => 8 Configuration.config.passwords[:ttl] # => 60
Just a note that the method chain can technically go on as long as you want:
Configuration.config.passwords.length.minimum = 8
This works because a new ConfigurationHash is created when you access a key that doesn’t exist.
There you have it – custom configuration settings made easy. One caveat: since this is all dynamic, if you spell a key wrong or provide an incorrect path, you won’t be getting the configuration setting you want. However, the trade-off is the ability to define new options instantly.
HOW-TO: Add a Gallery to Your Site
October 29th, 2007 — 4:47 pm —Wow, an article directed directly at our current users. That’s a little different for us. Today I had to write up how to add an image gallery to a site in slate so I figured I’d share it with everyone. Speaking of HOW-TOs I desperately need to update the ones that are already out there. Not enough time in the day. Which is why I’m writing a post ;) K, let’s get to it…
Setting Up Your Gallery
A gallery, in slate terms, just happens to hold albums which are what you’re really associating your images with for display.
- In slate go to ‘Files’
- Click on Images
- Create a set under Images called Galleries. You can give it whatever you description you want but you have to call the set Galleries.
Important: Note the ID in the URL for the Gallery set. You’ll need it at a later step.
Setting Up Individual Albums
Again, an album is what actually holds the images. So keep them topical to what you’ll be showing.
- Click on the set called Galleries
- You can create any number of sets under Galleries that correspond to the albums you want to create. So you could have Students, Event A… whatever.
Adding New Images to an Album
Refer to our article, HOW-TO: Organize Files in slate, in Trac. Specifically focus on the section ‘To Add Files to a Set’.
Adding the Gallery Listing to a Page in slate
By default, slate wants to push out a list of the albums you have in the set before it does it’s auto-magical stuff with creating your nice albums with slideshow.
- Navigate to the page where you want to add the album listing.
- Using the ID you noted earlier, put in the snippet: {{ Collection.collection_list collection_id=someid }}. You can add whatever text you need above and below.
Voila! You’ve just added an image gallery with multiple albums to your site. Note: Only a few sites have the appropriate styles and theme bits to show a gallery within their own look and feel. slate will show a nice default theme but if you want a more integrated feel for your gallery let us know.
JSONRequest.post Example
October 26th, 2007 — 4:08 pm —As I wrote in an earlier post we’re looking at JSON for one of our new features in slate. To quote the official JSON site, “JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate.” So far in playing with it I’d have to agree.
The one thing we’re doing a little differently (I think) is that we want to pass the JSON object from the page to the server as opposed from the server to the page. We’ll probably be doing the latter at some point though. Their is a proposal out there for adding JSONRequest to JavaScript proper. In lieu of it actually being there I messed around with a JSON JavaScript library from Andrea Giammarchi. While I worked with PHP for my example (it was just faster) and the JSON PECL package come Rails 2.0 to_json and from_json are both supported by default. Ready for an upgrade, Chris? ;)
So what did I come up with? This. Yup, a super cool method to reverse inputted text :) The JS code isn’t anything incredible:
//Show the info returned from the PHP script
function showJSONInfo(sn, response, error) {
if (response) {
$('revText').innerHTML = "<strong>It worked!</strong><br />Your text reversed: " + response.revText;
new Effect.Highlight('revText', {startcolor:'#ffcc00', endcolor:'#ffffff'});
}
else {
alert(error);
}
}
//Format and send the data to the PHP script
function getJSONInfo() {
var JSONInfo = {"normText":$('normText').value};
try {
JSONRequest.post("json.php", JSONInfo, showJSONInfo);
}
catch(e) {
alert(e);
}
}
Overall the library was pretty easy to use. I had to bang my head against a few things but that’s probably due to my own stupidity than anything else. A couple of things:
- While it’s noted that JSONRequest.js requires the associated error .js file it actually requires JSON.js and it’s associated error .js file as well. Maybe that should have been blindingly obvious to me but it wasn’t.
- I just dealt with the raw POST on the PHP side so, if you want to do the same, you might want to edit line 240 of JSONRequest.php to take out the var name.
- Make sure you’ve got the right content-type. I assume this isn’t a problem in Rails. It should be application/jsonrequest
- On the PHP side make sure you urldecode() that raw POST data. The decode may not be perfect so YMMV.
- Also on the PHP side (which is obviously where I had most of my problems) you can use arrays to hold your JSON data if you, like me, have no clue how to use objects in PHP. So it’s:
json_decode(urldecode($jsonData),true);
Note: I just started looking at JSON a few days ago so if I’ve rehashed things people already know or if I’ve gone into left field doing this ass-backwards feel free to let me know.
Miscellaneous
October 24th, 2007 — 3:29 pm —Just a collection of recent thoughts:
Feedburner Pro Now Free
If you’re taking advantage of Feedburner but didn’t want to shell out the cash for a Pro account it’s now free. This is kind of old news but if you didn’t know before, well, now you do. It’s interesting to see what’s clicked on.
jQuery UI Is Pretty Cool
So we’re looking to add a table builder to slate. Basically the pipes are too difficult for our users. I’ve been sketching out a number of ideas. I was even working on a draft version within our current snippet framework before realizing it wouldn’t work since we needed to render TEH within it. Now I’ve mocked up a crazy UI but I think it’ll be pretty cool. We’re looking at jQuery UI for our JS widgets. I also like the idea of using it for our new resource reorganize view. Be sure to check out the jQuery UI demos.
JSON Is Cooler
Keeping track of the data for each table cell in table builder I thought was going to be a bit of a nightmare until Chris showed me JSON. Used it a little bit and I’m really liking it. I had found a method to POST JSON data and I have to find that link again. Is that kind of thing included in Rails 2.0?
Some Uni Home Pages
During the day a co-worker forwarded me a link to the University of Oxford home page. Pretty cool, simple design. Make sure to click “This is Oxford.” Some more examples (and I’m strictly looking at design):
- Azusa Pacific University
- University of Nebraska-Lincoln really like this one
- Department of Spanish and Portuguese at UC Berkely just so unusual for a college/dept. page
- Humboldt State University simple
- Seattle University
- UMass Amherst
- Carnegie Mellon
- Cornell
- University of Notre Dame of course ;)
- « Older Entries
- Newer Entries »
About slate
slate is a content management system (CMS) developed using Ruby on Rails focused on rapid production of traditional websites created by WVU Web Services. Read more about why we created slate and a longer list of features of slate. You can also check out a list of sites using slate. If you have questions or comments let us know but if it's a question about open sourcing slate have a look at this article first.Archives
Recent articles
- No Wonder Rails Is Default in Mac OS X Server...
- Good News: An Open Sourced slate Is Coming
- The WVU Open Source License
- Implementation idea: .do templates
- Keeping slate Humming - Part 1
- Campfire for Design & Keeping Your Tag Cloud Running
- Custom configuration settings made easy
- HOW-TO: Add a Gallery to Your Site
- JSONRequest.post Example
- Miscellaneous
Articles