Uncategorized


17
May 10

Setting up multisite WordPress 3.0 with multiple different domains

WordPress 3.0 is coming out very soon (apparently they missed their original deadline, see the schedule here) – and it has one killer feature for anyone who maintains multiple WordPress sites: official support for multiple subdomains and (unofficial) support for multiple different domains. This means that one only has to maintain and upgrade one WordPress installation.

Here is my guide to setting up WordPress 3.0 with multiple different domains and subdomains – based on the experience I got from moving my own blogs to WP 3.0 beta 2 (still waiting for the final release before moving clients as well).

Installing WordPress 3.0

The basic installation process is the same as that of WP 2.9. Download, unzip, set up the database and the set up wp-config.php. If you aren’t going to use the multi-site support, then not much will change. Brief instructions below.

Multi-site mode with Apache

You will need to separately enable the multi-site mode, as well as take care of your Apache settings. WP 3.0 will handle all the requests it gets from a single directory, which means that all your subdomains must use that directory as their DocumentRoot/VirtualDocumentRoot.

Furthermore, WP 3.0 will assume that if you are using multi-site mode with subdomains, you want the subdomains under the first site’s URL – ex. if your first WP 3.0 install is under www.domain.com, then WP 3.0 will set up subdomains in the format subdomain1.www.domain.com.

That means that if you want to use first-level subdomains (ex. blog.domain.com, subdomain2.domain.com etc.), you have to set up WP 3.0 so that your first blog is using the bare domain (ex. domain.com) and not on the www.domain.com subdomain.

0. (Optional) Bare domain setup for Apache

The way in which you setup your bare domain (and forward from the www -subdomain to the bare domain) depends a lot on how you have set up your domain originally in Apache.

I have been using virtual hosts to host multiple sites, with each subdomain having its own directory. This means that I had to add an additional Vhost directive before my original Vhost directive in httpd.conf. Here is how I did it:

    ServerName domain.com
    ServerAlias domain.com blog.domain.com subdomain1.domain.com
    DocumentRoot /var/www/domain.com/www

As you can see in the first Vhosts directive, I have used the ServerAlias directive to specify domain.com, blog.domain.com and subdomain1.domain.com to be served from the DocumentRoot /var/www/domain.com/www (which is where I have installed WP 3.0).

In addition, I still have the rest of my subdomains served from a VirtualDocumentRoot, and have a forward from the www.domain.com -subdomain to the domain.com bare domain.

    ServerName domain.com
    ServerAlias *.domain.com
    VirtualDocumentRoot /var/www/domain.com/%1
    # rewrite www to bare domain
    RewriteEngine On
    RewriteCond %{HTTP_HOST} ^www\.domain\.com$ [NC]
    RewriteRule (.*) http://domain.com$1 [R=301,L]

Apache will use the first matching VirtualHost directive (see “An in-depth discussion of Virtual Host Matching” for more details).

If you want to test your setup – remember to restart Apache – you can use an online redirect checker such as: http://www.internetofficer.com/seo-tool/redirect-check/

1. Get the files and unzip them

2. Edit wp_config_sample.php

You can use https://api.wordpress.org/secret-key/1.1/salt/ to generate the secret keys

3. Enable multisite

Add:

 define(’WP_ALLOW_MULTISITE’, true);

to wp-config.php after the secret keys

4. Log in, go to Tools/Network

Select either the blogs-as-subdomains or blogs-as-directories option and install.

5. Make the changes detailed on the post-install page

WP 3.0 gives you a number of changes you will need to make manually to .htaccess and wp-config.php.

Adding a new subdomain

You have now set up the multisite functionality. Next, add a subdomain (see below for how to add a different domain).

1. Login in on your main site

2. Go to Super Admin (new menu at the top)

3. Use the add site form to add a new subdomain

4. Configure your DNS and add a Vhost for the subdomain

Make sure there is a DNS entry for your subdomain – if you don’t have a wildcard redirect for your domain to your server. If you did the Apache configuration, all you need to do now is to set up your DNS so that the subdomains you want are mapped to your server.

Quick tip for Windows: edit C:\Windows\System32\drivers\etc\hosts and add a temporary hosts entry for your new subdomain, such as:

123.14.15.16 subdomain.domain.com

This will allow you to test the subdomain without having to wait for DNS to propagate. Under Win7, you need to start Notepad as an Administrator (right-click) to edit the file.

5. All done!

Try navigating to your new subdomain. It should be set up now!

Adding a new (different) domain

1. Use the add site form to add a new subdomain

You will use the default tools to create all the tables, then you will make a small number of changes to make WordPress accept a different domain. All credit for this method goes InterconnectIt – see their writeup here.

2. Configure your DNS and add a Vhost for the subdomain

The easiest way is to add another ServerAlias domain to the original domain’s VirtualHost -> ServerAlias directive.

If you try to access the site now, you will get a “Registration” page. This means the Vhost is working.

3. Edit the wp_site table to include your new domain

This table stores all the domains that can be used in WP 3.0.

Leave “id” empty (it is an autoincrement field), set “domain” to the domain name, “path” should be /.

Make a note of the id your newly inserted row gets after saving, since you will need it in the next step.

4. Edit the wp_blogs table to use the new domain

Find the row for the subdomain you added earlier. Change “site_id” to the id given to the new row in the wp_site table. Change “domain” to the domain name you want to use.

5. Edit wp_[blog_id]_options to use the new domain name

The WP 3.0 multisite database schema is sharded by having the blog id in the table names. By default these are in the form wp_[blog_id]_*, so you will need to find which set of tables contains your new blog.

Each WordPress blog stores a small number of settings which need be changed to use the new domain name. You can use the query below to find the mentions of the domain in the options table:

SELECT * FROM `wp_[blog_id]_options` WHERE `option_value` LIKE "%subdomain.domain.com%";

For me these are: siteurl, home, fileupload_url. Change them to use the new domain.

6. Done!

Do you need to move an existing WP 2.9 to WP3.0 multisite? If you are moving an existing site to the WP multisite you’ve set up, check out my second tutorial on the topic.

Did you run into problems enabling themes or plugins on your separate domains? Have a look at how I solved a number of issues related to the separate domains setup.

References

  1. http://www.interconnectit.com/840/wordpress-3-0-multisite-with-multiple-domains-setup/

15
Mar 10

7 additional tips for CSS markup

1. Use a test page

Make a test page that has:

  1. All of the common HTML elements
  2. All of your widgets and inline elements

… on one page. This allows you to make and preview changes quickly.

Snippllr.com has a couple of test pages containing the major HTML elements:

http://snipplr.com/view/8121/html-test-page-for-css-style-guide/
http://snipplr.com/view/12564/css-test-page/

2. Start with a CSS reset

Using a CSS reset helps because it eliminates the inconsistencies between browsers and forces you to specify all of the styles you want. It makes CSS stylesheets more explicit, which is a good thing for maintainability.

http://meyerweb.com/eric/thoughts/2007/05/01/reset-reloaded/

http://developer.yahoo.com/yui/reset/

3.Order your rulesets into sections – generic to specific

Use stylesheet rule order to define “base” and “special case” tags. First, organize your CSS rules into sections so that the most generic rules (e.g. typography) come first before specific rules such as widgets. This is useful because it makes it easier to locate rules within the file and to make modifications.

For example, I have used the following sections:

  1. Base/reset styles (Yahoo’s CSS reset rules)
  2. Typography styles (inline elements applied to the whole page such as fonts, links, headings, paragraphs)
  3. Layout (fixed containers, blocks of content and other “website-specific” positioning)
  4. Widgets (ex.  informational messages, contextual help, menu lists, collapsible navigation list, tabs, table styles…)

4. Order your widget rules from “base” to “special case”

Organize the rules into “base” widgets and “special case” if necessary. Have the “base” widget specify the most important rules, and then override for the “special case”.

5. Indent your CSS files!

