Ruby on Rails Integration With Wordpress

23,633

Solution 1

The older answers are not relevant anymore. WordPress now provides a Rest API which can be accessed here: https://developer.wordpress.org/rest-api/

1) You will probably want to integrate all routing (by taking the "slug" from the articles) in your rails app to serve the articles correctly and present them with a nice "show" view.

2) If you want to store data in the rails system (e.g. for routing and to increase speed) you could create a database table called wp_articles, simply read the full article list or update relevant articles, then present them similar to your normal code.

I've looked at the non-maintained MOMA gem (not required anymore, not maintained), checked the above answer with direct database access (huge effort, slower, outdated) and read about a slighlty complex direct javascript based solution here (http://marydickson.com/how-to-use-the-wordpress-rest-api-in-rails/), but I think that simply copying the relevant info into your system and then presenting them with the normal MVC process is the easiest way.

Disadvantages: Some additional WP-Plugins provide more database fields and other information and its not clear whether you can always access those via the API. So you might have slightly limited functionality.

Solution 2

This seems to be working for me (I'm loading from Wordpress as secondary database, hence the establish_connection() calls and overriding table_name. This should get most of the way there, giving you access to the Wordpress data as ActiveRecord objects. I haven't yet written the wrapper around Posts (WPPost) to make them a bit more user friendly from an API perspective, but this should work well for Rails-based display of Wordpress data.

class Term < ActiveRecord::Base
   establish_connection "wordpress-#{Rails.env}"
   self.table_name = "wp_terms"

   has_one :term_taxonomy
end


class TermTaxonomy < ActiveRecord::Base
   establish_connection "wordpress-#{Rails.env}"
   self.table_name = "wp_term_taxonomy"

   belongs_to :term
   has_many :term_relationship
end

class TermRelationship < ActiveRecord::Base
   establish_connection "wordpress-#{Rails.env}"
   self.table_name = "wp_term_relationships"

   belongs_to :post, :foreign_key => "object_id"
   belongs_to :term_taxonomy
   has_one :term, :through => :term_taxonomy
end

class Post < ActiveRecord::Base
   establish_connection "wordpress-#{Rails.env}"
   self.table_name = "wp_posts"

   has_many :term, :through => :term_relationship
   has_many :term_relationship, :foreign_key => "object_id"
   has_one  :postmeta

   # we only care about published posts for notifications
   default_scope where("post_type = 'post' and post_status = 'publish'")
end

class Postmeta < ActiveRecord::Base
   establish_connection "wordpress-#{Rails.env}"
   self.table_name = "wp_postmeta"

   belongs_to :post
end

I then wrap up the category in a simple ruby object that makes accessing the data easy:

class WPCategory
   attr_accessor :id
   attr_accessor :name
   attr_accessor :description
   attr_accessor :term

   def self.categories()
      categories = Term.all()
      categories = categories.select{|term| term.term_taxonomy.taxonomy == "category"}
      return categories.map{|term| WPCategory.new(term)}
   end

   def self.category(id=nil)
      if id
         term = Term.find(id)
         if term.term_taxonomy.taxonomy == "category"
            return WPCategory.new(term)
         end
      end
      return nil
   end

   def initialize(term)
      @id = term.term_id
      @name = term.name
      @description = term.term_taxonomy.description
      @term = term
   end

   def to_s
      return "Wordpress Category: '#{@name}' (id=#{@id})"
   end

end

Here's my database.yml (make sure that your db user has read-only access to the wordpress db to avoid any ActiveRecord mishaps):

test:
        adapter: mysql2
        encoding: utf8
        database: test-rails
        pool: 5
        username: test
        password: XXXXXX
        socket: /var/lib/mysql/mysql.sock

wordpress-test:
        adapter: mysql2
        encoding: utf8
        database: test-wordpress
        pool: 5
        username: test
        password: XXXXXXX
        socket: /var/lib/mysql/mysql.sock

wordpress-development:
        adapter: mysql2
        encoding: utf8
        database: wordpress
        pool: 5
        username: dev
        password: XXXXXX
        socket: /var/lib/mysql/mysql.sock

development:
        adapter: mysql2
        encoding: utf8
        database: dev
        pool: 5
        username: dev
        password: XXXXXX
        socket: /var/lib/mysql/mysql.sock

Solution 3

The Museum of Modern Art had a WordPress JSON API plugin built for this exact purpose: https://github.com/dphiffer/wp-json-api

This allowed them to build a RoR-based front-end layer while maintaining a WordPress-driven back-end layer.

Solution 4

You could install Wordpress then reproduce the wordpress database as Models and add the associations like wordpress uses them. Then you would be able to access the data using rails that were entered in the wordpress frontend. I did something like this in the past but not as a permanent solution but as a datasource for migration to another solution. Its possible, its not nice but it works.

But one question: Why are you using wordpress for a thing its not mighty enough?! Its a CMS not a framework for challenging tasks. If it doesnt fit the needs of the costumer its simply not the right thing to use. You could rather build a similar GUI using rails then fiddling with wordpress.

Solution 5

Concerning HAML, you can still write your views in haml, and then use haml input.haml output.html on the command line. A bit boring, but you don't have to write html.

Share:
23,633
BananaNeil
Author by

BananaNeil

I am a lion, rawr.

Updated on July 09, 2022

Comments

  • BananaNeil
    BananaNeil almost 2 years

    I have a client who has requested for me to build them a website with a very user friendly way to update content. They have expressed familiarity with wordpress, and expressed interest in being able to use the wordpress front-end to update their content.

    I had originally intended to build them a simple admin page, where they can create posts, or add other types of content.. but it seems like wordpress has most of the functionality already in place.

    The main problem is that i am a RoR developer. I prefer to use haml for every thing I do, and have 100% full control over how the site works.

    So i was hoping someone out there would have an idea of a way i could still build the site using rails and haml, but still allow my client to update using wordpress. I thought maybe i could access the wordpress api, and just pull the content and display it the way i want? or maybe i should go with another CMS.. like Refinery?

    Honestly, I just really dont want to have to touch PHP, and preferably use haml, rather than html. O_o

  • BananaNeil
    BananaNeil over 12 years
    Do you know where i would be able to find more information about this? Like what the actual models they use and what their relations are.
  • davidb
    davidb over 12 years
    You have to reverse engine it! Use the mysql console using show tablesand show columns from table_name to demiter what their tables and fields are. But like I said its bad style...
  • BananaNeil
    BananaNeil almost 7 years
    Thank you so much for helping to keep this question up to date.
  • mysticalghoul
    mysticalghoul almost 6 years
    Wow, Do you have a detailed guideline somewhere about this. Thanks.
  • Fahmiin
    Fahmiin over 3 years
    Is this approach better than accessing the WP db directly and creating the models/controllers for them? Or is that not possible anymore?
  • Michael Schmitz
    Michael Schmitz over 3 years
    You would probably have a cleaner solution if you access the WP db directly, if that's the only thing your app is doing. In my case it was mixed into a different project and I wanted to keep things separate. Good luck.