Matt Mullenweg is Wrong. Thesis Should Carry Whatever License It Wants.

There is a debate underway about the legality of Thesis, a popular, paid for WordPress theme, using a different license than the one WordPress uses, which is the GPL. Matt Mullenweg, founder of WordPress, contends that all themes for the platform should inherit the WordPress license and should be considered a part of the platform. Chris Pearson, creator of Thesis, obviously has a different opinion. There have been many heated debates over the topic, but I haven’t heard an argument by either side that is compelling one way or the other.

My opinion, which I obviously think is compelling, though is not in any way rooted in any facet of the law or articulated in any legalese whatsoever, is that Matt Mullenweg is wrong. I love what Matt has done. I use and love the WordPress platform. I also think that his position is noble and rooted in the greater good for the WordPress community and open source in general.

I think what has been overlooked in his argument is an assumption we have about software, namely how it is supposed to work and what defines working software in relation to a pluggable software stack, such as WordPress. Technically, I could create an empty my-new-index.php file, place it inside the WordPress directory structure, and I have extended the platform. According to Matt, my software which does nothing, must inherit the WordPress license. Now if I want to sell (or redistribute) this do nothing piece of software for $50.00 (available upon request) I must also sell it with the GPL license. So technically, any piece of PHP code can placed inside of the WordPress directory structure and therefore, all PHP code must also carry the WordPress license!?!

There is obviously some rational limit and discretion available to us so that this sort of thing won’t ever happen!  We could say because the Thesis theme makes use of the WordPress API, it must be intended for use with WordPress. However, the WordPress API is a bunch of PHP functions and WordPress  itself uses the PHP API, which carries a different license (The PHP License). Which one takes precedence (if they were conflicting) ? Do all PHP applications, because they all must, by definition, use the PHP API, have to inherit the PHP License? This would be ridiculous and I’ve never seen a PHP app with the PHP license, so clearly using an API can’t include licensing requirements, so long as you aren’t modifying and redistributing the original API itself. For example, if I use a PEAR class, I don’t have to inherit the license for all of my work, I just can’t change the license of that class and or modify the original code without making it available again.  Thesis doesn’t (to my knowledge) modify or extend any of the WordPress core. It provides interface enhancements, outputted HTML generated not by WordPress, but by Thesis. WordPress just consumes the Thesis software because it exists in a certain location, placed by someone into the WordPress directory structure.

This is the nature of pluggable systems, or software stacks. They are meant to be interoperable with other pieces of software whose parts and purposes are not known ahead of time. This covers a lot of space, space that isn’t even in existence and which it would, if Matt were correct, claim licensing rights to, in the event “it” comes into existence and “works” with said piece of software. Clearly Thesis “works” with WordPress. But so does a blank file. I intend for that file to do nothing, and it performs (quite efficiently) that task!

At the end of the day, it is only because Thesis is marketed to the WordPress community and is intended to be used with the WordPress platform, that there is an argument about how the software should be licensed. But Thesis is not sold bundled with WordPress, nor is anyone who purchases it required to use it with WordPress. For all intents and purposes, it is a stand alone piece of code, that well, does nothing important or worthwhile. Can you really license functionality that may or may not exist depending on how the purchaser decides to implement their purchase, just like my overpriced(though well worth the investment), blank PHP file could be used in any PHP application?

I have a lot of questions (I haven’t read all the licenses either, so I may be in total error :). Though from what I’ve read and heard so far, it is only because we have an expectation of how the software will work when it is in the WordPress directory structure that there is a conflict with how Chris has licensed Thesis. This expectation is set by the marketing of the software, not necessarily the software itself. Aside from Trademark infringement, does the language used to sell a product carry over into the the actual license the code must carry? This wouldn’t make sense. Say for instance, “Runs on Windows”, would require another license too?

I think we’re going to see a lot more arguments over licensing conflicts like what we’re seeing with WordPress/Thesis. Software is the biggest it has ever been. Open Source software is integrated into the business world like never before and business models are built on top of many of the various projects which are out there, “free” to use. As this space expands, no doubt more and more gray areas will as well.

On a practical note, what would stop Chris from writing a simple wrapper around the WordPress API his files use, license this with the GPL, use his wrapper functions instead from inside Thesis and then keep the current Thesis license?

Get Child Categories of Parent Category on Single Post in WordPress

I was hoping to find a function in the WordPress API, that goes something like this…

  the_child_categories("Vermont");
  // print Burlington, Brattleboro... etc if this post has any child categories of Vermont

But I could not. The result that I did find, from various forums goes something like this…

$parentcat = get_category_by_slug('Vermont');
foreach((get_the_category()) as $childcat):
  if (cat_is_ancestor_of($parentcat, $childcat)):
    echo get_category_link($childcat->cat_ID);
    echo $childcat->cat_name;
  endif;
endforeach;

If you’re in the in the Loop, you can use the get_the_category() function to retrieve the category objects of the current post, without printing the results to the screen. You can loop over the contents from what is returned by the function.

This condition uses the API function “cat_is_ancestor_of” to check whether or not the category from the current post is a child of the parent which we fetched with the “get_category_by_slug” function.

Here is a little function that I threw into “functions.php” so that I can get the child categories easily in my theme.

/** Usage
_the_category_children("Vermont"); */
function _the_category_children($slug=""){
  if($categories       = get_the_category()):
    if($slug_category   = get_category_by_slug($slug)):
      foreach($categories as $category):
        echo (cat_is_ancestor_of($slug_category, $category)) ? $category->cat_name : '';
      endforeach;
    endif;
  endif;
}

More info/references on accomplishing this functionality are available
http://codex.wordpress.org/Function_Reference/cat_is_ancestor_of
http://wordpress.org/support/topic/284057?replies=8#post-1120489
http://wordpress.org/support/topic/297615

How To Flush Your Permalink Structure in WordPress When Using Taxonomies …or WordPress Taxonomies Not Working Instead I See A 404 Page

I didn’t know this, but because of a linking problem using custom taxonomies in WordPress, I was forced to find out. If you create a new taxonomy, it will not work immediately on the front facing end. Your users will be greeted by a 404, page not found instead. This isn’t ideal for obvious reasons.

You create and/or register custom taxonomies like so. You may have multiple taxonomies.

add_action('init', 'create_my_taxonomy', 0);
function create_my_taxonomy(){
  register_taxonomy( 'musicians',
    'post',
    array(
      'hierarchical' => false,
      'label' => 'People who play lovely music that I like...',
      'query_var' => 'musicians',
      'rewrite' => array('slug'=>'musicians')
    )
  );
}

In your theme directory you need at “taxonomy.php” file. This will catch your custom taxonomy requests. You can get even more fancy and create a file like so “taxonomy-musicians.php” which you can use to differentiate your taxonomies look/feel. Nice and slick… however, you may be frustrated after following these two steps and be greeted with a friendly 404 page not found template instead.

Fear not, you need only visit the Admin >> Settings >> Permalinks page as a logged in admin to flush your rewrite rules and get linking and your correct custom taxonomy template file. Straight forward, unless if you didn’t know that merely visiting the Permalinks Settings page would correct the problem. But Alas, you do!

Addendum

You must also have posts using the taxonomy! Otherwise, you will still get the page 404 not found! I’m not sure if there is a work around for this at the moment. Anyone know?

20 May 2010, 10:27am
Projects:
by

leave a comment

Natural Dog Training

Natural Dog Training uses WordPress to run a blog and content management system.
more »

Programmatically Turn Off Comments in WordPress with Filter

To turn comments off programmatically with a filter in WordPress, you can set the post object’s comment_status variable to “closed”. Call the filter at some point after the post is loaded but before the comments are rendered. This is a hack, but I haven’t seen a simpler approach, beside installing another plugin. In the example below, the condition to disable comments is simple. If a post is in a certain category, comments aren’t allowed. Otherwise, go ahead and behave as normal. You can still disable comments on a per post basis in other categories.

One thing to note is the use of the global $post object. The function needs access to the object to set the variable.

add_filter('get_header', 'sb_turn_comments_off');
function sb_turn_comments_off(){
    if(in_category("Projects") AND is_single() ){
      global $post;
      $post->comment_status="closed";
  }
}

I’ve only tested this with the Thematic framework. I assume that other themes will check the comment_status variable before allowing comments.

Intercepting the WordPress Loop with Pre_get_posts

#deprecated (see http://codex.wordpress.org/Function_Reference/query_posts#Post_.26_Page_Parameters)

Using the “pre_get_posts” filter you can intercept the WordPress loop and override or set attributes in the “$query” object. This is useful because you can select just the posts you want, say for instance on your homepage you want to show posts from just one category.

