Sitek

Software, Technology and More Stuff

Integrating WordPress into a Rails Application

Hi, first of all, this is the first entry on the Sitek Blog. As director I think write the first entry is the right thing to do. And the subject, well…, is because the event that finally led me to set up of this blog was this issue in particularity, how to integrate a blog into an existing Rails Application.

Well the story begin with the request of one of our customers to add a blog to he’s application. This application was developed over more than a year ago and it have while time in production, this request was an improvement. This application was made in Rails and perform a set of task in the business process of the company, isn’t  just a simple site web.

Obviously the easy way could be just set up a blog as an independent application and give to the client the URL to access. But, on one side, they want that the posts appear on their home page, and second the application all ready has he’s user authentication system. So have an other user administration system wasn’t  going to be the cleanest way to go.

So, basically I had two options. One, develop the blog functionality from scratch or use an all ready develop engine. First of all I do a little googling, to analysis my options and even so, the are some plug-ins for Rails like “act_as_blog”, it looks like just a lot of work that need to be done and yet in the end the final result its going to be at last in the best of the case a blog whit the basic functionalities that a modern blog has. In the other hand, we have this other engines all ready built an tested, with tons of options and functions. So definitely I went throw the built engine. The problem was now what engine? Basically here I go with two options, one WordPress, because I think is the most used, tested and therefore with more documentation and probabilities than some else run into this problem before. And the second option was mephisto, that is a blog engine written in Rails. The second one was my first option, mainly because of the programing language, but I didn’t find much documentation to integrate whit an existing application, even more the documentation page seem to be down. So I went to the WordPress option, and happily for me, I found a plug-in for WordPress to accomplish this task. The plug-in is: Rails Integration API son now I proceed to explain how to set up and configure this plug-in and the application, because is not berry straightforward.

Strategy of the plug-in

The basic idea, is use the authentication system of the external application to access the WordPress system, to accomplish this, first of all we need to have an anauthentication system that hold the logged-in user information into a session cookie on our application. This because when the user tray to access to WordPress, the plugin will try to read this cookie and determine if the user is all ready authenticated or not and the user information, as the user name, email, etc. In my case I use Restful-authentication but I think any other can do the trick.

Step 1. Set up WordPress

Set up WordPress, nothing fancy just standard installation. Just one thing, in my case I installed in a subdomain, in the documentation the example use different ports. In this case because the application is hosted in a shared server I can’t do this. But a subdomain work as well as a different port. So we are going to have our application in a domain like this: www.myapp.com, and the blog in this other: blog.myapp.com. (Just for make an example).

Step 2. Configure The Rails App

Well, to do this we need to install an other plug-in, but in this case is a rails plug-in: It, call’s Integration_API this plug-in is responsible to expose the configurations options, and user information to the other plug-in. At the beginning feels a little messy but when you see working all together is not that much. You install the plug-in just as usual from github, and proceed to the configuration part:

The first thing to do is add this lines to the environment file, you can add this to the enviroment.rb directly but, its cleaner if you use the config/development.rb and config/production.rb for obvious reasons.

enviroments/development.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:session_domain] ='.localhost.com'
 
# Constants for the Integration API
INTEGRATION_API_DEBUG               = false
INTEGRATION_API_SESSION_USER_ID_KEY = :persona_id
INTEGRATION_API_SESSION_ID_PARAM    = :id
INTEGRATION_API_CONFIG = {
  :login_url  => 'http://localhost.com:3000/login',
  :logout_url => 'http://localhost.com:3000/logout'
}
 
# For security:
INTEGRATION_API_REQUIRED_PORT       = nil        # Set to nil to disable
INTEGRATION_API_REQUIRED_HOST       = nil # Set to nil to disable

enviroments/productiont.rb

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:session_domain] ='.myapp.com'
 
# Constants for the Integration API
INTEGRATION_API_DEBUG               = false
INTEGRATION_API_SESSION_USER_ID_KEY = :persona_id
INTEGRATION_API_SESSION_ID_PARAM    = :id
INTEGRATION_API_CONFIG = {
  :login_url  => 'http://www.myapp.com/login',
  :logout_url => 'http://www.myapp.com/logout'
}
 
# For security:
INTEGRATION_API_REQUIRED_PORT       = nil        # Set to nil to disable
INTEGRATION_API_REQUIRED_HOST       = nil # Set to nil to disable

Ok, now I’m gone to explain my self, first, the line 1,

ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS[:session_domain] ='.localhost.com'

This line is important because we need to set the domain of the session cookie used by rails to store the global session[] array, if you see, there’s a dot at the beginning of the domain ’.localhost.com’ or ‘.myqpp.com’, is because with the dot we indicate to the browser than the cookie can be read from the domain or any subdomain applications. The second important thing is as you can see in the development config I’m using localhost.com instead of just localhost, this is because using the notation .com or .org as cookie scope is not valid to the browsers for security reasons and if we use .localhost, isn’t going to work. Of course to make localhost.com to be resolved we need to add a record to our hosts file (linux: /etc/hosts windows: C:\Windows\System32\drivers\etc\hosts) this issue take me a little while  to figure out what was the problem when I was testing.

The line 4 we specified the name of the id of the user we are using, this depend of the authentication system we are using, but it’s important as we well see way in the next lines.

The line 5 establish the name of the parameter we are going to use to send the session information, in most cases using the Resful notation is fine, so we leaved as :id.

And finally the line 8 and 9 it’s just for the WordPress to redirect when it needed.

Step 3. Test the integration_api, plugin.

Now that we configure the plugin we can go a head an see how it works. Wen we install the plug in it should create a controller named integartion_api_controller, this is the one that is going to do the magic. The first action we are going to test is config_info. In my case I’m using Rails 2.3.4 and it seam’s that is a little bug her, with the line

