Key generation failed due to lack of entropy on the system. You may need to generate a GPG key on a desktop machine and import it into Virtualmin instead.

Failed to create backup key : Key generation failed : Key generation failed due to lack of entropy on the system. You may need to generate a GPG key on a desktop machine and import it into Virtualmin instead.

So you’re running Virtualmin and would like to encrypt your backups before they leave your server?
Unfortunately it would seem that some older, more quiet systems (or virtual systems) suffer from a lack of entropy.
The general advice it to move the mouse and use the keyboard, both which are not going to do much on a server.
Some people will recommend you use urandom as a source of random material (That’s a very bad idea!)

I’ve found Virtualmin to be extremely impatient when it comes to generating the key and found that if you’re willing to be patient you can better do this from the command line and just import the key into Virtualmin instead.
Also, you can follow these instruction on a local machine that does have sufficient entropy.
Here are my step by step instructions:

gpg –gen-key

gpg (GnuPG) 2.0.14; Copyright (C) 2009 Free Software Foundation, Inc.

This is free software: you are free to change and redistribute it.

There is NO WARRANTY, to the extent permitted by law.

 

Please select what kind of key you want:

(1) RSA and RSA (default)

(2) DSA and Elgamal

(3) DSA (sign only)

(4) RSA (sign only)

Your selection? 1

RSA keys may be between 1024 and 4096 bits long.

What keysize do you want? (2048) 

Requested keysize is 2048 bits

Please specify how long the key should be valid.

0 = key does not expire

<n>  = key expires in n days

<n>w = key expires in n weeks

<n>m = key expires in n months

<n>y = key expires in n years

Key is valid for? (0)

Key does not expire at all

Is this correct? (y/N) y

GnuPG needs to construct a user ID to identify your key.

Real name: <Server> Backups 2013

Email address: <server>@<company>.com

Comment: <Server> backups 2013

You selected this USER-ID:

“<Server> Backups 2013 (<Server> backups 2013) <<server>@<company>.com>”

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? O

You need a Passphrase to protect your secret key.

