Inheriting and Mounting Stacks

One of the useful things about Pancake is that you can inherit your full application. This includes routes, bootloaders, configuration, paths and a few other things I won’t expound heavily on here.

What I want to go through is how to use it. Before we get started, make sure you have at least pancake 0.1.20

Since my initial post, Jack Dempsey has written a small test blog for Pancake. It’s not going to upset wordpress at this point (maybe one day), but it will serve to demonstrate inheriting and mounting gem’d stacks. The test blog stack is at http://github.com/jackdempsey/pancake-blog

Install Pancake-Blog

$ git clone git://github.com/jackdempsey/pancake-blog.git
$ cd pancake-blog
$ gem build blog.gemspec
$ gem install blog-x.x.x.gem

Once we’ve got the blog gem installed in the system, lets do the bare minimum to get it running in a container app. Move to another directory:

$ pancake-gen micro blog_container
$ cd blog_container

In pancake, you can progressively add directories of a larger app and they will just work. Lets setup a config.rb file and include an AR connection.

$ mkdir config
touch config/config.rb

Here’s an example of what you can put in there to get the connection setup.

require 'activerecord'
require 'blog'

ActiveRecord::Base.establish_connection(
  :adapter  => "mysql",
  :username => "root",
  :password => "",
  :host     => "localhost",
  :database => "pancake_blog_development",
  :encoding => "utf8"
)

You’ll notice here that we’ve also included the blog gem. Next lets mount the blog in the application. Lets get the blog_container.rb file looking like this:


class BlogContainer < Pancake::Stacks::Short
  add_root(__FILE__)
  initialize_stack

  router.mount(Blog, "/blog")
end

Initializing the stack will load the config file and mount applications etc. That’s almost it. Before we actually fire it up though, we need to create the database.

$ rake -T
$ rake blog:bootstrap

Pancake will load the rake files from the gem and make them available to you once we’ve mounted the Blog in the router. Now we can start the application :)

$ unicorn -p 5000 

Head over to http://localhost:5000/blog and you should see a shiny new blog. Enter a few posts and you can see it’s a very very simple app.

Inheriting Stacks

It’s kinda cool that we can mount an app and stuff. But inheriting full apps could be a bit cooler. Lets get that happening. Lets get the blog_container.rb file looking like this:

class BlogContainer < Pancake::Stacks::Short
  add_root(__FILE__)
  initialize_stack

  get "/" do
    render :root
  end
end

class WagyuBlog     < Blog; end
class VegetableBlog < Blog; end

BlogContainer.router do |r|
  r.mount(WagyuBlog,      "/wagyu")
  r.mount(VegetableBlog,  "/veggies")
end

We’ll also need to add this to the bottom of the config/config.rb file.

Blog.initialize_stack

This makes sure all the models in Blog are loaded before we inherit.

Ok, so lets start up the app again (with unicorn) and head over to http://localhost:5000/wagyu Aaaannnddd… The posts from before have disappeared… That’s actually intentional. It’s done that way in pancake-blog so you can mount multiple blogs in the one process without clashing the posts.
The model Blog::BlogEntry (the post) is inherited along with Blog so we end up with WagyuBlog::BlogEntry and VegetableBlog::BlogEntry. By doing this we’re segregating the data via STI.

Try it… Go to http://localhost:5000/wagyu and make some posts. Now scoot on over to http://localhost:5000/veggies and put in some posts there. Flip about a bit and you’ll see it’s actually separate.

That’s kinda cool, but we can do better. It’s not much good to have them all behaving the same all the time, and having all the stuff in the blog_container.rb file isn’t the most awesome. Lets mount them through the mounts directory. Create a “mounts” directory and a sub-directory for each blog:

$ mkdir -p mounts/wagyu-blog
$ mkdir -p mounts/vegetable-blog

Now, lets make the blog_container.rb file look like this by removing the inherit calls:

class BlogContainer < Pancake::Stacks::Short
  add_root(__FILE__)
  initialize_stack

  router do |r|
    r.mount(WagyuBlog,      "/wagyu")
    r.mount(VegetableBlog,  "/veggies")
  end

  get "/" do
    render :root
  end
end

Now, lets create a pancake_init.rb file in each of the sub-directories in “mounts” In them, we’ll put


# mounts/wagyu-blog/pancake_init.rb
class WagyuBlog < Blog
  add_root(__FILE__)
end

# mounts/vegetable-blog/pancake_init.rb
class VegetableBlog < Blog
  add_root(__FILE__)
end

Start the applciation again. You’ll see that the behavior is the same as doing it the other way. So, what exactly did that buy us? We’ve added a root to each of the blogs. That means we can start tweaking the views and add models / other files etc. We’ll just do one, but it will work for either, or both.

If you look at the pancake-blog source. You’ll see that the view inherits_from :base. Lets replace the base of the wagyu blog. Make a views directory in mounts/wagyu-blog/views and create a base.html.haml file. erb and erubis works just as well. Create your template, remember that you need to create a content block for at least :content (because of the child template in pancake-blog) That means you’ll need something like:


# snip template stuffs
- content_block :content do 
  %p
    No Posts Found

# snip

When you’re playing with templates, it’s a good idea to restart the app with shotgun so that the templates are re-compiled on each request.

shotgun -s thin -p 5000

I’ve made my mounts/waygu-blog/views/base.html.haml look like this:

!!!
%html
  %title A blog about Wagyu

  %body
    %h1 A Blog about Wagyu

    - content_block :content do
      %p
        No Posts Found

    %hr/

    .footer
      Here's My Footer

Not a very dramatic template I know, but you can see that it’s different when you render it. The VegetablesBlog at http://localhost:5000/veggies and see that it’s still the same as it was before we modified the templates for the WagyuBlog.

You can change any and all of the templates as you see fit for each inherited mount individually. You can even add a common root to both of them (or the parent class) and tweak there to have it affect both of them.

About these ads

One Response to “Inheriting and Mounting Stacks”

  1. Pancake’s Console « Pancake Says:

    […] Pancake Tasty Tasty Pancake « Inheriting and Mounting Stacks […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

%d bloggers like this: