Pages

Tuesday, November 25, 2014

How not to program

Today, I tried to write some simple code to use #-tags in the wordpress backend. It should recognize the #tags, remove the #, add the tags to the post if they’re not present yet and, if they don’t yet exists, create those terms.
I had to dig through a lot of wordpress API documentation, Stack Overflow answers, the PHP manual for preg_replace and preg_match_all, and some simple functions I always forget the name of like strtolower or substr (I am blessed with a weak memory).

First, the code:

function ccb_quicktagsfilter( $content ) {
global $tag_ids;
$pattern = '/#(\w+)/i';
$replacement = '${1}';
preg_match_all($pattern, $content, $matches);

foreach ($matches[1] as $term) {
if (!($tid = term_exists( $term, ‘post_tag’ ))) {
$t = wp_insert_term( $term, ‘post_tag’, array(‘name’=>$term) );
$tag_ids[] = $t[‘term_id’];
}
else {
$id = get_term_by( ‘name’, $term, ‘post_tag’ );
//$id = term_exists($term);
$tag_ids[] = intval( $tid[‘term_id’]);
}
}

return preg_replace($pattern, $replacement, $content );
}
function ccb_quicktagsaction($postid) {
global $tag_ids;
wp_set_object_terms( $postid, array_unique($tag_ids), ‘post_tag’, true); //append tags
}
add_filter( ‘content_save_pre’ , ‘ccb_quicktagsfilter’,10, 1);

add_action(‘save_post’,’ccb_quicktagsaction’);

It took me a long time to get it right (and there might still be mistakes). Everybody makes mistakes, but needing hours for some simple line of code is pathetic, especially if you have a Master’s degree in computer science (sic!). I shouldn’t be doing this, I know. I want to contribute something positive to the world, I have many ideas to cultivate and a lovely daughter to raise.

So if this sounds recognizable, read on. This is for people who cannot code (or cannot code except for doing trial-and-error, which is the same).

So how did I do it? I had this idea of doing tagging in WordPress with a ‘#’ and adding the tags automatically to the database using WordPress hooks and filters. I started to search for a filter and found content_save_pre. This was one part: I needed to remove the #. This could be done with preg_replace, so I looked at the PHP manual for that function. It had many examples and comments, a lot of which was very complex and made me feel like I’m a stupid idiot and don’t deserve to live.

Anyway, I read and started to experiment with the regexps. It was not until I tried using single quotes that I got it working. The #s got stripped away using the most simple regexp

#(\w+)

. I had to figure out, by trial and error, that \w matches a word-character and not a whole word. I had to figure out that the returned $matches is an multidimensional array, and the standard flag is set so that we need the second subarray, that matches the ()-section rather than the whole thing.

The # were gone, and I had an array with my new terms. I looked at the WordPress documentation for the functions to add these tags. wp_insert_term if the tag didn’t exist yet, otherwise just mark the tag id. But I couldn’t access the $post-ID from within the filter. I googled the issue and lo and behold, there was a thread and a plugin. Someone wrote a plugin to make the postid available where it was designed not to be available.

I was lost, then thought about using a global array. Where to declare it as global? Does it work at all? Let’s test with some dummy value. Change it back. Etc.

There is an action hook save_post that should be used for this. It’s easy to write a function using wp_set_object_terms and the global tag array that was created in the filter function (that we can assume is always executed before the action hook).

Now it was ready for testing. But instead of tags the numbers showed up. It seemed like the tag id’s were converted to the slugs and names and there were bugs in WordPress core and I had to program everything from scratch and I am completely worthless. I tested again and again, refreshed browser caches and manually edited tags (this all gobbles up time). Eventually I read *somewhere* that WordPress interprets numbers as strings.

So what happened? The tags were added (after I figured out the return value for term_exists) as numbers. The $tag_ids-array should have integers as keys and the names of the tags (not the slugs – another 15 mins) as values. But when the function added the id as a string, PHP just added it to the associative array, something like ‘642’ -> null. Now WordPress was kind enough to interpret that value as a new tag with auto increment number 687, and name/slug “642”, when it didn’t ignore the string-index.

This kind of bullshit takes a long time. The particularities of WordPress and PHP are annoying, there is always something going on behind your back. Yes, I know, that is why people go for RoR or MEAN or any other clean stack.

I solved the thing by converting the value to an integer. In the process, my editor complained about the ‘${1}’ (took me a while to figure out why). How many lines of code? Just a few. Feeling like a complete moron, not worthy of anything. That sounds like a typical addiction symptom. But let’s not complain about that here, I know what I have to work on and that’s none of your business. I wanted to write about the process of coding, and how not to do it. And this is a hands-on example. Don’t do trial and error. Don’t get lost in lengthy documentation. Don’t use badly documented functions. Don’t type before you have solved the problem conceptually. Don’t fear the machine. Don’t stare at the screen. Don’t write makeshift shaggy “test” code.

I work with NotePad++, I don’t have a dedicated editor, and trial and error is the method that works fastest. But this is ridiculous. But unfortunately, it can become an addiction. When I really want to solve these little problems, like always, I bite. This biting at every bone is in my genes – I’m a mad dog.

Eventually, it seemed to work. I turned it into a plugin and will upload it to the WP repository. A piece of code that should take a seasoned programmer no longer than 20 mins to research and 10 mins to code, but took (away from) me valuable hours, in which I should have written poetry, studied anticapitalism and permaculture, hugged my wife, and do yoga.

That is how not to program.

Monday, November 24, 2014

Visualizer

I found a useful WordPress plugin called Visualizer. It renders charts (pie, bar, world map, etc).

I created a map of where I have spent my time :)
[visualizer id=”149″]

Bypassing censorship for Wordpress

I came across this cool site:
http://www.daobydesign.com/free-plugins/censortive/. Haven’t tried it out myself yet, but this can be very useful for anyone making critical postings and wants to reach internet users in China (or any other country plagued by a repressive regime).

Saturday, November 22, 2014

Flickr Fallback Thumbnails

In my last post I wrote something about a small plugin for Flickr thumbnails. Well, here it is. It’s a quick-and-dirty version that assumes everything is working (no conditionals) but well, on this site it does as you can see ;)

The class is something like this:

'names' ) );
if (count($tags)==0) return false;
$r = rand(0, count($tags)-1);
return $tags[$r];
}

function get_flickr_img ($tag, $count=1) {
$tag = urlencode($tag);
$thumb_url = “”;
$url = ‘https://api.flickr.com/services/rest/?';
$url .= ‘method=flickr.photos.search&api_key=’.$this->api_key.’&tags=’.$tag.’&per_page=’.$count;
$url .= ‘format=’.$format;

if (!wp_get_http( $url )) return;

$xml = simplexml_load_file($url);
if (!$xml) return false;
# http://www.flickr.com/services/api/misc.urls.html
# http://farm{farm-id}.static.flickr.com/{server-id}/{id}_{secret}.jpg

if (count ($xml->photos->photo)>0) {
foreach ($xml->photos->photo as $photo) {
$title = $photo[‘title’];
$farmid = $photo[‘farm’];
$serverid = $photo[‘server’];
$id = $photo[‘id’];
$secret = $photo[‘secret’];
$owner = $photo[‘owner’];
if ($count>1) $thumb_url[] = “http://farm{$farmid}.static.flickr.com/{$serverid}/{$id}_{$secret}_m.jpg”;
else $thumb_url = “http://farm{$farmid}.static.flickr.com/{$serverid}/{$id}_{$secret}_m.jpg”;
}
}

return $thumb_url;
} // get_flickr_img

function flickr_thumb_init( $html, $post_id, $post_thumbnail_id, $size, $attr ) {
if ( empty( $html ) ) {
return sprintf(
‘,
$this->get_flickr_img ( $this->random_tag($post_id) ),
get_option( ‘thumbnail_size_w’ ),
get_option( ‘thumbnail_size_h’ ) );
}
return $html;
}
} //flickr_thumb

$ft = new flickr_thumb();

?>

Todo: integrate with open calais (see tagaroo; it would be great if they would have something like an API because I don’t want to hack their plugin – it could be so much more versatile than just autotagging. This is the kind of computing we need full control of because of bandwidth usage and other issues).

Wordpress doesn't recognize plugins that have spaces in the header declaration

This one took me a while to find out – I hope this post saves you some time. I was working on a simple Flickr API plugin for WordPress (will post and use it here), but all of a sudden my plugin stopped from showing up in my (multisite) admin back-end.

So I headed over to Google and looked if anyone had the same issue. There were a lot of comments about looking at multisite admin rather than the individual network site, some remarks about the contents of the header file – but none about its very syntax.

A few extra spaces. Come on, WordPress, why do you use such a strict parser to look at the plugin directory? Why not adding that extra \s* to that regexp you use to identify plugins?

Thursday, November 20, 2014

Using dashicons in Wordpress

I was working on a theme today, and wanted to use the neat retina-ready icons we see on the WordPress back-end since version 3.8 or thereabout.

This is easy – just load the font “dashicons” in your styles-queue (thanks @Jameskoster):

add_action( 'wp_enqueue_scripts', 'themename_scripts' );
function themename_scripts() {
wp_enqueue_style( 'themename-style', get_stylesheet_uri(), array( 'dashicons' ), '1.0' );
}

…and use the icons by setting the content of the :before pseudoclass to the code. Example:

.comment-link:before {
font-family: "dashicons";
content: "\f101";
}

An overview of all available icons can be found here.

Friday, November 14, 2014

Yandex translation API

Google Translate API does a great job, but it is a paid service. For those who don’t want to spend money on machine translation, or don’t want to go through the hassle of signing up and paying recurring fees, there is an alternative: the yandex API. It works with 30 languages, including Arabic, Azerbaijani, Belarusian, Bulgarian, Bosnian, Catalan, Czech, Danish, German, Greek, English, Spanish, Estonian, Finnish, French, Hebrew, Croatian, Hungarian, Armenian, Indonesian, Icelandic, Italian, Georgian, Lithuanian, Latvian, Macedonian, Malay, Maltese, Dutch, Norwegian, Polish, Portuguese, Romanian, Russian, Slovak, Slovenian, Albanian, Serbian, Swedish, Thai, Turkish, Ukrainian, Vietnamese, Chinese.

It is an easy-to-use API: signing up and requesting an API key took me under 3 minutes. Just go to http://api.yandex.com/ and follow the instructions. It supports XML, JSON, and JSONP return string.

My English to Russian test translation, “Miru is a sweet girl”, returned

{
"code":200,
"lang":"en-ru",
"text":["Miru-сладкая девочка"]
}

Reference: http://api.yandex.com/translate/doc/dg/reference/translate.xml

Background noise

I found this simple but great idea on addcss.com. If you’re designing a “grungy” feeling web site, you can add some background noise to elements. This can easily be done with an inline transparent noise-png and a CSS-rule to set the right color.

