Mar 112012
 

For my own record and maybe for your convenience I wrote down the steps to install a Debian/Ubuntu VPS as web server. This setup is optimized for low memory usage (128-512 MB). This means nginx instead of Apache, no DNS server and no e-mail server (only outgoing mail) and some MySQL, PHP and nginx tuning.

This setup guide has been tested for a VPS on OpenVZ, Xen and KVM and for Debian 6.0 (Squeeze), Ubuntu 10.04 (Lucid Lynx) and 11.10 (Oneiric Ocelot). My favorite combination so far is KVM and Debian 6.0 with the Dotdeb repository (fast virtualization, stable Linux and the latest server software).

This setup is handling > 60,000 page views per day (> 100,000 hits) for a dozen of sites on a dual core VPS (2 × 2.4 Ghz) with 512 MB memory with ease (little CPU usage, load average 0.1-0.2, and almost no swapping).

I use Hurricane Electric Free DNS Management, because I like the fast web interface, the possibility to set the TTL and because it is free (up to 50 domains), but be aware wildcard domains are not allowed (anymore). List of free DNS providers.

has been so kind to provide a VPS to test this guide.

Cheap, reliable VPS providers:

Fora:

Index

Setup VPS

From the hosting control panel:
  • Configure the host name
  • Configure rDNS and SPF (for reliable e-mail)
    • Check: dig -x <IP>
    • Check: dig TXT <domain>
    • SPF wizard
  • Point a domain name to the VPS
  • Install a recent version of Debian or Ubuntu

Setup security

  • Login to the VPS:
    • ssh root@domain
  • Set new root password:
    • passwd
  • Fix the hostname when needed:
    • hostname <name>
    • nano /etc/hosts
  • apt-get update
  • apt-get upgrade
  • apt-get install nano sudo
  • Sometimes needed:
    • locale-gen en_US en_US.UTF-8
    • dpkg-reconfigure locales
  • When IPv6 doesn’t work: nano /etc/gai.conf
precedence ::ffff:0:0/96  100
  • If you want more recent package versions, use Dotdeb
    • Don’t change to Dotdeb afterwards, because you will run into dependency problems!
  • Not every VPS-template is perfect and it may be necessary to prevent kernel/grub updates
    • nano /etc/apt/preferences
Package: linux-base linux-image linux-headers firmware-linux-free
Pin: version 2.6.32-30
Pin-Priority: 1001

Package: grub-common
Pin: version 1.98+20100804-14
Pin-Priority: 1001

This can be fixed this way too.

  • mkdir /root/.ssh
  • chmod 700 /root/.ssh
  • nano /root/.ssh/authorized_keys
    • paste key from local computer
    • cat ~/.ssh/id_dsa.pub
  • ssh-keygen -t dsa
  • nano /etc/ssh/sshd_config
Port 22022
PasswordAuthentication no
ClientAliveInterval 120
ClientAliveCountMax 600
#Subsystem sftp /usr/lib/openssh/sftp-server
Subsystem sftp internal-sftp
Match Group users
ChrootDirectory /home
AllowTCPForwarding no
X11Forwarding no
ForceCommand internal-sftp
  • service ssh restart
  • chown root:root /home/*
  • apt-get install iptables
  • nano /etc/resolv.conf
nameserver 8.8.8.8
nameserver 8.8.4.4
  • mkdir /etc/fw
  • Download FirewallBuilder
    • use web server template
    • allow https in
    • allow port 22022 in (ssh)
    • allow port 587 out (ssmtp)
    • allow http/https out (for updates)
    • allow ntp out
    • allow ftp out
    • allow xmpp-server in/out
    • allow xmpp-client in
    • Install
  • nano /etc/rc.local
/etc/fw/firewall.fw
echo 1 >/proc/sys/net/ipv6/conf/eth0/disable_ipv6
  • Prevent DoS attacks (to a certain extend):
iptables -I INPUT 1 -i eth0 -p tcp --syn --dport :1024 -m connlimit --connlimit-above 25 -j LOG --log-prefix "Conn limit: "
iptables -I INPUT 2 -i eth0 -p tcp --syn --dport :1024 -m connlimit --connlimit-above 25 -j DROP

(Documentation)

You can put these extra rules in Firewall Builder: double click on your machine name under Firewalls, then button Firewall Settings, tab Prolog/Epilog, second textarea.

  • nano /etc/default/useradd
SHELL=/bin/false

Setup time

  • apt-get install ntpdate
  • nano /root/ntpdate.sh
#!/bin/sh
/usr/sbin/ntpdate pool.ntp.org
  • chmod 755 /root/ntpdate.sh
  • crontab -e
0 9 * * * /root/ntpdate.sh >>/root/ntpdate.log 2>&1

Not needed/possible when shared Linux kernel (for example OpenVZ)

Setup servers

Remove pre-installed stuff:
  • apt-get purge sendmail* apache2* bind9 samba xinetd
Install new stuff:
  • apt-get install nginx php5-fpm php5-cli php5-apc php5-curl php5-gd php5-suhosin php5-mcrypt php5-intl php5-mysql mysql-server
Debian:
  • Use Dotdeb repository (see before)
Ubuntu 10.04:
  • apt-get install python-software-properties
  • add-apt-repository ppa:nginx/stable
  • add-apt-repository ppa:brianmercer/php
    • Obsolete and due to be closed in the near future.
  • apt-get update

Setup MySQL

  • nano /etc/mysql/my.cnf
[mysqld]
skip-innodb
#skip-external-locking
skip-networking
query_cache_size = 64M
key_buffer = 64M
table_cache = 1024
  • Debian:
default-storage-engine=MyISAM
  • service mysql restart

Setup PHP

  • nano /etc/php5/fpm/pool.d/www.conf
;pm = dynamic
;pm.max_children = 10
;pm.start_servers = 4

pm = static
pm.max_children = 3
pm.status_path = /fpm_status
catch_workers_output = yes
pm.max_requests = 1000
listen.backlog = -1

request_terminate_timeout = 60s
request_slowlog_timeout = 30s
slowlog = /var/log/php5-fpm-slow.log
  • You could also use the dynamic process manager:
pm = dynamic
pm.max_children = 7
pm.start_servers = 1
pm.min_spare_servers = 1
pm.max_spare_servers = 1
  • or the new on demand process manager:
pm = ondemand
pm.max_children = 3
pm.process_idle_timeout = 3s
  • nano /etc/php5/fpm/php.ini
cgi.fix_pathinfo = 0;
memory_limit = 80M;
user_ini.filename = ".user.ini"
upload_max_filesize = 4M
open_basedir = /home:/tmp
allow_url_fopen = Off
mail.add_x_header = Off

[PATH=/path/to/folder]
open_basedir =
suhosin.simulation = On
  • Debian:
date.timezone = "Europe/Amsterdam"
  • nano /etc/php5/fpm/conf.d/apc.ini
apc.enabled=1
apc.shm_size=96M
apc.cache_by_default=0
;apc.ttl=900
apc.stat=1
  • Get maximum size: sysctl kernel.shmmax
  • nano /etc/sysctl.conf
kernel.shmmax=83886080
  • nano .user.ini
apc.cache_by_default=1
  • nano /etc/php5/conf.d/suhosin.ini
suhosin.mail.protect=2
suhosin.memory_limit = 128M

[PATH=/path/to/piwik]
suhosin.memory_limit = 800M
  • service php5-fpm restart

Setup nginx

  • nano /etc/nginx/nginx.conf
worker_processes 2;
server_tokens off;
client_max_body_size 4M;
  • Enabled GZIP:
#gzip on;
gzip_http_version 1.1;
gzip_vary on;
gzip_comp_level 1;
gzip_min_length 1100;
gzip_proxied any;
gzip_types text/plain text/css application/json application/x-javascript text/x$
gzip_buffers 16 8k;
gzip_disable "MSIE [1-6].(?!.*SV1)";

(you might want to use extra config files in /etc/nginx/conf.d)

  • service nginx restart

If you want to migrate from one server to another, you can do this:

server {
        listen 80;
        location / {
                proxy_pass http://aaa.bbb.ccc.ddd;
                proxy_set_header X-Real-IP $remote_addr;
                proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                proxy_set_header Host $http_host;
                proxy_redirect off;
        }
}

Setup WordPress

  • Segregate users:
    • useradd <username>
    • passwd <username>
    • usermod -G users <username>
  • File permissions
find /home -type d -name 'wp-content' -exec mkdir -p {}/../assets \;
find /home -type d -name 'wp-content' -exec mkdir -p {}/gallery \;
find /home -type d -name 'wp-content' -exec mkdir -p {}/uploads \;
find /home -type d -name 'wp-content' -exec mkdir -p {}/upgrade \;

chown root:root /home
chown -R <username>:www-data <username>

find /home -type d -exec chmod 2750 {} \;
chmod 755 /home
find /home -type d -name '.ssh' -exec chmod -R 2700 {} \;
find /home -type d -name 'wp-content' -exec chmod -R 2770 {}/gallery \;
find /home -type d -name 'wp-content' -exec chmod -R 2770 {}/uploads \;
find /home -type d -name 'wp-content' -exec chmod -R 2770 {}/upgrade \;
find /home -type d -name 'wp-content' -exec chmod -R 2770 {}/upgrade \;
find /home/ -type f -exec chmod 0640 {} \;

Setup Piwik

9 * * * * su www-data -c "/usr/bin/php5 .../misc/cron/archive.php --url=http://example.org/"
>>.../piwik-archive.log 2>&1

Setup E-Mail

Root=user@example.org
MailHub=smtp.gmail.com:587
RewriteDomain=example.org
Hostname=example.org
FromLineOverride=YES
UseTLS=YES
UseSTARTTLS=YES
AuthUser=user@example.org
AuthPass=...
AuthMethod=LOGIN
  • nano /etc/ssmtp/revaliases
root:user@example.org:smtp.gmail.com:587
www-data:user@example.org:smtp.gmail.com:587

For Google mail send limits, see here.

Don’t forget to setup rDNS and SPF.

Possible alternative: Msmtp (not tested)

Setup FTP

  • apt-get install proftpd
    • standalone
  • nano /etc/proftpd/proftpd.conf
RequireValidShell off
  • service proftpd restart

(needed for WordPress updates)

Setup XMPP

Backup

  • Backup databases:
fn="/tmp/backup_mysql.sql.gz"
mysqldump -u... -p... --all-databases | gzip -9 >$fn
scp -q -P 22022 $fn user@domain:/path/to/folder/
  • Restore databases:
gunzip <test.gz >/tmp/dump.sql
mysql -u... -p... </tmp/dump.sql
mysqladmin -u... -p... flush-privileges
  • You might need to restore the debian-sys-maint password:
    • nano /etc/mysql/debian.cnf
  • Backup files with rsync (apt-get install rsync)
rsync -avz -e 'ssh -p 22022' /etc/ user@domain:/path/to/folder/
rsync -avz -e 'ssh -p 22022' /var/lib/ user@domain:/path/to/folder/
rsync -avz -e 'ssh -p 22022' --exclude some/folder /home/ user@domain:/path/to/folder/
  • crontab -e
0 1 * * * /root/backup.sh >>/root/backup_`date +\%F`.log 2>&1
duplicity --exclude-filelist=duplicity.exclude --full-if-older-than 1W --allow-source-mismatch / rsync://user@host:22022//path/to/backup/folder
duplicity remove-older-than 1M --force rsync://user@host:22022//path/to/backup/folder

Some typical excludes for duplicity:

- /sys
- /dev
- /proc
- /tmp
- /mnt
- /var/lib/mysql
- /var/lib/mongodb

You might need a backport of duplicity on Debian.

(duplicity tutorial)

Monitoring

  • apt-get install munin munin-node sysstat libwww-perl libipc-sharelite-perl libcache-cache-perl
  • perl -MCPAN -eshell
  • install IPC::ShareLite
  • nano /etc/munin/plugin-conf.d/munin-node
[nginx_status]
env.url http://host/nginx_status

[nginx_request]
env.url http://host/nginx_status
  • ln -s /usr/share/munin/plugins/nginx_* /etc/munin/plugins
  • ln -s /usr/share/munin/plugins/mysql_* /etc/munin/plugins
  • rm /etc/munin/plugins/mysql_innodb
  • rm /etc/munin/plugins/iostats_ios
  • service munin-node restart
  • munin-node-configure –suggest
  • PHP5-FPM
  • Other plugins

Tuning

  • nano /etc/sysctl.conf
vm.swappiness=10

Tools

Be sure to lock these down behind a firewall / password.

Remote desktop

  • apt-get install  lxde-core lxtask lxde-icon-theme xfonts-base xarchiver tightvncserver
  • tightvncserver :1
  • tightvncserver -kill :1
  • nano ~/.vnc/xstartup
lxterminal &
/usr/bin/lxsession -s LXDE &
  • tightvncserver :1
  • If you want a browser:
    • apt-get install epiphany-browser
  • xtightvncviewer -via “user@domain -p 22022″ localhost:1
  • If you want VNC in your web browser: noVNC

Please let me know if you have any remarks or suggestions.

Aug 122011
 

I am using the fast and light bbPress 1.x stand-alone forum software for support on some of my WordPress plugins.

To reduce spam I added the following code to bb-config.php to automatically close old topics:

// Auto close topics older than 10 days
mysql_connect(BBDB_HOST, BBDB_USER, BBDB_PASSWORD);
mysql_select_db(BBDB_NAME);
mysql_query('UPDATE bb_topics SET topic_open = 0 WHERE DATEDIFF(CURDATE(), topic_time) > 10');
mysql_close();
Jul 172011
 

BrowserID logoI welcome any initiative that could free us from logging in with a user name and password. I have created an account on countless websites and I have to remember all those user names and passwords. Except from being inconvenient, this is also not very safe.

The Identity Team of Mozilla Labs has recently launched BrowserID, an open source experiment to login with just two clicks. The idea is that your e-mail addresses represent your identity and that someone vouch for your ownership of it. You can read here how it works and you can try it here.

Because I like the idea and I wanted to support it, I wrote this WordPress plugin to allow logging in with BrowserID to any WordPress powered website (currently 50,899,997).

Install now

I am curious what you think about BrowserID.

Jun 142011
 

Sometimes guests write something on my weblog. I like guest posts to have a different background color. In the past I realized this with a little bit of PHP code and some CSS styling. To realize this in a nicer way and to make it available to more people I crafted another WordPress plugin for it. With the Author Color plugin each author can simply set the post background and border color using the personal option of his/her profile page.

Install now

Author Color - Profile personal optionsAuhor Color - Example post

Jun 122011
 

BackPackTrack for AndroidWhen I am traveling I like to display the route I have traveled so far for the people at home. To simplify this I wrote an open source Android application to keep track of my route automatically. To save batteries the application turns on the GPS of my Android phone periodically and tries to acquire an accurate location for some time. It is also possible to mark important locations manually (make waypoints), like an attraction or the hotel I am sleeping in. It is also possible to geocode an address (find the latitude/longitude for an address), for the case I forgot to make a waypoint. When I have internet access I can upload the route information to my weblog easily, maybe after I have reverse geocoded a few marked locations (find the address for a latitude/longitude). To make the upload to my weblog possible, I wrote a little WordPress plugin to extend the WordPress XML-RPC protocol. The route information is stored as a standard GPX file attached to a post which is automatically created at the first upload. The excellent XML Google Maps WordPress plugin can be used to display a map based on the GPX file (example).

Install now

QR code BackPackTrack for Android

May 172011
 

Just over three months ago I published the Add Link to Facebook WordPress plugin. I had never expected that the number of downloads would be over 100,000 today! Last week the number of ratings passed 300. The average rating is great (4 stars). The plugin is currently number 26 on the list of the most popular WordPress plugins. So far I have answered more than 1100 questions (!). To reduce the number of questions, I opened a forum, wrote an extensive FAQ and this week I added an User Guide. Since the first release I improved a lot of things and added quite a lot of features, such as showing the names of the people who liked the link, adding a Facebook like and send button and two-way comment integration. It is nice to see that something I wrote for myself is making a lot of other people happy too!

Update 20/6/2011: > 150,000 downloads, > 500 ratings, #19 most popular plugins, #131 top 1000 authors
Update 18/7/2011: > 200,000 downloads, > 650 ratings, #26 most popular plugins, #103 top 1000 authors
Update 24/8/2011: > 250,000 downloads, > 825 ratings, #26 most popular plugins, #86 top 1000 authors
Update 15/2/2012: > 500,000 downloads, > 600 ratings, #12 most popular plugins, #12 highest rated, #53 top 1000 authors
Update 15/12/2012: > 1,000,000 downloads, > 2120 ratings, #48 most popular plugins, #4 highest rated, #38 top 1000 authors

Feb 072011
 

For my own convenience I wrote another WordPress plugin, which is specialized in adding links of posts that are being published to your Facebook wall or pages. Although you have to create a Facebook application yourself (which is not difficult), the setup is as simple as it can be. Just follow the directions of the plugin. If you encounter a problem, please let me know below and I will try to help you.

The link title will be the post title. The link description will be the excerpt, or part of the post text if there is none. It is possible to configure a link image (WordPress icon, featured image or custom image) or you can let Facebook select one automatically. It is possible to exclude individual post links from being added to your wall or pages by ticking a check box just above the publish button. There is support for multi-user and network sites and shortcodes will be processed. It works for remote publishing too, for example from Android or iOS (iPhone, iPad) powered devices or using Window Live Writer or from Linux using BloGTK or Blogilo.

You can find the plugin here in the WordPress repository.

Install now

Add Link to Facebook

Aug 242010
 

If you have been traveling to developing countries, like India, you may have experienced that using WordPress on slow connections and/or slow computers can be an exercise in patience. To solve this problem I wrote another new WordPress plugin “Light Post” that allows you to publish and edit posts a lot quicker in such circumstances. The price is that you can only edit HTML and that you only have a basic set of features available, like choosing the title, category and tags. Availability of JavaScript and Flash is not required, but when JavaScript is enabled you can upload and insert images. To prevent loading of the chunky WordPress administration panel, the plugin redirects the browser directly after logging in to an alternate post management screen outside the normal WordPress environment (this can be turned off with a setting). Just one click brings you back to the normal WordPress rich edit screen and visa versa (look in the ‘Publish’ meta box for a link).

Install now

 Posted by at 14:06  Tagged with:
Jul 292010
 

For a while I have been searching for a WordPress plugin that could display at least the Google PageRank for a configurable list of sites in a dashboard widget. A requirement was that no third party site should be referenced to get the rankings. I couldn’t find one, so I wrote one myself.

The List Rank Dashboard Widget can display currently:

By default the Google PageRank, Alexa Rank and number of Delicious Posts are displayed for the current site, but more sites can be added using the settings. After entering a Google API Key and a Yahoo! Application ID (both free) the number of Google and Yahoo! Backlinks can be displayed too.

Included is a shortcode to display rankings in post, pages and sidebar widgets (see the Faq for usage instructions).

If you like to see more rankings, please leave a comment, but don’t ask me to add rankings, such as the Technorati Authority, which requires parsing an HTML response. Sooner or later this will break, when the design of the site is being changed.

Install now

 Posted by at 21:40  Tagged with:
Mar 202010
 

Recently I installed the simple, but beautiful Suffusion theme by Sayontan Sinha. This theme is using the funtions.php file extensively, the same place where my shortcode definitions were stored. Sayontan will probably fix this in the near future by including a custom functions.php file from another location. I also used some PHP code in two sidebar widgets that was executed by the Exec-PHP plugin.

I thought, why not use a plugin to define shortcodes and execute PHP code snippets? I couldn’t find one, so I wrote one myself. You can find it in the WordPress repository as Shortcode Exec PHP.

Example shortcode to print your age:

extract(shortcode_atts(array('birthdate' => 'Jan 1, 1980'), $atts));
return floor((time() - strtotime($birthdate)) / (60 * 60 * 24 * 365.2425));

If you named the shortcode age, you can execute it in pages, posts, comments, widgets and/or RSS feeds like this:

[age birthdate="Mar 20, 2010"]

Please, use the forum for questions, bug reports and feature requests.

If you know a nice shortcode, you can leave it in the forum too.

Install now

Listing posts

If you want to list posts or pages on a post, page or in a widget, you can use the code below.

// Prevent recursion
global $outerPost;
if ($outerPost)
	return '';
 
// Parse parameters
extract(shortcode_atts(array('query' => 'post_type=post'), $atts));
$query = html_entity_decode($query);
 
// Create new post loop
global $post;
$outerPost = $post;
$my_query = new WP_Query($query);
while ($my_query->have_posts()) {
	$my_query->the_post();
	setup_postdata($my_query->post);
 
	// Process post
	echo '<em>'; the_title(); echo '</em>';
	echo '<div style="font-size: xx-small; border: 1px solid;">';
	the_content();
	echo '<div>';
}
$post = $outerPost;
$outerPost = null;
setup_postdata($post);

Example usage:

[list_posts query="author_name=marcel"]

Look here for possible query parameters.
Be sure the shortcode option ‘Output echoed‘ is checked.

Using forms

Example of form handling:

if (isset($_POST['form_select']))
	echo 'You selected ' . $_POST['form_select'] . '<br />';
?>
<form method="post">
<select name="form_select">
<option selected="selected" value="1">one</option>
<option value="2">two</option>
<option value="3">three</option>
</select>
<input type="submit" value="Submit" />
</form>

Be sure the shortcode option ‘Output echoed‘ is checked.

 Posted by at 16:11  Tagged with:
Aug 282009
 

Recently I published the One-Time Password WordPress plugin to be able to login more safely into my weblog to write my travel stories in internet cafés. I wanted something similar to access my e-mail. I considered using my weblog URL as OpenID, but most e-mail providers support OpenID only as provider, not as consumer (meaning that you cannot login with an OpenID). But suddenly I thought why not access my e-mail directly from my WordPress dashboard using a pre-stored password? This is exactly what the Mini Mail Dashboard Widget plugin offers, with the option to receive SMS messages when new e-mail messages arrive (using the services of VoipBuster or one of its clones).

Install now

Mini Mail Dashboard Widget

 Posted by at 14:47  Tagged with:
Aug 092009
 

For various reasons it is sometimes handy to have short URLs to my posts. After reading this post and some surfing around I selected Cli.gs as short URL service.

I couldn’t find a simple WordPress plugin to create and display Cli.gs short URLs, so I wrote Cli.gs and Tweet. As the name suggests this plugin can send a customizable Twitter message containing the created short URL too. This plugin can also inserts code into the page header for short url auto-discovery.

There is no setup required if you only want to automatically create short URLs when saving posts and display them above your posts. If you want to send Twitter messages, you just have to enter your Twitter user name and password. The appearance can be modified by some settings and/or by modifying a style sheet.

cligs-tweet-screenshot-1

This plugin requires PHP 4.3.0 only.

 Posted by at 18:02  Tagged with:
Jul 222009
 

I my attempt to write my travel stories in internet cafés without worries I wrote the Login Virtual Keyboard plugin sometime ago. However, using a virtual keyboard to prevent keylogging is somewhat clumsy and is still not entirely safe.

To improve safety I recently wrote the One-Time Password plugin that enables me to login to my weblog using passwords which are valid for one session only, so my main WordPress password cannot be stolen. The plugin is simple to use, just install it, generate a password list and you can start logging-in using one-time passwords.

For even more safety, I added the possibility to protect administrative actions with one-time passwords in version 2.

Amit Banerjee wrote an excellent guide to setup the plugin.

Update: this plugin is one of the 11 12 13 Vital Tips and Hacks to Protect Your WordPress Admin Area.

Install now

Login

Login

List

List

Generator

Generator

The authorize window for an administrative action

Authorize

 Posted by at 14:29  Tagged with:
Jun 192009
 

I wanted to show the number of visits per post using the statistics recorded by the CyStat plugin. This appeared to be quite simple, because there exists a suitable template function. I just added the following line to my WordPress theme to make it working:

<div><span>< ?php cystats_getPostVisitsByID($post->ID, $showmode=TRUE); ?> Visits</span></div>
 Posted by at 20:28  Tagged with:
May 082009
 

When I am traveling I frequently publish my travel stories from internet cafés on this weblog. However, these places are not the safest computing places. I have seen a lot of worrying messages from virus scanners nobody pays attention to.

Because of this I have been searching for ways to improve security. One measure I took was installing the Semisecure Login Reimagined plugin to send the WordPress password encrypted from the browser to the server (a better way is to use SSL, but my hosting provider doesn’t support that).

However, sending the password encrypted doesn’t prevent keylogging. A possible solution is to use a virtual keyboard (on-screen keyboard). Because I don’t want to search for or install a virtual keyboard each time, I wanted a virtual keyboard integrated in my login screen. I couldn’t find something existing, so I decided to write a new WordPress plugin to accomplish this. The short name of this plugin is WP-Login-Vkb.

After pressing the keyboard icon next to the password box, my login screen looks like this now:

WP-Login-Vkb plugin

Install now

The plugin was tested with WordPress version 2.7 on a standard (not customized) login screen. Please let me know if the plugin does work with other WordPress versions (especially older versions).

Disclaimer: I cannot guarantee this plugin will prevent keylogging in all cases.

The plugin is licensed under the GNU General Public License version 3. The plugin uses the Javascript Virtual Keyboard downloaded from The  Code Project. The keyboard icon was downloaded from Wikimedia Commons.

Remarks, comments and questions are as always very welcome.

 Posted by at 13:07  Tagged with:
Feb 282009
 

For developing the website leren.arabisch.nu, I wanted to display the last date and time any page was updated. Because currently no plugin exists that can do this, I used the following shortcode definition:

add_shortcode('mb_last_modified', 'mb_last_modified_func');
 
function mb_last_modified_func($atts) {
	global $wpdb;
	$last_modified = $wpdb->get_var("SELECT MAX($wpdb->posts.post_modified) FROM $wpdb->posts WHERE $wpdb->posts.post_status = 'publish'");
	return date(get_option("date_format") . " " . get_option("time_format"), strtotime($last_modified));
}

If you want to use this shortcode, put the code in the file functions.php of your theme. Create this file if it does not exist; WordPress will automatically find and use it. After that you can use the shortcode [mb_last_modified] anywhere in your posts and/or pages. If you want to use the shortcode in a widget just like I did, you have to add the following line of code too:

add_filter('widget_text', 'do_shortcode');
 Posted by at 13:25  Tagged with:
Feb 142008
 

Op dit moment zijn de volgende WordPress PlugIns op deze weblog geïnstalleerd:

  1. Advanced Search voor een verbeterde zoekfunctie
  2. Akismet om commentaar spam te voorkomen
  3. All in One SEO Pack voor zoekmachine optimalisatie
  4. Automatic Timezone voor automatische overgang zomer/wintertijd
  5. Auto Thickbox
  6. Bad behavior voor het weren van ongewenste bezoekers
  7. Comment Reply Notification om gebruikers op de hoogte te stellen van nieuw commentaar
  8. Canonical URL’s voor het voorkomen van dubbele inhoud
  9. Countdown Timer voor het aftellen naar een datum
  10. CyStat voor bezoekersstatistieken
  11. Dashboard Google Page Rank
  12. Enhanced WP-ContactForm voor een contactpagina
  13. Exclude pages from Navigation voor experimentele pagina’s
  14. Executable PHP widget voor o.a. landing sites
  15. Google Analytics for WordPress voor integratie met Google Analytics
  16. Google XML Sitemaps voor het automatisch genereren van een sitemap
  17. http:BL voor het tegengaan van ongewenste bezoekers (gebaseerd op Project Honey Pot)
  18. Landing sites voor het tonen van related posts na een search
  19. Link Indication voor het tonen van iconen bij links
  20. MaxBlogPress Ping Optimizer
  21. NextGEN Gallery voor het tonen van foto’s
  22. OpenID om met OpenID in te kunnen loggen
  23. Pagebar2 voor een beter pagina navigatie
  24. Permalink Redirect wegens een wijziging in de permalink-structuur
  25. Piwik Analytics als alternatief voor Google Analytics
  26. Post-Plugin Library voor de Similar Posts PlugIn
  27. Public Post Review voor het laten reviewen van niet gepubliceerde posts
  28. Robots Meta voor Google, Yahoo! en Live verificatie
  29. Semisecure Login Reimagined voor veiliger inloggen in internetcafés
  30. Shockingly Big IE6 Warning
  31. Similar Posts voor het tonen van gerelateerde posts
  32. SwfObj voor flash content
  33. TimeZoneCalulator voor het tonen van tijden
  34. TinyMCE Advanced voor een uitgebreidere editor
  35. WP-DBManager voor het maken van backups
  36. WP-Print voor het afdrukken van posts
  37. WP-Syntax voor het tonen van codefragmenten
  38. XML Google Maps om (satelliet)kaarten te tonen
  39. XRDS-Simple voor OpenID provider functionaliteit

De laatste versies van deze Plugins werken goed met WordPress versie 2.7.1

 Posted by at 8:27  Tagged with:
Feb 052008
 

After uploading an image to WordPress (version 2.3.3) the thumbnail of the image was not displaying. This was because the thumbnail had the wrong permissions (660). More people seem to have this problem. I fixed this problem by setting the permissions of the thumbnail after it has been move to its target.

The file to fix is wp-admin/includes/image.php. After inserting the following code at line 93 the problem is solved:

if (!chmod($thumbpath, 0644))
	$error = __( "Setting thumbnail permissions failed" );

Update: This problem has been solved in WordPress 2.5

 Posted by at 22:31  Tagged with: