🚀 See the 2024 Ruby on Rails Community Survey results!
Article  |  Development

Fixing Wordpress URLs When Using Rack

Reading time: Less than a minute

Tip to fix WordPress URLs

In my last article I detailed how to run PHP through a Rack server. This works fairly well until you try to sign into the Wordpress admin section.

The problem is that Wordpress stores site URLs in the database and it will use these for some redirections. Luckily, with a few Rake tasks you can painlessly override them.

I borrowed some conventions from Rails and created a config/database.yml file. This is your run of the mill database connection file, nothing special here.

From there I created a Rakefile in the root of the project titled rakefile.rb.

I've been spoiled by Rails' database Rake tasks so I decided to build my own using ActiveRecord.

Here are the Rake task components that setup the ActiveRecord connections:

require 'yaml'
require 'logger'
require 'active_record'

namespace :db do
    def create_database(config)
        options = { :charset => 'utf8', :collation => 'utf8_unicode_ci'}

        create_db = lambda do |config|
            ActiveRecord::Base.establish_connection config.merge('database' => nil)
            ActiveRecord::Base.connection.create_database config['database'], options
            ActiveRecord::Base.establish_connection config
        end

        begin
            create_db.call config
        rescue ActiveRecord::StatementInvalid => exception
            puts "There was an error creating the database. The error is: #{exception.message}" and return
        end

        puts "Database #{@config['database']} was created."
    end

    task :environment do
        DATABASE_ENV = ENV['DATABASE_ENV'] || 'development'
    end

    task :configure_connection => :configuration do
        ActiveRecord::Base.establish_connection @config
        ActiveRecord::Base.logger = Logger.new STDOUT if @config['logger']
    end
end

Now that we have that out of the way, we can create our database create and drop table tasks. I put these in the db namespace.

desc 'Create the database from config/database.yml'
task :create => :configure_connection do
    create_database @config
end

desc 'Drops the database'
task :drop => :configure_connection do
    begin
        ActiveRecord::Base.connection.drop_database @config['database']
    rescue MySql2::Error => exception
        puts "There was an error dropping the database. The error is: #{exception.message}"
    else
        puts "Database #{@config['database']} was dropped."
    end
end

Now we can create and drop our database with the familiar commands of rake db:create and rake db:drop.

There is only one more thing to do and that's fix the Wordpress site URL references. I added the following task to the db namespace:

desc "Set Wordpress URL's to localhost"
task :fix_wordpress_urls => :configure_connection do
    begin
        ActiveRecord::Base.connection.execute(
            "UPDATE wp_options SET option_value = 'http://localhost' WHERE option_name IN ('siteurl', 'home');"
        )
    rescue ActiveRecord::StatementInvalid => exception
        puts "There was an error fixing the Wordpress URLs. The error is: #{exception.message}"
    else
        puts "Wordpress URLs have been fixed."
    end
end

With that final task we can now run this command:

rake db:fix_wordpress_urls

Now our Wordpress instance is ready to be run through Rack.

Final Thoughts

This is how I thought to manage this particular PHP/Wordpress hurdle in a Rails dominated environment. Hopefully some of you can apply this, and let us know if you have any other clever solutions.

Have a project that needs help?