can’t connect to `/root/.gnupg/S.gpg-agent’: No such file or directory

You don’t want a passphrase – this is probably a *bad* idea!

I will do it anyway.  You can change your passphrase at any time,

using this program with the option “–edit-key”.

We need to generate a lot of random bytes. It is a good idea to perform

some other action (type on the keyboard, move the mouse, utilize the

disks) during the prime generation; this gives the random number

generator a better chance to gain enough entropy.

We need to generate a lot of random bytes. It is a good idea to perform

some other action (type on the keyboard, move the mouse, utilize the

disks) during the prime generation; this gives the random number

generator a better chance to gain enough entropy.

<snip>

public and secret key created and signed.

<snip>

 

Look at the bolded parts for your input and be sure to replace the <Server> with your server name (whatever you want it to be) and same for <Company>
For example: [email protected]

Once you have generated the key you need to export it, list it first:

gpg –list-keys

/root/.gnupg/pubring.gpg

————————

pub   2048R/1074… 2013-12-15

uid                  <Server> Backups 2013 (<Server> backups 2013) <<server>@<company>.com>

sub   2048R/443F… 2013-12-15

It should list more, as your keychain also includes GPG for the Virtualmin repo.

You export the key using the ID for the “sub” part of your key. Of course you should use the full value as shown by the output.

gpg –output <server>.gpg –armor –export-secret-key 443F…

This gives you the ASCII version of your private key that you can offer to Virtualmin, you can either copy paste it into your browser or point to the file locally.
Hope this helps you encrypt your backups

Virtualbox and Vagrant on CentOS

We heard you like servers, so we put a Virtualbox in your server.

I’m fairly sure you’ve heard of both of these technologies, so I’ll skip the introduction. You can read more about VirtualBox and Vagrant if you want.
Today I’ve setup a small test lab using Vagrant so that I can run integration tests against live servers (that optionally I can restore if the tests break)
For some of my projects I’ve built SSH and Virtualmin integration code and was testing it against a server that was technically also a backup machine. Not the best idea.

It goes without saying that you should not do this on a machine that is critical to you. Also, make backups.

Installing Virtualbox and Vagrant

We are assuming you are on a x86_64 machine, replace paths and packages as needed for 32 bit systems.

Start by updating the system and ensuring the dependencies are installed

yum update
yum install binutils qt gcc make patch libgomp glibc-headers glibc-devel kernel-headers kernel-devel dkms

Add the correct Virtualbox repo:

cd /etc/yum.repos.d/
wget http://download.virtualbox.org/virtualbox/rpm/rhel/virtualbox.repo

And install it

yum install VirtualBox-4.3

Resolving Dependencies
–> Running transaction check
—> Package VirtualBox-4.3.x86_64 0:4.3.2_90405_el6-1 will be installed
–> Finished Dependency Resolution

Dependencies Resolved

================================================================================
Package Arch Version Repository Size
================================================================================
Installing:
VirtualBox-4.3 x86_64 4.3.2_90405_el6-1 virtualbox 72 M

Transaction Summary
================================================================================
Install 1 Package(s)

Total download size: 72 M
Installed size: 146 M
Is this ok [y/N]: y
Downloading Packages:
VirtualBox-4.3-4.3.2_90405_el6-1.x86_64.rpm | 72 MB 02:24
warning: rpmts_HdrFromFdno: Header V4 DSA/SHA1 Signature, key ID 98ab5139: NOKEY
Retrieving key from http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc
Importing GPG key 0x98AB5139:
Userid: “Oracle Corporation (VirtualBox archive signing key) <[email protected]>”
From : http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc
Is this ok [y/N]: y
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : VirtualBox-4.3-4.3.2_90405_el6-1.x86_64 1/1

Creating group ‘vboxusers’. VM users must be member of that group!

No precompiled module for this kernel found — trying to build one. Messages
emitted during module compilation will be logged to /var/log/vbox-install.log.

Stopping VirtualBox kernel modules [ OK ]
Uninstalling old VirtualBox DKMS kernel modules [ OK ]
Trying to register the VirtualBox kernel modules using DKMS [ OK ]
Starting VirtualBox kernel modules [ OK ]
Verifying : VirtualBox-4.3-4.3.2_90405_el6-1.x86_64 1/1

Installed:
VirtualBox-4.3.x86_64 0:4.3.2_90405_el6-1

Complete!

This will take some time, so grab a cup of tea while it installs.

After this we will install Vagrant. Go to http://downloads.vagrantup.com/ to get the latest versions and grab the link to the proper (x86_64) rpm.
You will install this using (example):

rpm -iv http://files.vagrantup.com/packages/a40522f5fabccb9ddabad03d836e120ff5d14093/vagrant_1.3.5_x86_64.rpm

You can check Vagrant is installed:

vagrant -v
Vagrant 1.3.5

I’m placing my vagrant boxes in /opt/boxes:

mkdir /opt/boxes
chgrp -R vboxusers /opt/boxes

Congratulations. The hard part is over!

Your first Vagrant box

Let’s grab a CentOS box from: http://www.vagrantbox.es/
I’m using the “CentOS 6.4 x86_64”:

mkdir centos6_virtualmin ; cd centos6_virtualmin
vagrant box add CentOS6_virtualmin https://github.com/2creatives/vagrant-centos/releases/download/v0.1.0/centos64-x86_64-20131030.box

Downloading or copying the box…
Extracting box…te: 21.0M/s, Estimated time remaining: 0:00:01)
Successfully added box ‘CentOS6_virtualmin’ with provider ‘virtualbox’!

vagrant init CentOS6_virtualmin
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

Time to get going:

vagrant up
Bringing machine ‘default’ up with ‘virtualbox’ provider…
[default] Importing base box ‘CentOS6_virtualmin’…
[default] Matching MAC address for NAT networking…
[default] Setting the name of the VM…
[default] Clearing any previously set forwarded ports…
[default] Creating shared folders metadata…
[default] Clearing any previously set network interfaces…
[default] Preparing network interfaces based on configuration…
[default] Forwarding ports…
[default] — 22 => 2222 (adapter 1)
[default] Booting VM…
[default] Waiting for machine to boot. This may take a few minutes…
[default] Machine booted and ready!
[default] Mounting shared folders…
[default] — /vagrant

Start customizing your box

Logging in is quite simple:

vagrant ssh

Usually a box lets you sudo to root without a password:

[vagrant@vagrant-centos64 ~]$ sudo -i
[root@vagrant-centos64 ~]#

Wait, am I really in the box?

[root@vagrant-centos64 ~]# hostname
vagrant-centos64.vagrantup.com

Yup 🙂

In my case I’ll be installing Virtualmin for internal tests of the LAMP stack.

When you need more power

So a default box has the following:

[root@vagrant-centos64 ~]# free -m
total used free shared buffers cached
Mem: 589 212 376 0 12 146
-/+ buffers/cache: 53 535
Swap: 0 0 0

And

[root@vagrant-centos64 ~]# cat /proc/cpuinfo | grep “model name”
model name : Intel(R) Xeon(R) CPU E5-2630 0 @ 2.30GHz

So let’s assign 2 cores and 3 GB of memory (the host has 64G so plenty to go… )

You exit twice (CTRL+D or type exit) to get back to the server you installed on.
To change the box you need to shut it down first, if you are in the folder with the Vagrant file just this command will suffice:

vagrant halt

[default] Attempting graceful shutdown of VM…

Check the status

vagrant status
Current machine states:

default poweroff (virtualbox)

The VM is powered off. To restart the VM, simply run `vagrant up`

You will find a commented line that contains “vb.customize [“modifyvm”, :id, “–memory”, “1024”]”
Uncomment this line and change the memory as you need

Thanks to this article  and this StackOverflow question I also found how to set the cores. Ending up with this configuration:

config.vm.provider :virtualbox do |vb|
# # Don’t boot with headless mode
# vb.gui = true
#
# # Use VBoxManage to customize the VM. For example to change memory:

vb.customize [“modifyvm”, :id, “–ioapic”, “on”]
vb.customize [“modifyvm”, :id, “–memory”, “3072”]
vb.customize [“modifyvm”, :id, “–cpus”, 2]
end

Note how I uncommented the config.vm.provider :virtuabox block and the end statement!

After starting and logging in, I am greeted with the following:

[root@vagrant-centos64 ~]# free -m
total used free shared buffers cached
Mem: 2887 105 2781 0 5 33
-/+ buffers/cache: 66 2821
Swap: 0 0 0

And

[root@vagrant-centos64 ~]# lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 2
On-line CPU(s) list: 0,1

Please note that not including “vb.customize [“modifyvm”, :id, “–ioapic”, “on”]” will cause the second CPU not to show up. It also seemed to slow my Box.

Good luck and please comment back if you need help.
I’ll be typing up a small article on how to include this in Jenkins.

Sources:

http://www.tecmint.com/install-virtualbox-on-redhat-centos-fedora/
http://docs.vagrantup.com/v2/installation/
http://stackoverflow.com/questions/17117063/how-can-i-create-a-vm-in-vagrant-with-virtualbox-with-two-cpus
https://coderwall.com/p/ghbzhw

Instructions unclear? Stuck on the configuration bit?
Download this Gist

 

Why I love Papertrail for remote syslog

Why log remotely?

As you move to better and more comprehensive and useful logs, you’ll find a need to run searches and maybe even alerting from these logs.
We’re probably all familiar with setting up a remote syslog server to keep the logs safe away from the server that made them.
Remote logging serves the following purposes:

  1. Secure the logs away from the server (helps in forensics as the logs can’t be wiped, or in case the server is unavailable)
  2. Aggregate logs over various machines (think access logs in clusters, or security warnings across servers)
  3. Perform searches and run analytics on these logs (like AWStat, security alerts, etc)

Number one is immediately helpful in diagnostics as it helps you figure out why a server just “disappeared” on you. (Am I looking at just a network glitch or did something break?)
As you move up to running multiple servers you want to correlate these logs and probably include alerting from one central location (so that you don’t have to define these over and over)
The main problem is obviously that you would need some kind of dedicated logging server to do this properly, preferably away from your current server farm.
While you could go out and spend more money to get a virtual server for this, I also found another interesting way..

How Papertrail gets you started on remote logging

While I’m not getting the most out of my logging yet (it’s a gradual process of refinement), Papertrail is very easy to get started and absolutely free up to 100 mb of logging per month.
Depending on how much you move into them you could put one or two servers there absolutely free.
Their next plan includes 1 GB of data per month for 7$, which is probably still cheaper than a virtual server and a lot cheaper than rolling your own.

You can read more about their product on the Papertrail website.
My favorite feature is that getting started is extremely easy, true to their 45 second promise you’ll be running remote syslog with them in a minute (maybe a bit more to set it up properly with TLS)
After that, adding a simple search and daily email allows to keep track of certain events (automated updates, rejected emails. etc) will take you maybe another 2 minutes.
This allows me to check on a daily basis what’s going on to my servers and change my security expectations based on that.

More advanced features are also available. Your alerts and events can be pushed to a webhook (POST), PagerDuty or Campfire for your alerting pleasure.

So in summary, super easy to get started. Very powerful in the future and reasonably priced (or even free depending on your log loads)
Go ahead and give it a try Papertrail and let me know if it works for you.

Fixing corrupted Spotlight index on Mountain Lion (or why is my Mac Mini so slow?)

I’ve been having a problem that was driving me insane. My trusty desktop a 2011 Mac Mini (Server edition) with Mac OS X Mountain Lion was unbearably slow when doing pretty much anything.

I thought it was the Software RAID, so I removed it. I thought it was because of the external drive (whenever a USB drive spins up, the system halts for a second, very annoying feature). So I turned it off.

After some searching I found that the likely culprit could be a corrupted Spotlight index. No idea why something simple like that would impact everything, including opening tabs in Google Chrome, but the errors in the log matched.

The thread that helped me was: mac mini running EXTREMELY slow

You should check your system logs (through the Console application) and look for the following errors (PID’s and date/times removed):

mdworker[]: Unable to talk to lsboxd
sandboxd[]: ([]) mdworker() deny mach-lookup com.apple.ls.boxd

Triggering the rebuild can be done from the command line by executing:

sudo mdutil -E /

This will start the background job of rebuilding your spotlight index.

 

I did also start my Mac in safe mode, which could have also helped.

Truncate log files without a shutdown

Anybody who handles Java applications for a living will have encountered that log from hell that keeps on growing and does not automatically roll over to a sane size. Cleaning that log is going to require you to shutdown the application since deleting it will not work.

To understand why the delete will not work you need to understand that while you might delete the inode to the file, the file descriptor to that file will still be in use. Meaning you can no longer see the file, but still see it fill up your disks and continue to grow

What I’ve learned to do is execute the following for older distros like CentOS 5 to truncate log files:

echo “” > /log/file

This will basically change the file contents to an empty string, removing all the current data in the file.
Advantage is that all filedescriptors will remain open and the file will be continue to be written to without interrupting the owning process.

Modern systems also include the truncate command, which does something similar, but much better.

So far this little trick has helped me a lot, but according to a discussion on StackOverFlow it should not.
Anybody want to clue me in why it works for me, but not everbody? Or chime in with your own experiences 🙂

Verify your package integerity with yum-verify

If you’ve been following the news you may have heard of a new backdoor that replaces your Apache binary.
While it’s a great idea to install something like Tripwire or CSF to let you know when a binary changes, ad hoc queries using yum are also possible.

A short and to the point example..

For this example we are going to “infect” the GCC binary as if we are creating a backdoored compiler

Step 1: Install yum verify

yum install yum-verify -y

Step 2: Let’s do some damage..

echo “.” >> /usr/bin/gcc

Step 3: Running and understanding yum verify-rpm

You can invoke yum verify  to check the package integerity

yum verify-rpm gcc
Loaded plugins: fastestmirror, presto, priorities, verify
==================== Installed Packages ====================
gcc.x86_64 : Various compilers (C, C++, Objective-C, Java, …)
File: /usr/bin/gcc
Problem: checksum does not match
Current: sha256:c2ddfb51a2e631e6176d550c035ab9484043a4be6732cb405a92bad3ecfd1e35
Original: sha256:173b459de91d3d08fb04ec72eafac6a3fad87c5a75bdfb381e071e48e8c16fa8
——–
Problem: size does not match
Current: 263890 B
Original: 263888 B
——–
Problem: mtime does not match
Current: Thu May 9 16:05:48 2013 (77 days, 0:29:20 later)
Original: Thu Feb 21 15:36:28 2013
File: /usr/bin/x86_64-redhat-linux-gcc
Problem: checksum does not match
Current: sha256:c2ddfb51a2e631e6176d550c035ab9484043a4be6732cb405a92bad3ecfd1e35
Original: sha256:173b459de91d3d08fb04ec72eafac6a3fad87c5a75bdfb381e071e48e8c16fa8
——–
Problem: size does not match
Current: 263890 B
Original: 263888 B
——–
Problem: mtime does not match
Current: Thu May 9 16:05:48 2013 (77 days, 0:29:20 later)
Original: Thu Feb 21 15:36:28 2013
verify-rpm done

Well there is your problem. It would seem the binary no longer matches the original hash. Please note that this tool will also flag configuration changes that you made to the original configs after install.

Step 4: Remediate the problem by reinstalling the old package

A reinstall is simple:

yum reinstall gcc
Loaded plugins: fastestmirror, presto, priorities, verify
Setting up Reinstall Process
Loading mirror speeds from cached hostfile
* base: www.fedora.is
* extras: www.fedora.is
* updates: www.fedora.is
Resolving Dependencies
–> Running transaction check
—> Package gcc.x86_64 0:4.4.7-3.el6 will be reinstalled
–> Finished Dependency Resolution

Dependencies Resolved

==============================================================================================================================
Package Arch Version Repository Size
==============================================================================================================================
Reinstalling:
gcc x86_64 4.4.7-3.el6 base 10 M

Transaction Summary
==============================================================================================================================
Reinstall 1 Package(s)

Total download size: 10 M
Installed size: 19 M
Is this ok [y/N]: y
Downloading Packages:
Setting up and reading Presto delta metadata
Processing delta metadata
Package(s) data still to download: 10 M
gcc-4.4.7-3.el6.x86_64.rpm | 10 MB 00:00
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : gcc-4.4.7-3.el6.x86_64 1/1
Verifying : gcc-4.4.7-3.el6.x86_64 1/1

Installed:
gcc.x86_64 0:4.4.7-3.el6

Complete!

 

Step 5: Verify that the package is now correct

yum verify-rpm gcc
Loaded plugins: fastestmirror, presto, priorities, verify
verify-rpm done

No output means that the packages are now fine.

gem install remote_syslog failing on CentOS 6 (ERROR: Failed to build gem native extension.)

Got this problem while installing the remote_syslog gem on CentOS 6 for pushing logs to remote syslog (for example Papertrail)
Basically running gem install remote_syslog yields the following errors:

[root@machine log]# gem install remote_syslog
Building native extensions. This could take a while…
ERROR: Error installing remote_syslog:
ERROR: Failed to build gem native extension.

/usr/bin/ruby extconf.rb
checking for rb_trap_immediate in ruby.h,rubysig.h… yes
checking for rb_thread_blocking_region()… no
checking for inotify_init() in sys/inotify.h… yes
checking for writev() in sys/uio.h… yes
checking for rb_thread_check_ints()… no
checking for rb_time_new()… yes
checking for sys/event.h… no
checking for epoll_create() in sys/epoll.h… yes
creating Makefile

make
g++ -I. -I. -I/usr/lib64/ruby/1.8/x86_64-linux -I. -DWITH_SSL -DBUILD_FOR_RUBY -DHAVE_RB_TRAP_IMMEDIATE -DHAVE_RBTRAP -DHAVE_INOTIFY_INIT -DHAVE_INOTIFY -DHAVE_WRITEV -DHAVE_WRITEV -DHAVE_RB_TIME_NEW -DOS_UNIX -DHAVE_EPOLL_CREATE -DHAVE_EPOLL -fPIC -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector –param=ssp-buffer-size=4 -m64 -mtune=generic -fno-strict-aliasing -fPIC -c pipe.cpp
make: g++: Command not found
make: *** [pipe.o] Error 127
Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/eventmachine-1.0.0 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/eventmachine-1.0.0/ext/gem_make.out

 

Well there is a duh moment.. you will need to install the package gcc-c++
yum install gcc-c++

 

Now running the install again will yield the following:

 

[root@machine log]# gem install remote_syslog
Building native extensions. This could take a while…
Successfully installed eventmachine-1.0.0
Successfully installed eventmachine-tail-0.6.4
Successfully installed syslog_protocol-0.9.2
Successfully installed em-resolv-replace-1.1.3
Successfully installed remote_syslog-1.6.13
5 gems installed
Installing ri documentation for eventmachine-1.0.0…
Installing ri documentation for eventmachine-tail-0.6.4…
Installing ri documentation for syslog_protocol-0.9.2…
Installing ri documentation for em-resolv-replace-1.1.3…
Installing ri documentation for remote_syslog-1.6.13…
Installing RDoc documentation for eventmachine-1.0.0…
Installing RDoc documentation for eventmachine-tail-0.6.4…
Installing RDoc documentation for syslog_protocol-0.9.2…
Installing RDoc documentation for em-resolv-replace-1.1.3…
Installing RDoc documentation for remote_syslog-1.6.13…

 

If it still does not work, ensure you have installed ruby-devel as well

Artisteer Bullet points showing up in Gravity forms fix

Annoyingly Artisteer takes the shotgun approach to adding it’s bullet point flair to the li tags on your website. This for example shows up as checkmarks in front of every field in your Gravity forms. Fortunately somebody named Cees shared the winning fix on the Artisteer forums.

You should add the following CSS to your theme (either as an option in Artisteer or in your style.css / client theme.

body .gform_wrapper form .gform_body ul li:before {
content: none;
}

This will properly override the li tags inside your Gravity forms and remove the content that was put in by Artisteer. Most likely a small variation of this will fix other plugins

Cheers Cees 🙂

 

Set WordPress menus based on logged in status

How do I set my WordPress Menu to be different for guests and logged in users for WordPress?
I’m sure there is a plugin to do this, but if you believe that less is more this quicky will let you alter the main navigation menu from your theme. Your best bet is to use a child theme so that your changes will persist after theme updates. This is more a quick and dirty guide to get you started.

Step 1: Create the menus

Create 2 menus under Appearance -> Menus call them logged-in and logged-out
Fill the logged-in menu with items that you want members to see and the logged-out menu with public items.

Step 2: Alter the header.php for your theme

It should be said that these pages will still be visible to users guessing the URL’s to these pages.
To properly secure your pages you should either mark them private or password protect them or use User Access Manager

Having said that, the check is relatively simple: you can check for is_user_logged_in() and switch the menu around as required..
If you’re a programmer (in any language) you will probably understand what is going on, still I’ll take this step by step.
Let’s take Twenty Twelve as an example, you will need to find the code where the navigation menu is showed. In TwentyTwelve it is this line:

<?php wp_nav_menu( array( ‘theme_location’ => ‘primary’, ‘menu_class’ => ‘nav-menu’ ) ); ?>

theme_location refers to the configuration option in your theme (under Appearance -> Menus )
menu_class specifies the correct CSS class to be used when outputting your menu.
There are many more options, all of which are explained on this Codex page

Should you for example want to only show the menu to logged in users you can change it to:

<?php
if( is_user_logged_in() ) {
    <?php wp_nav_menu( array( ‘theme_location’ => ‘primary’, ‘menu_class’ => ‘nav-menu’ ) ); ?>
}

?>

Read this as “if user is logged in, execute the following.

Or maybe you want to show the menu named “logged-out” to all guests?

<?php
if( is_user_logged_in() ) {
    <?php wp_nav_menu( array( ‘theme_location’ => ‘primary’, ‘menu_class’ => ‘nav-menu’ ) ); ?>
}

    <?php wp_nav_menu( array( ‘menu’=>’logged-out’,’theme_location’ => ‘primary’, ‘menu_class’ => ‘nav-menu’ ) ); ?>

?>

menu basically does as you expect it to do, it loads the menu with the specified name (so you need to define it under Appearance -> Menus)

Now that you have seen some simple code, you might be interested in what else you can do! Just be sure to always make backups of your site, or better yet, use a separate site to test changes.

Translating .PO files using Google translate

So you need to translate some plugin or theme to your native language and have been handed one of those pesky .pot / .po files?

You’re lucky the plugin at least supports language files, but unlucky that you now have a mountain of small lines to translate. You could download a tool like poedit and slog through the translation, but I felt there has to be a way to populate the file with at least some of the required translation, saving some of the grunt work. Fortunately Google delivers (although oddly I did not find the link through my initial google search!)

Google translate has a workbench for PO files: http://translate.google.com/toolkit/list?hl=en#translations/active

Obviously you need a Google account. This tool gives you a simple side by side workflow where you can see the original and edit the translation, but more importantly: Google will make a best effort attempt to translate your file for you!

Let’s take a wpjobboard po file as an example and upload this:

You select the orange upload option:

overview

Then you proceed to select the .PO file with the original language. Be sure to save the result as filename-nl_NL (in case of the Dutch version). If you are unsure about the correct language, check your wp-config.php file for the correct name.

upload

Once you select “upload for translation” the file will be uploaded and Google will attempt to translate the contents to the language you selected in the previous screen. This is where you go through the translations one by one to ensure they are correct.

Basically the blue entries are the ones Google believes are correct. The red entries were translated, but had some issues. Most automatic translation tools attempt to reverse translate their translations to verify. Red does not have to mean the translation is wrong, just that the system is unable to validate automatically.

translating

When you are finally done you can complete the translation. The file -> Download… gives you the resulting file. This file will need to be uploaded to the location specified by your plugin.