add_filter('pre_get_posts', 'filter_homepage_posts');
function filter_homepage_posts($query) {
    $limit_number_of_posts = 5;
    $featured_category_id = get_cat_id('Reviews'); // by cat name...
    if ($query->is_home) {
        $query->set('cat', $featured_category_id);
        $query->set('showposts', $limit_number_of_posts);
    }
  return $query;
}

Thematic Function Reference

I could not find a listing of all thematic theme functions for WordPress online. So the following is just a recursive grep of the thematic directory.

grep -rh "function thematic_" *

Each function needs to prepended with “thematic_” when adding as a action or filter eto a WordPress childtheme. Example

function my_function_says_hello(){ print "Hello!"; }
add_filter('thematic_abovepagebottom', 'my_function_says_hello');

Here is the list

remove_generators()
abovecomments()
abovecommentslist()
belowcommentslist()
abovetrackbackslist()
belowtrackbackslist()
abovecommentsform()
show_subscription_checkbox()
belowcommentsform()
show_manual_subscription_form()
belowcomments()
singlecomment_text()
multiplecomments_text()
postcomment_text()
postreply_text()
commentbox_text()
commentbutton_text()
commenter_link()
comments_template()
include_comments()
abovecontainer()
archives()
navigation_above()
navigation_below()
above_indexloop()
archiveloop()
authorloop()
categoryloop()
indexloop()
searchloop()
singlepost()
tagloop()
below_indexloop()
above_categoryloop()
below_categoryloop()
above_searchloop()
below_searchloop()
above_tagloop()
below_tagloop()
belowcontainer()
page_title()
nav_above()
archive_loop()
author_loop()
category_loop()
index_loop()
single_post()
search_loop()
tag_loop()
time_title()
time_display()
postheader()
postheader_posteditlink()
postheader_posttitle()
postheader_postmeta()
postmeta_authorlink()
postmeta_entrydate()
postmeta_editlink()
content()
archivesopen()
category_archives()
monthly_archives()
archivesclose()
404()
404_content()
postfooter()
postfooter_posteditlink()
postfooter_postcategory()
postfooter_posttags()
postfooter_postcomments()
postfooter_postconnect()
nav_below()
previous_post_link()
next_post_link()
author_info_avatar()
cats_meow($glue)
tag_ur_it($glue)
comments($comment, $args, $depth)
pings($comment, $args, $depth)
body_class( $print = true )
post_class( $print = true )
comment_class( $print = true )
date_classes( $t, &$c, $p = '' )
abovefooter()
footer()
footertext($thm_footertext)
belowfooter()
after()
subsidiaries()
siteinfoopen()
siteinfo()
siteinfoclose()
create_doctype()
head_profile()
doctitle()
create_contenttype()
seo()
canonical_url()
use_excerpt()
use_autoexcerpt()
create_description()
show_description()
create_robots()
show_robots()
create_stylesheet()
show_rss()
show_commentsrss()
show_pingback()
show_commentreply()
head_scripts()
add_menuclass($ulclass)
before()
aboveheader()
header()
brandingopen()
blogtitle()
blogdescription()
brandingclose()
access()
belowheader()
trim_excerpt($text)
the_excerpt($deprecated = '')
excerpt_rss()
tag_query()
sidebar()
abovemainasides()
betweenmainasides()
belowmainasides()
aboveindextop()
belowindextop()
aboveindexinsert()
belowindexinsert()
aboveindexbottom()
belowindexbottom()
abovesingletop()
belowsingletop()
abovesingleinsert()
belowsingleinsert()
abovesinglebottom()
belowsinglebottom()
abovepagetop()
belowpagetop()
abovepagebottom()
belowpagebottom()
abovesubasides()
belowsubasides()
subsidiaryopen()
before_first_sub()
between_firstsecond_sub()
between_secondthird_sub()
after_third_sub()
subsidiaryclose()
search_form()
widgets_init()
sort_widgetized_areas($content)
primary_aside()
secondary_aside()
1st_subsidiary_aside()
2nd_subsidiary_aside()
3rd_subsidiary_aside()
index_top()
index_insert()
index_bottom()
single_top()
single_insert()
single_bottom()
page_top()
page_bottom()
before_widget_area($hook)
after_widget_area($hook)
before_widget()
after_widget()
before_title()
after_title()

Thematic is a nice theme framework for WordPress. More info is available at the developers website ThemeShaper. Using the above filters it is possible to create a highly customized child theme quickly.