cookie_name = ActionController::Base.session_options[:session_key]

the main function of this line it’s to get the name of the cookie session of the application, I spend some time searching and doing some googling, but I couldn’t find the equivalent in my rails version. So in this case (i know this wasn’t the best solution but I can’t figure out a better one ) I hardcode directly the name of the session cookie like this:

cookie_name = “_myapp_session”

The session cookie name is configure in the config/envoroment.rb file as :session_key

After this little hack you can go to http://localhost.com:3000/integration_api/config_info and if your browser support rendering json objects, you should see the configuration options. This action is user by the WordPress plugin to determine some of the options that need to work.

The next thing is to test the user action, in this action we are going to retrieve the information of the logged in user. First of all we have to login into our application, next with the browser help we can go and check for the cookies stored, it should be there one named as we configured in the :session_key, for example, _myapp_session and should contain as value some weird encrypt data, something like this:  BAh7CCIKZmxhc2hJQzonQWN0aW9uQ29 , so for the test we can do something like this:

http://localhost.com:3000/integration_api/user/BAh7CCIKZmxhc2hJQzonQWN0aW9uQ29

In my case, again, I recive an error the first time. This was because a version bug to. In this case I do find a equivalent option. The problem is in a function named restore_session_user, this function has a line like this:

if ActionController::Base.session_store == ActionController::Session::CookieStore

so I changed for this other:

if ActionController::Base.session_store == CGI::Session::CookieStore

this one works with my rails version.

The next problem was, my user model name, as you can see in this function in the next lines, the code assume, my user model name is User, but in my case it was Persona, so I change this to, and boala, it works.

Now after this we finaly have our integration API working from the Rails Application side.

Step 4. Configuring the WordPress, Integration plugin.

Once we have been configured the plugin of rails, we can start to configure the WordPress plugin. First we install the plugin manually, following the instructions indicated by the author (the plugin is not available from the WordPress installation panel). Once the plugin is installed, we can go ahead and configure, when we access it, it is possible to get an error, this is because the default options are incorrect. The setting are very simple:

Integration API Settings
Integration API Settings
The more important parameter here is the API web service URL, this parameter is the controller of our plugin. The second two options can be marked or not depends of your needs, the first one is used to make WordPress automatically authenticate the user, and the second one is for the case when the user doesn’t exist, then the user would be created automatically.
At last in the inferior part comes a section to map the user attributes of our application with the users of WordPress, has the user name, complete name, email, etc. This is really useful, because it maintain the information consistency between our to user systems.
It’s important to, that before we save any changes to have validated and done all the tests explained in the last step. Other wise, if something goes wrong, we are not going to be available to make login into WordPress, in which case we are going to need to make a re installation of the plugin and start again.
If everything is OK after we save the changes and if we have our session open in the application, we are going to be logged in WordPress as the user on our application. It’s convenient to, create into our application an account that map’s to the admin account of WordPress, so we can use this account to make all the administrative task of the blog.

Paso 5. Add the posts to our home page

This step has to do a little more with the WordPress itself and their personalization an configuration options, so I don’t going to go deeply into this matter, but basically, the technique involves the use the WordPress API and a few php lines, next the script that I’m using to show the lasts post into my home page.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
	<?php wp_head(); ?>
	<div id="content" class="wideindex">
	        <?php if (have_posts()) : ?>
	        <?php while (have_posts()) : the_post(); ?>
			<div id="post-<?php the_ID(); ?>">
			<h2><a title="Permanent Link to <?php the_title_attribute(); ?>" rel="bookmark" href="<?php the_permalink() ?>">
				<?php the_title(); ?>
			</a></h2>
			<small>
	            <?php the_time('F jS, Y') ?>
	            <!-- by  -->
	        </small>
			<div class="entry">
	                <?php the_content('Leer el resto del documento &raquo;'); ?></div>
					<?php the_tags('Etiquetas: ', ', ', ' '); ?>
	                Publicado en
	                <?php the_category(', ') ?>
	                |
	                <?php edit_post_link('Editar', '', ' | '); ?>
	                <?php comments_popup_link('Sin comentarios &#187;', '1 Comentario &#187;', '% Comentarios &#187;'); ?></div>
					<?php endwhile; ?>
			<div class="navigation">
			<div class="alignleft">
	                <?php next_posts_link('&laquo; Entradas antiguas') ?></div>
			<div class="alignright">
	                <?php previous_posts_link('Entradas nuevas &raquo;') ?></div>
			</div>
	<?php endif; ?>
	</div>

Finlay, putting this file into the root of WordPress, what we are going to have is the last entries of the blog, without the navigation bars and menus. You can find more information in the Codex de WordPress page. This segment can be rendered inside an iframe in our home page for example and even it would be rendered using the style and css of our application.

Conclusion

Even so, it wasn’t easy and you have to do a lot of hacks, it’s better than make a blog from scratch for our application. In the other hand, ones is working, everything is very transparent for the user, and as result we end with blog with a lot of options and tools as WordPress.

I hope this information to be helpful for other people that can run into a problem similar to this.

3 Responses to “Integrating WordPress into a Rails Application”

  • I used to be very happy to seek out this site.I wanted to thanks for this nice learn!! I definitely enjoying every little bit of it and I have you bookmarked to take a look at new stuff you post. Anyway, in my language, there are usually not a lot good supply like this.

  • dermajuv says:

    You really know how to grab people attention because when I started to read I wanted to know what will be in the end.

  • Interesting article. Gratefull and looking forward to more.

  • Leave a Reply