XML Import in ActiveAdmin (Part 1)
I’m currently working on a new home for the Podcast I’m co-hosting. Since I won’t be the only one posting on the page, Octopress isn’t really a choice. So I’m going with with Rails. The design is almost completely made with Twitter Bootstrap, Since design isn’t my strong suit, and I’m using ActiveAdmin for the admin interface.1 I’m thinking about making the finished app available for others, but at the moment I’m not really sure how exactly that will be. More about that in the future.
One of the troublesome things when moving a page is taking all the existing data with you. Our current side is running on Wordpress, which allows you to export your posts and pages as XML. In this post I’ll explain how we will put two little forms in the admin interface with which we can choose a file to import from, parse the XML and create our pages or episodes. In the next post we’ll see, if we can’t improve the parsing a bit.
Page Import
Let’s start with the page import.
To parse the XML we’ll use Nokogiri, which we need to add to our Gemfile:
gem 'nokogiri'
And run bundle install
.
Then we’ll create the partial app/views/admin/_import.html.erb
with the form we’ll use to initiate the import. The form should call the import_xml action, which we’ll write later, and should allow us to submit a file. Since Formtastic is already installed for ActiveAdmin, we might as well use it:
<%= semantic_form_for :import, :url => { :action => "import_xml" } do |f| %>
<%= f.input :file, :as => :file, :label => false %>
<%= f.actions do %>
<%= f.action :submit, :as => :button %>
<% end %>
<% end %>
Then we render the partial in a sidebar on our pages admin index2:
sidebar "Import", :only => :index do
simple_format("Import pages from a XML file.") + render("admin/import")
end
And now we need to write the action. The XML for your exported pages (or posts) you get from Wordpress looks something like this:
<channel>
<!-- Some stuff -->
<item>
<title>Impressum</title>
<link>http://www.talesofinterest.de/impressum/</link>
<pubDate>Wed, 22 Sep 2010 14:16:25 +0000</pubDate>
<dc:creator>code-chimp</dc:creator>
<guid isPermaLink="false">http://www.talesofinterest.de/</guid>
<description></description>
<content:encoded>A bunch of Important stuff</content:encoded>
<!-- Some meta stuff -->
</item>
<!-- Some more items -->
</channel>
What we need to do is take the title
and content:encoded
of every item
, create a new page with it and redirect to the pages admin index. In our app/admin/pages.rb
we do the following:
collection_action :import_xml, :method => :post do
items = Nokogiri::XML(params[:import][:file]).xpath("//channel//item")
items.each do |item|
Page.create!(:title => item.at_xpath("title").text, :content => item.at_xpath("content:encoded").text)
end
redirect_to admin_pages_path, :notice => "Pages imported successfully!"
end
That’s it for our page import.
Episode Import
If you have only one podcast and modelled your episodes like a blog post, it’s actually pretty straightforward, too.
We’ll be using the same partial but change the import_xml a bit, so that the created_at
stamp of our episodes equals the pubDate
. Let’s do that in our app/admin/episodes.rb
:
sidebar "Import", :only => :index do
simple_format("Import episodes from a XML file.") + render("admin/import")
end
collection_action :import_xml, :method => :post do
items = Nokogiri::XML(params[:import][:file]).xpath("//channel//item")
items.each do |item|
Episode.create!(:title => item.at_xpath("title").text,
:description => item.at_xpath("content:encoded").text,
:created_at => item.at_xpath("pubDate").text)
end
redirect_to admin_podcasts_path, :notice => "Episodes imported successfully!"
end
That is all.
In the following post I will show you, how the episode import could look like, if you app is structured a bit more complex.
Mainly because I used it a ton at work. RailsAdmin does look really cool, too. ↩︎
Note that it won’t actually work yet. It will return an error because we haven’t written the import_xml action yet. ↩︎