Use indentation to organize the code – the first level of indentation is for sections, the second for widgets and the third for special cases of widgets or sub-widgets. (If you are concerned about bandwidth, use a CSS minifier afterwards – don’t sacrifice understandability just to try to save a few characters).

For example:

/** Css reset **/
/** Base styles **/
   ...
/** Typography styles **/
   ...
/** Layout styles **/
   /** Containers **/
   ...
/** Widgets **/
   /** Information messages **/
   ...
   /** Tabs widget **/
   div.tabs {
      ...
   }
   div.tabs ul {
      ...
   }
   div.tabs ul li {
      ...
   }
   div.tabs ul a:link, div.tabs ul a:visited {
      ...
   }
   div.tabs ul li.selected a, div.tabs ul a:hover {
      ...
   }

6. Keep the dependency chains as short as possible

Avoid modifying the HTML element styles without specifying a class. Adding styles to tags without a class -attribute is problematic because it makes the dependencies much more complex.

By keeping dependency chains short – so that the base CSS is unmodified and all necessary styles are defined on a class-specific level –  you keep the dependencies reasonably simple.

7. Never rely on coincidental nesting & avoid “class-itis”

“Class-itis” is the disease that causes CSS files to have too many classes. Instead, use tag nesting to create widgets.

Have single base element with a simple but descriptive class name, and then specify the sub-elements.

For example:

  • Instead of “div.content-title” use “#content h1″ (e.g. div#content with a h1 tag inside it)
  • Instead of “div.form-label” use “#form label” (e.g. form#form with a label tag inside it)

24
Feb 10

Options for securing PHP in a shared virtual hosting environment

The terms and options for implementing security measures can be quite confusing. This blog post is a survey of the options available, including some possible pros and cons and definitions of relevant terminology.

It is very typical to run multiple sites on a single server, since it would be overkill to run each small website and blog on its own VPS instance. The default Apache setup: mod_php and prefork-mpm does not offer any privilege separation or hardening for virtual hosts. Hence the need for additional security measures.

What are the general approaches taken to securing PHP?

The approaches taken in securing PHP can be divided into two broad categories:

  1. Hardening PHP. This approach aims to improve the security of PHP scripts by limiting dangerous functionality on a site-by-site basis and by preventing flaws from escalating through additional patches to the PHP core. The main examples are: a) tweaking PHP core settings such as open_basedir and b) running a version of PHP which includes additional options to limit functionality and prevent flaws such as buffer overflows (Suhosin).
  2. Privilege separation. This approach limits the extent to which other sites can be damaged if one of the websites on the shared server is compromised. There are several solutions, including mod_suPHP and suEXEC.

How can PHP and Apache interact?

There are several ways in which PHP and other scripts can be invoked by Apache:

  • CGI (Common Gateway Interface) is a standard protocol that defines how webserver software can delegate the generation of webpages to a console application. It operates on a “one new process per request” basis.
  • FastCGI is a protocol introduced in the mid-1990s that improves upon the older CGI protocol. It allows a single persistent process pool to handle multiple requests over its lifetime, reducing overhead.
  • In-process as an Apache module, such as the default mod_php.

The default interaction between PHP and Apache is handled by the mod_php module. The most common ways of implementing privilege separation use either CGI or FastCGI to interface with PHP. PHP supports both CGI and FastCGI protocols.

Privilege separation can be done either:

  1. by using CGI scripts and suEXEC, a feature built in Apache
  2. by using Apache modules that make invoking CGI scripts easier
    • Apache modules are bundles that can be loaded to add new functionality to Apache. They are integrated into the Apache server and add new functionality to instances of the server, such as the capability to interpret PHP scripts.
    • Examples: mod_php, mod_suPHP, mod_fastcgi and mod_fcgid.
  3. by using Apache MPMs that support privilege separation
    • Apache MPMs (Multi-Processing Modules) are responsible for binding to network ports on the machine, accepting requests, and dispatching children to handle the requests. There are several different MPMs – the Unix platform default is the prefork mpm.
    • Examples: prefork, worker, perchild, mpm_itk, mpm_peruser

What are the options for privilege separation?

suEXEC

suEXEC is a feature built into Apache, but not included in the default Apache installation. It makes all CGI scripts execute with the user id and permissions of their owners. It can be used with PHP and with other CGI scripts.

It consists of a setuid “wrapper” binary that is called by the main Apache web server, and which executes CGI scripts with the correct used id.

+ Tried and tested

+ Can be used with other languages than PHP

- Low performance without FastCGI (similar to suPHP)

- Separate script files are a minor hassle

Module: mod_suPHP

mod_suPHP makes PHP scripts execute with the user id and permissions of their owners.

It consists of an Apache module (mod_suphp) and a setuid root binary (suphp), which calls PHP as a CGI process.

+ Easy to install, in RPMForge repo (http://wiki.centos.org/AdditionalResources/Repositories/RPMForge)

+ Quite commonly used

- Low performance relative to others (similar to suEXEC)

- PHP specific solution

= Recommended for low load sites which are not using their resources to their limits.

Module: FastCGI (mod_fastcgi or mod_fcgid)

mod_fastcgi and mod_fcgid implement process persistence between page views and communicate with PHP using FastCGI. They do not by themselves perform privilege separation, suEXEC is needed.

+ Decent performance when using suEXEC with FastCGI, similar or better performance than mod_php has been reported

+ Can be used with other languages than PHP

- FastCGI may require more memory because there are more persistent processes (more suited for servers with a lot of memory)

- Separate script files are a minor hassle

= Recommended for higher load sites.

MPM: mpm_itk and mpm_peruser

These are alternative MPMs for Apache that replace the default preform MPM and perform additional privilege separation.

mpm_itk works in a manner similar to regular CGI scripts in that it does not reuse processes after each request. However, unlike CGI scripts, it invokes each process with the user id and group specified for that virtual host.

+ Neat solution with decent performance, some systems have it in the repos

- Must patch and compile separately in Centos

- Not as commonly used as suEXEC or suPHP

= Recommended as a upcoming solution that is higher performance than mod_suPHP and easier to setup than suEXEC+FastCgi.

mpm_peruser creates one or more apache child processes for each unique user/group, each handling its own set of virtual hosts.

+ Faster than mpm_itk

- Must patch and compile separately in most systems

- Development and adoption seems to be more limited than mpm_itk


29
Jan 10

Finnish translation for Subscribe2 / Suomenkielinen käännös Subscribe2 -pluginiin

Installation instructions

I’ve made a Finnish translation for the WordPress Subscribe2 -plugin, download it here: subscribe2-fi.zip

Upload the subscribe2-fi.mo file to the wp-content/plugins/subscribe2/ directory. If WPLANG in wp-config.php is something other than the default “fi”, then change “fi” in the filename to the correct value.

I was reminded again how hard it is do proper translations in Finnish because of the differences in word order compared to English, e.g. “For digest notifications, date order for posts is” -> “Yhteenvetomuotoisissa päivityksissä artikkelien (aika)järjestys on”…

If you want to improve the translation, open the .po -file in Poedit or some other editor. The translation was done in one go, so I some of the wordings could be improved. (Then again, the terminology in the Finnish WordPress itself is sometimes rather confusing.)

Continue reading →


3
May 09

Why blog? (ep. 2)

  1. Realize that the rest of the world does not, in fact, give a damn 

    It is easy to delude yourself that you are incredibly special. In fact, it is beneficial. But I hope that by working on an online presence you can show yourself that you really don’t matter and won’t be a superstar online. Delusions of grandeur, like that people care about what you did today, are damn common in the world of blogging. Understanding what one can and cannot do through online communication is worth exploring and busting those ego bubbles is a worthy task. Frankly, if you live and die by your online image, then something is really wrong with your self-esteem.
     
  2. To learn about marketing and publicity without having to face high stakes

    Whatever bloggers would like to believe, an online “brand” is still highly marginal. Most people do not read blogs. Think about that. Online communities are deceptive in that they make it easy to imagine that one is reaching a wide audience. Think about TechCrunch for example. Well known and influential? I bet that most people you know have never heard of it – even those in the relevant industry. TC, a wildly successful blog is just the tip of the iceberg when it comes to people. It is easy to forget that online. (I think Eric Sink said it well: “Objects in browser are smaller than they appear”)

    Most employers won’t bother finding out about your blog. Therefore I think this online thing should be about learning to market information – with little at stake. Failing doesn’t really matter; you can experiment and not worry too much.
     

  3. To write about things you care about for yourself

    I think the only reason to write is to preserve ideas you like, while perhaps helping some random people online. I think that is a good reason: I have been helped by random blog posts on many topics, and hopefully some of my posts will help someone.

    “Monetizing” a blog is, I think, a rather bad reason to write. Not to discourage people (not that they would care), but putting up ads on a blog to me seems rather desperate unless you already have built up a huge audience. In terms of my quality of life, I don’t see how making an extra 30 or 100 bucks a month are going to make any difference in my life. I have all the toys and ramen noodles I need and getting a few more does not matter. I like banner ads less than having to work an extra hour every now and then. (Obviously, if you are TC, this does not apply. But for $random_person like me, that is probably not going to be true.)


28
Apr 09

How I Read Stuff

I strongly believe that reading is extremely important. I mean, if the information is out there, why not use it? I find it absolutely amazing that statistically so few people read books after they graduate.

I read:

  • Books – a bit over 50 books a year, essentially all of them non-fiction.
  • Blogs, websites and news. I don’t read general news websites, since I don’t find them to be relevant. As for blogs and websites, I read them like books.
  • Email.
  • Scientific articles. More and more nowadays. I usually speedread them, since most articles aren’t all that great :) .

Reading books

My yearly average comes to about a book a week, but usually I read less during the busy times of the year and more during vacations. I read books from the start to the end, unless the book is really bad. Really, I have only had two to three books in the last years which I could not finish (unbearably simple, totally boring or too “sociological”).

The best way to read quickly is NOT to read something. I.e. pick a good book and avoid reading crap. Generally I focus on the negative reviews (a single “too simple” review on a US textbook = don’t buy) and the table of contents. I occasionally spend a lot of time on Amazon picking books for wishlists (one for each topic).  Then I do a second review before purchasing the books, picking the best from the wishlists I have.

When reading I try not skip ahead, since I find that speedreading isn’t very pleasurable if you want to think and retain the information. If I come across a fascinating idea, I log it down in my notebook.

I’ve kept a reading log since 2006. In the log 1) keep track of when I started reading and when I finished the book and the number of pages, 2) write a brief summary of the book and a rating. Keeping track of the books I read helps me see how much other things have taken time away from reading.

In the near-ish future I am planning to get the log up and on Amazon+here.

Reading blogs and websites

I don’t follow blogs, I read them. When I find something interesting, I usually keep the website open in the browser until I have finished reading ALL of the articles on a site (well, everything in the archives that interests me). I am wondering if by doing this I am missing out on something, but so far not following blogs has worked fine.

Reading emails

Until a few years back I used to read all the mail I received. Now I don’t. I keep three email boxes, roughly: personal mail, work mail and stuff I might want to know about (lists, random stuff). For anything I need to reply to, I will set the star icon in Gmail so I remember to get back to it. No icon = will never open again.


18
Apr 09

Why blog?

I’ve been blog-sceptical for quite a few years, but recently I’ve been thinking about getting more active online*. The reason is not that I would want to share how my stamp collecting project is going or what I think about Obama. Frankly, I don’t give a damn about status updates and I don’t expect anyone to give damn either.

What I would like to do is connect and get feedback from people who share my rather specific interests: tech entrepreneurship, product development and getting stuff done. Finland is a small country and sometimes it is hard to get into a good discussion on these topics. If this blog succeeds in sparking at least a couple of new interesting acquaintances and good conversations – it has worked.

(* I’ve had this domain since 2002, first it was a discussion forum, then a wiki, then dead, and now hopefully a blog.)