.grunge {
background-color: #EF8;
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAUVBMVEWFhYWDg4N3d3dtbW17e3t1dXWBgYGHh4d5eXlzc3OLi4ubm5uVlZWPj4+NjY19fX2JiYl/f39ra2uRkZGZmZlpaWmXl5dvb29xcXGTk5NnZ2c8TV1mAAAAG3RSTlNAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAvEOwtAAAFVklEQVR4XpWWB67c2BUFb3g557T/hRo9/WUMZHlgr4Bg8Z4qQgQJlHI4A8SzFVrapvmTF9O7dmYRFZ60YiBhJRCgh1FYhiLAmdvX0CzTOpNE77ME0Zty/nWWzchDtiqrmQDeuv3powQ5ta2eN0FY0InkqDD73lT9c9lEzwUNqgFHs9VQce3TVClFCQrSTfOiYkVJQBmpbq2L6iZavPnAPcoU0dSw0SUTqz/GtrGuXfbyyBniKykOWQWGqwwMA7QiYAxi+IlPdqo+hYHnUt5ZPfnsHJyNiDtnpJyayNBkF6cWoYGAMY92U2hXHF/C1M8uP/ZtYdiuj26UdAdQQSXQErwSOMzt/XWRWAz5GuSBIkwG1H3FabJ2OsUOUhGC6tK4EMtJO0ttC6IBD3kM0ve0tJwMdSfjZo+EEISaeTr9P3wYrGjXqyC1krcKdhMpxEnt5JetoulscpyzhXN5FRpuPHvbeQaKxFAEB6EN+cYN6xD7RYGpXpNndMmZgM5Dcs3YSNFDHUo2LGfZuukSWyUYirJAdYbF3MfqEKmjM+I2EfhA94iG3L7uKrR+GdWD73ydlIB+6hgref1QTlmgmbM3/LeX5GI1Ux1RWpgxpLuZ2+I+IjzZ8wqE4nilvQdkUdfhzI5QDWy+kw5Wgg2pGpeEVeCCA7b85BO3F9DzxB3cdqvBzWcmzbyMiqhzuYqtHRVG2y4x+KOlnyqla8AoWWpuBoYRxzXrfKuILl6SfiWCbjxoZJUaCBj1CjH7GIaDbc9kqBY3W/Rgjda1iqQcOJu2WW+76pZC9QG7M00dffe9hNnseupFL53r8F7YHSwJWUKP2q+k7RdsxyOB11n0xtOvnW4irMMFNV4H0uqwS5ExsmP9AxbDTc9JwgneAT5vTiUSm1E7BSflSt3bfa1tv8Di3R8n3Af7MNWzs49hmauE2wP+ttrq+AsWpFG2awvsuOqbipWHgtuvuaAE+A1Z/7gC9hesnr+7wqCwG8c5yAg3AL1fm8T9AZtp/bbJGwl1pNrE7RuOX7PeMRUERVaPpEs+yqeoSmuOlokqw49pgomjLeh7icHNlG19yjs6XXOMedYm5xH2YxpV2tc0Ro2jJfxC50ApuxGob7lMsxfTbeUv07TyYxpeLucEH1gNd4IKH2LAg5TdVhlCafZvpskfncCfx8pOhJzd76bJWeYFnFciwcYfubRc12Ip/ppIhA1/mSZ/RxjFDrJC5xifFjJpY2Xl5zXdguFqYyTR1zSp1Y9p+tktDYYSNflcxI0iyO4TPBdlRcpeqjK/piF5bklq77VSEaA+z8qmJTFzIWiitbnzR794USKBUaT0NTEsVjZqLaFVqJoPN9ODG70IPbfBHKK+/q/AWR0tJzYHRULOa4MP+W/HfGadZUbfw177G7j/OGbIs8TahLyynl4X4RinF793Oz+BU0saXtUHrVBFT/DnA3ctNPoGbs4hRIjTok8i+algT1lTHi4SxFvONKNrgQFAq2/gFnWMXgwffgYMJpiKYkmW3tTg3ZQ9Jq+f8XN+A5eeUKHWvJWJ2sgJ1Sop+wwhqFVijqWaJhwtD8MNlSBeWNNWTa5Z5kPZw5+LbVT99wqTdx29lMUH4OIG/D86ruKEauBjvH5xy6um/Sfj7ei6UUVk4AIl3MyD4MSSTOFgSwsH/QJWaQ5as7ZcmgBZkzjjU1UrQ74ci1gWBCSGHtuV1H2mhSnO3Wp/3fEV5a+4wz//6qy8JxjZsmxxy5+4w9CDNJY09T072iKG0EnOS0arEYg! XqYnXcYH wjTtUNAcMelOd4xpkoqiTYICWFq0JSiPfPDQdnt+4/wuqcXY47QILbgAAAABJRU5ErkJggg==);
}

@import in CSS: no space

I tortured myself over a particular piece of emptiness. Not the existential void we’re thrown in by our creator, but the space I put before url in


@import url ("../twentytwelve/style.css");

This is for wordpress stylesheet development, and with the space, the child theme doesn’t load up the parent style.css. I just corrected it to


@import url("../twentytwelve/style.css");

and it’s working fine. I hope that this post if useful for whoever just stumbled upon it.

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Lady Gaga, Salman Khan