Hacking on GNU social: Unicode Smileys

As you probably know already, GNU social is a GNU Affero licensed microblogging server software written in PHP that implements the OStatus protocol, an open standard for distributed status updates.

Everyone can deploy her own server and follow people in her own server or any other, as I explained here https://www.fsf.org/blogs/community/thousands-of-spaniards-leave-twitter-for-gnu-social.

I have run my own server for quite a long time, and the time to make some contribution back to this great software has come! I always thought that it would be great to take advantage of Unicode characters to insert some emojis in GNU social notices. You can always copy and paste these entities (http://unicode-table.com/en/) but the experience is better if that feature is integrated, so I decided to create a plugin.

Where do I start to hack

The best way to start is to follow best practices. These practices are translated into code in a plugin named Sample that is distributed along with the server. That Sample plugin can be found here.

A GNU social plugin is a mix of PHP, jQuery, Javascript, HTML and CSS code. The PHP engine define a great deal of “hooks”. You can chain your actions to these hooks so as to integrate your own code into the main code. Hooks are defined in the file EVENTS.txt.

The essential part is a PHP file that defines a class that inherits from Plugin. So we start with this:

class SmileysUnicodePlugin extends Plugin

You don’t really start with a blank class, because you can copy standard methods from the sample plugin, but make sure you understand what you are copying and why. Each request to a GNU social server can be seen as a dialog between the main engine and the plugins:

Engine: I have created the main header, have you got something to do?
Plugin: nope!
Engine: I have created the main navbar, have you got something to insert?
Plugin: no, sir
Engine: Well, I’ve spitted out my jQuery files, anything to add?
Plugin: Certainly! Please add references to these files!

This is done because we implement a method like this:

function onEndShowJQueryScripts(Action $action)
//This is the file to modify if you want to add or remove unicode sets
//This is the plugin main jQuery file

If you reveal the source code of the final page, you will see references to these two files. There is a similar method to insert your own CSS code (onEndShowStyles).

Third party plugins are installed normally in [GNU Social root]/local/plugins. With a file for the plugin main class named SmileysUnicodePlugin.php that defines a class SmileysUnicodePlugin extending Plugin, that defines these two methods (onEndShowJQueryScripts and onEndShowStyles), we are ready to deploy our first plugin. Create a directory structure for the plugin:


Now, modify the file config.php in [GNU social root] to add this directive:


And you are ready to go, no server restart required. The GNU social cycle will load your plugin and insert your code in the final result.

Developing the plugin

I wanted to create the plugin with some restrictions:

  • Work with all themes.
  • Little or no modification at all necessary for the HTML code of the upstream themes.
  • If I had to modify HTML, I had to do it dinamically with Javascript.

That’s why we call it a plugin. If you find yourself hacking on server software you are creating a fork and your code will not be portable to other nodes. The first challenge was where to put the control that opens a dialog containing the entities. This is tricky because it has to work in a predictable manner with all themes. I decided to insert this little snippet inside the fieldset of the form for a new notice:

<label class=”smileys_open”>😃</label>

In each request, the engine only creates one form, that of the main notice. It doesn’t create a form for the replies. Instead, it is created every time a user activates a reply by copying the main notice form with jQuery. This is important, because you can’t add the label to a form that doesn’t exist yet. So I put it there and expect it to be copied along with the rest of the form. This design decision has some effects on the jQuery behaviour assignment that we will see later.

When you hack on GNU social you have jQuery and jQuery UI available. This is very convenient to rapidly build interfaces. I chose the controls Dialog and Tabs to present the Unicode entities.

Unicode Smileys plugin in action
Unicode Smileys plugin in action

As I said earlier, I can insert a control and assign a click function to it with jQuery if that control exists, but the controls for opening the dialog in the replies don’t exist until I click on a “reply to” button in any notice. But jQuery, great library as it is, brings us a solution. If I assign this click function to document and specify a selector, it will automatically add the behaviour to any new element that matches the selector.

‘#content_inner label.smileys_open’,

Having worked around that, I only have to make sure that each click on a smiley puts it in the appropiate form (the main one or a reply form).

Inserting entities in replies
Inserting entities in replies

Extending the icon sets

Have a look at assets/js/config.js. If you want new icon sets (see http://unicode-table.com/en/) you only have to find the initial (decimal) number and the final number and add the set as I have done with “Emoji”, “Dingbats” and “Miscellaneous”. Not all entities will appear on all combinations of operating system/locale/browser but you can try!

Show me the code!

And last but not least, browse the code for this plugin in https://git.gnu.io/danielside/SmileysUnicode. If you maintain a GNU social node, feel free to install it and hack around.


Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *