Autodeployment with Bitbucket

De Anleitung:
Eine weitere Anleitung:

hook Skript

config bis hierher:

$CONFIG = array(
 'gitCommand' => 'git', // Git command, *REQUIRED*
 'repositoriesPath' => '/www/htdocs/w0121b1e/repos', // Folder containing all repositories, *REQUIRED*
 'log' => true, // Enable logging, optional
 'logFile' => 'bitbucket.log', // Logging file name, optional
 'logClear' => true, // clear log each time, optional
 'verbose' => true, // show debug info in log, optional
 'folderMode' => 0755, // creating folder mode, optional

// List of deployed projects:
$PROJECTS = array(
 'skurrilewelt/bvbtheme' => array( // The key is a repository full name *REQUIRED*
 'master' => array(
 'deployPath' => '/www/htdocs/w0121b1e/bvb/templates/bvb', // Path to deploy project, *REQUIRED*
 'postHookCmd' => '', // command to execute after deploy, optional


Problem 1: Es war ein Verzeichnisschutz auf dem Server – Bitbucket konnte das Skript nicht aufrufen
Nachdem der beseitigt war, gab es folgenden Logeintrag nach dem pushen:

2017.12.07 08:19:35 *** repo:push #d44c8c5e-36e5-46ec-bc71-c35ef91bc954 (Bitbucket-Webhooks/2.0)

2017.12.07 08:19:35 remote addr: 2017.12.07 08:19:35 Valid payload was received 2017.12.07 08:19:35 ERROR: Not found repository config for ‘bvb-nachhaltigkeit/bvbtheme’!

Änderung des Reponamens in der config: hier muss offensichtlich der Teamname rein. Die URL von Bitbucket sieht aber genauso aus – also genau das eintragen.

Nach dem pushen steht im Log folgendes:

2017.12.07 08:30:30 *** repo:push #d44c8c5e-36e5-46ec-bc71-c35ef91bc954 (Bitbucket-Webhooks/2.0)

2017.12.07 08:30:30 remote addr: 2017.12.07 08:30:30 Valid payload was received 2017.12.07 08:30:30 Changes in branch ‘master’ was fetched 2017.12.07 08:30:30 CONFIG: Array ( [gitCommand] => git [repositoriesPath] => /www/htdocs/w0121b1e/repos [log] => 1 [logFile] => bitbucket.log [logClear] => 1 [verbose] => 1 [folderMode] => 493 ) 2017.12.07 08:30:30 REPO: bvb-nachhaltigkeit/bvbtheme 2017.12.07 08:30:30 repoPath: /www/htdocs/w0121b1e/repos/bvbtheme.git 2017.12.07 08:30:30 BRANCHES: Array ( [0] => master ) 2017.12.07 08:30:30 Fetching repository ‘bvb-nachhaltigkeit/bvbtheme’ 2017.12.07 08:30:30 cmd: cd /www/htdocs/w0121b1e/repos/bvbtheme.git && git fetch 2017.12.07 08:30:31 ERROR: Cannot fetch repository ‘bvb-nachhaltigkeit/bvbtheme’ in ‘/www/htdocs/w0121b1e/repos/bvbtheme.git’!

Der Wechsel ins Verzeichnis funktioniert. Beim manuellen Aufruf des Kommandos fragt Bitbucket aber nach dem Passwort. Problem schein die Authentifizierung mit dem Key zu sein. Also nochmal zurück zur ssh key config, die folgenden Inhalt hat:

IdentityFile bitbucket

Sowohl die Keys als auch die config liegen im server root. Ein .ssh Verzeichnis lies sich nicht oberhalb von root anlegen.

Also direkt in ssh server root dann in das Verz. .ssh und dort

ssh-keygen -t rsa neue Schlüssel erstellen und dort mit vim die config anlegen und mit :w config speichern und mit :q beenden. (ESC wechselt vom Einfüge in den command mode)

Inhalt erstmal genauso wie vorher. Den Schlüssel .pub in vim geöffnet und bei bitbucket als access Key gespeichert.

Config geändert in:

IdentityFile ~/.ssh/bitbucket_rsa

With no luck. Message was once again ‘cannot fetch’.

Strato and it’s Security

Some of my clients do such incredible things as using Strato as their webhoster. I can’t understand that because there are so much webhosters with resonable offers out there in the world.

Today I stumbled over an interesting behavoir: After some changes in a user account my browser prompted me to download the profile.php. Okay – I saved this file and looked into. It shows me taht the server responsed with 503 Service unavailable message. I was completely at sea so I digged into the net and found out that Strato has a very special security option. Strato counts multiple requests to php scripts and after x-times within x seconds ( I can’t figure out the exact values) Strato blocks this requests. Wow – this is cool. After opting out this feature everything worked fine.

The official explanation points out that spam robots calls script files periodically and this feature will enhance your security.

How good that usual administrators don’t call php scripts more than once.

You will find this option here:

DeepL automatic translations

Deepl is a great tool to translate texts into other languages. The translations are precise and Deepl is able to deal with linguistic nuances and meanings quite well. All in all, the translations are almost perfect. In short: Optimal for solving automatic translations with a plugin.

Look out:

more to come in the next weeks.

Update 2018-2:

I have contacted deepl, but have not received an answer yet. You will need an API key to get translations und it will be restricted and a payed service.

Useful: Set templates for all WordPress pages programatically

Come across this little snippet while I’m searching for a solution to change all page templates from default to a custom one. I didn’t want to change the default template in general either change the page template itself – but only change the template setting for all pages yet created.

This solutions rewrites all post meta entries in the database with the value  ‘_wp_page_template’ if they differ from my desired setting.

add_action( 'admin_init', 'set_page_templates' );

function set_page_templates(){

    foreach( get_posts('post_type=page&posts_per_page=-1') as $page ) {
        $current_template = get_post_meta( $page->ID, '_wp_page_template', true );
        $new_template = 'home-panels.php'; // Change home-panels.php to your template file name

        if( $current_template != $new_template ) {
            update_post_meta( $page->ID, '_wp_page_template', $new_template );

Put this in yout theme’s functions.php, reload the backend and remove this code afterwards.

Found here:

By the way:

Changing the preselected entry in the metabox ist easy also, so every newly created page will get this as template:

function set_default_page_template() {
    global $post;
    if ( 'page' == $post->post_type
        && 0 != count( get_page_templates( $post ) )
        && get_option( 'page_for_posts' ) != $post->ID // Not the page for listing posts
        && '' == $post->page_template // Only when page_template is not set
    ) {
        $post->page_template = "home-panels.php"; // Change home-panels.php to your template file name
add_action('add_meta_boxes', 'set_default_page_template', 1);

Put this in your theme’s functions.php, that’s all. Don’t know, where I found this but it’s useful also.



Polylang Copy Updated

Polylang Copy is now in version 1.1.0. Goto Bitbucket and get the new version.

I’ve just added support for automatic translations! From now on you can decide if you like to translate only certain posts or pages in a particular language or switch to auto mode. Then every new created post or page will be translated immediately into all available languages considering allready existing translations.

Some screenshots:

Find new settings panel for Polylang copy

Decide which method you prefer:

In single translating mode you will get a dropdown below every entry’s quickedit menu

Any suggestions and bug reports welcome.


New Free WP Plugin: Polylang Copy

Sometimes work is boring and inefficient. While I was working on the relaunch of ClientSolutions website I had the idea to make copying of posts and pages to other languages more easy.

If you use Polylang (thanks for this great plugin) for translating your wordpress page too, you maybe interested in using my little plugin. It will add a dropdown to each row action in posts, cpt or page listings from which you can select a language to translate a post or page in. After that you will be redirected  to the edit screen.

Polylang Copy makes an exact copy of the item, including featured image, categories and tags. If there are translations of categories or tags they will be used instead of original cats or tags.

That’s all.

Updated: See this post for more information.

Developer Tools: Debug :hover etc. in Chrome

Did you ever try to get a css style for a hovered or active button or link? Today I tried to figure out, why the bootstrap btn-success don’t accepts my :active state style. Searching for a way to get this brings me to the simple solution:

Open developer tools in chrome (ctrl-shift-i or F12), select  the element (crtl-shift-c or the most left button in the menu bar) and then see this:


Click on the dotted button to get the context menu for this element:


Select the states you need and you will see the corresponding style in the style window and on the webpage.

In my case it was the combination of to states:


and not only :active.

Free Plugin: get-image

get-image – serve (tracking) images via php

get-image is intended to serve images from your wordpress installation to any other site via php as base64 encode image tag source. It includes rudimentary statistic to see, how often this image has been served.

What can you do with it?

Place it on other sites in your blog posts, place it as email footer logo in your emails or something else and see, how often this image is downloaded in total and in the current month. Since this small piece of code is open source feel free to enhance it’s functions and create pull requests on or create issues in the issue tracker. Every comment is helpful and welcome.

How it works

Backend is short and easy. Here is the list view:


You can see the menu item ‘Request’ and the list view shows the already created items with title, image and the counts column. Every entry represents an image which can be served.

The edit view shows this:


You can enter a title to identify a little bit later an additionally short description. Then you can choose or upload an image and after that you will see in the text box the img tag which you have to place where the image should appear.

Thats all.

get-image creates a rewrite rule which manages the redirecting and responding the image as base64 encoded data.


Don’t know. Use it and have fun, you can download or clone here:


Duplicator ( LifeInTheGrid) SQL-Fehler

Der WordPress Duplicator ist ein Supertool, wenn man eine live oder lokale Wordpress Installation umziehen bzw. deployen möchte. Es gibt aber hier und da einige Schwierigkeiten und Fallstricke.

Im aktuellen Fall wollte ich ein live Projekt vom Kundenserver lokal duplizieren, um daran zu arbeiten. Duplicator meldete mir keine wesentlichen Fehler und erstellte problemlos das Archiv.

Bei der Installation auf meinem lokalen System allerdings stieg der Duplicator beim Einspielen des Datenbank Dumps aus. Ein Blick in die log Datei von Duplicator zeigte, dass das Erstellen der Tabellen bereits fehl schlug. Nachdem ich die MySQL Versionen überprüft hatte (live 5.5.28 und lokal 5.5.32) konnte das nicht das Problem sein.

Ich habe mir dann in der lokalen Installation die Datei database.sql angeschaut. Das Problem war die falsche Create-Anweisung im SQL Dump:

CREATE TABLE `wgo_options` (
 `option_id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
 `option_name` varchar(191) NOT NULL DEFAULT '',
 `option_value` longtext NOT NULL,
 `autoload` varchar(20) NOT NULL DEFAULT 'yes',
 PRIMARY KEY (`option_id`),
 UNIQUE KEY `option_name` (`option_name`)

Die MySQL Doku sagt: TYPE keyword is depreciated (since 5.0) and not supported in MySQL5.5. Scheint also ein Bug in Duplicator Version 1.1.16 zu sein.

Aus dem heruntergeladenen Archiv die database.sql extrahieren und aus dem Archiv löschen. In Notepad++ TYPE gegen ENGINE getauscht und wieder ins Archiv hineinkopiert.

Bevor man jetzt die Installation erneut starten kann, muss die wp-config.php gelöscht werden, da Duplicator sonst (korrekterweise) den Fehler meldet, die Datei wäre bereits vorhanden, Das Duplicator die vorhandene wp-config.php nicht überschreibt, ist prinzipiell eine gute Sache.

Ein anderer Weg ist, Duplicator mitzuteilen, dass die Dateien manuell entpackt werden:


Danach läuft die Installation problemlos und die Datenbank kann installiert und migriert werden.