There’s a bazillion ways to do most things in WordPress. Here’s one I just used to make a simple private page for the Sunshine Coast Community Foundation.
The request: allow board members to download a document in a members-only page. Of course, I’d like to protect the document from direct access as well.
The solution I used was as follows. It requires comfort with FTP and installing plugins.
1. Install the Page Restrict plugin
This is basic and really easy to set up: simply select the page(s) you want to protect. The result is that the private page will be hidden with a “please log in” message (which you can set on the plugin’s settings page) plus a log-in form.
Note: private pages don’t appear on the list of pages you can restrict, so if your page is marked private when you go to restrict it you’ll have to adjust that.
Nitpicks: I didn’t like the way the plugin displayed the log-in form. Instead of it using WordPress’s native wp_login_form(), it inserts it’s own. Unfortunately it had a layout I didn’t like with HTML that wouldn’t be easy for me to adjust via CSS. So I did something I almost never do and altered the plugin directly. I saved backups of the original and my new version outside the plugin folder in case it’s needed after future upgrades.
If you’re looking for a free plugin that controls content in a more advanced way, check out Role Scoper. You can protect a parent page for instance and have all child pages follow the same rules. You can create groups of users and limit access to certain pages per group.
2. Create a private folder for the documents
Even though I only have one document to protect at this point, it’s likely there could be more in future. The doc was too large for uploading via the WP admin anyway so it seemed to make sense for me to create a folder for these. I created /docs-private/ in the root of the site, and uploaded the document there.
3. Protect the folder from browsing and contents from direct links
In that folder, I made an .htaccess file that prevents people directly accessing the files unless coming there via the website. So in my /docs-private/ folder I created a file called: .htaccess and in it I put:
IndexIgnore *
Options +FollowSymlinks
RewriteEngine On
RewriteCond %{HTTP_REFERER} !^http://(www\.)?sccfoundation\.com/ [NC]
RewriteCond %{REQUEST_URI} !hotlink\.(gif|png|jpg|doc|xls|pdf|html|htm|xlsx|docx) [NC]
RewriteRule .*\.(gif|png|jpg|doc|xls|pdf|html|htm|xlsx|docx)$ http://sccfoundation.com/ [NC]
To quote wwhitehead whom I adapted this from:
In the above example the first line disables file directory listings (so no one can view the files in the ‘uploads’ or any of its subdirectories. The line with HTTP_REFERER makes sure linking to a particular file is coming from my site. The gif|png|jpg|doc|xls|pdf|html|htm|xlsx|docx) is a list of filetypes I want to prevent from being directly linked to (unless they are clicking from my site).
Of course there is another step implied above: On my restricted resources page, I created a link to the actual download.
Now I just have to create user accounts for all the members to be able to log in, view the resources page, and download the document.
The one unfortunate thing about this model is that it means the board members won’t be able to add new documents to a protected folder without knowing FTP. I should probably try to increase the file upload limit and apply the same protection to the uploads folder so that they can do so. Another day, another puzzle