Install and Serve a Rails Application from PHP Subdirectory Using Apache, Phussion Passenger and Ruby Enterprise Edition

Here is how to install a Rails application out of a subdirectory (rather than as a subdomain) with the Apache web server(Apache2). In this example I’m going to use my own blog which is a WordPress installation and serve a Rails application from the subdirectory “reader”. Note, I’m not going to keep my Rails application in the document root of my WordPress Blog, which is a PHP application and therefore anyone could browse the ruby source code :(. I’ll keep it elsewhere on the filesystem and tell Apache about the location in the VirtualHost file.

You can visit the application by going to http://seanbehan.com/reader. The application just parses a bunch of RSS feeds and displays them.
It uses the Feedzirra library, which I’ve also written about http://seanbehan.com/ruby-on-rails/installing-feedzirra-rss-parser-on-ubuntu-8/.

I’m using Phussion Passenger and Ruby Enterprise Edition from the folks at Mod Rails. Installing both Phussion Passenger and Ruby Enterprise Edition is simple and a very well documented process. However, you’ll need to download and compile them from source. If you install Ruby Enterprise Edition (REE) it comes w/ Passenger so you won’t need to download it separately. I recommend going with REE. http://www.rubyenterpriseedition.com/download.html

Installing Ruby Enterprise Edition

Here are the commands to download and install (change the X.X.X to the package you’ve actually downloaded).

wget http://rubyforge.org/frs/download.php/68719/ruby-enterprise-1.8.7-2010.01.tar.gz
tar xzvf ruby-enterprise-X.X.X.tar.gz
./ruby-enterprise-X.X.X/installer

When you run the installer you’ll be prompted for an installation location. Just hit enter to install in the default location. Follow the instructions from there and remember to copy/paste any code that they give you.

Official Instructions on installation for Passenger on its own are available here http://www.modrails.com/install.html I’ve written about setting up an entire box w/ Passenger here http://seanbehan.com/ruby-on-rails/new-ubuntu-slice-apache-mysql-php-ruby-on-rails-git-and/ If you already have Passenger installed and want to use REE just download and install REE and it’ll recompile Passenger with REE support if you follow the instructions.

*** If you install REE you’ll need to either link or reinstall all your gems. I linked the REE gem with the one in /usr/bin so that I can run gem install and REE will be aware of it.

ln -s /opt/ruby-enterprise-X.X.X/bin/gem /usr/bin/gem

The VirtualHost

If you have Passenger and REE successfully installed you’ll need to modify your VirtualHost file and add Rails application information to it.

<VirtualHost *>
  # Normal virtual host info
  ServerName seanbehan.com
  ServerAlias *.seanbehan.com
  DocumentRoot /var/www/seanbehan.com/wordpress

  # Rails info goes here
  Alias /reader /var/www/seanbehan.com/reader/public
  <Location /reader>
    PassengerAppRoot /var/www/seanbehan.com/reader
    RailsEnv production
  </Location>
</VirtualHost>

The “Location” directive tells apache to forward requests starting with /reader to the directory
/var/www/seanbehan.com/reader/public which is the location of our Rails app. However, we need to add the PassengerAppRoot assignment so that it knows where the actual application lives.

Routing in Rails with Relative Path

And finally, your Rails application will need to be aware of the relative url prefix assigned to each route. Normally, you could do this w/ the :path_prefix at the individual route level like so

map.resources :feeds, :path_prefix => "reader"

This will work but you can add a line to your RAILS_ROOT/config/environments/production.rb file which will handle all your routes for you. This way you don’t need to setup a relative path on your development environment work.

# in RAILS_ROOT/config/environments/production.rb
config.action_controller.relative_url_root = '/reader'

Final Thoughts

Remember Ruby Enterprise Edition is the new Ruby Interpreter that your Rails web applications are using. If you
have any gem or rake issues make sure that you’re using the same interpreter that REE is using. Look in the location
installation of REE “/opt/ruby-ent…” bin/gem or bin/rake and see if that helps. I just linked those to the standard /usr/bin/gem and /usr/bin/rake and everything worked fine.

Also I’ve read some people have trouble using the alias with passenger. This may be an older issue but works for me without a problem on Ubuntu (latest).

Here are some useful resources I found along the way…

http://robots.thoughtbot.com/post/159806388/phusion-passenger-with-a-prefix

http://www.modrails.com/documentation/Users%20guide.html#deploying_rails_to_sub_uri

http://www.modrails.com/documentation/Users%20guide.html#RailsBaseURI

http://stackoverflow.com/questions/848258/server-prefix-and-rails-routes

TinyMCE Rich Text Editor: HELLO EDITOR Plugin Tutorial and Example

I wanted to create a button for the TinyMCE Rich Text Editor for WordPress. It was tough to find good docs on the subject. There are a couple of useful posts out there but in general I found them lacking.

http://codex.wordpress.org/TinyMCE_Custom_Buttons#Creating_an_MCE_Editor_Plugin

The above resource has a good section on the PHP code needed to write your own callbacks but there is no mention of the JavaScript required to create a button and interact with it. Links are available for more reading but why not also post a code sample to get up and running?

Anyway, I made a simple plugin after hobbling a bunch of resources together to get a button in the text editor that when clicked triggers an alert to the window. The code isn’t fancy but it might provide a starting off point for a larger project or be useful as a resource for some of the basic ideas involved. I read through a couple of the sample plugins included with WordPress along with the Viper Video Quicktags Plugin, which makes extensive use of the feature. However, they were too complex for a quick, basic understanding.

This plugin doesn’t do a lot. I’ll probably flesh it out a bit more when I have a clearer understanding of how it all works. For now here are some code samples and at the bottom of this post there is a link to the .zip file for the plugin which you can install on your own site.

In wp-content/plugins/hello_editor/index.php

<?php
/*
Plugin Name: Hello Editor
Plugin URI: http://seanbehan.com/wordpress/tinymce-rich-text-editor-hello-editor-plugin-tutorial-and-example/
Description: A simple plugin showing how to add a button to the rich text editor in WordPress.
The plugin doesn't do anything except place a button and respond to onclick event, with "Hello Editor".
Most of the editor plugins available are too 'functional' to quickly read and see how to do the
basics. This plugin doesn't 'do' anything, rather it makes it simple to read what is going on.
Version: 0.1
Author: Sean Behan
Author URI: http://seanbehan.com
*/

define( "HELLO_EDITOR_PLUGIN_DIR", "hello_editor" );
define( "HELLO_EDITOR_PLUGIN_URL", "/wp-content/plugins/" . HELLO_EDITOR_PLUGIN_DIR );

// Register the external pllugin from the .js file
function hello_editor_register_external_plugin($plugin_array) {
  $plugin_array['HELLO_EDITOR'] = HELLO_EDITOR_PLUGIN_URL . '/editor_plugin.js';
  return $plugin_array;
}

// Add the button to the array ***NOTE*** The name here "HELLO_EDITOR" must
//match the name in the editor plugin file for the addButton(name_of_button) function!
function hello_editor_register_button($buttons) {
  array_push( $buttons, "|", "HELLO_EDITOR" );
  return $buttons;
}

// Filters which will call our functions
function hello_editor_init(){
  add_filter("mce_external_plugins", "hello_editor_register_external_plugin");
  add_filter('mce_buttons', 'hello_editor_register_button');
}

// When the editor is initialized
add_action('init', 'hello_editor_init');

In wp-content/plugins/hello_editor/editor_plugin.js

(function() {
  //Init the plugin
  tinymce.create('tinymce.plugins.HELLO_EDITOR', {
    init : function( ed, url ) {
    //addButton name needs to match $plugin_array['HELLO_EDITOR'] in add_filter function
    ed.addButton('HELLO_EDITOR', {
      title : 'Hello Editor',
      image : url + "/buttons/hello.png",
      onclick : function(){
        alert("HELLO EDITOR!");
      }
    });
  },
  //Info about the plugin
  getInfo : function() {
    return {
      longname : "Sean Behan's Sample Hello Editor Plugin",
      author : 'Sean Behan',
      authorurl : 'http://www.seanbehan.com/',
      infourl : 'http://seanbehan.com/wordpress/tinymce-rich-text-editor-hello-editor-plugin-tutorial-and-example/',
      version : "0.1"
    };
  }
});
tinymce.PluginManager.add('HELLO_EDITOR', tinymce.plugins.HELLO_EDITOR);
})();

You’ll also need a directory called buttons inside the hello_editor plugin directory with a hello.png file which will be displayed. Without it you’ll just get a blank button. You can rename this but remember to change the name in the editor_plugin.js file as well.

You can download the sample plugin here http://seanbehan.com/wp-content/uploads/2009/11/hello_editor.zip