Modifications, add-ons, plugins, hooks - whatever your preferred name for them is - 3rd party code modifications are an important part of any successful web application. It wasn't that long ago that the way you did this was manually opening up files and copying and pasting bits of code in, or the really cool web applications had points scattered throughout the code for modifications to be injected into, or even scripts which opened up the files and made the changes for you (I'm not joking, that's seriously what used to go on!). In fact, IP.Board was one of the first web applications to, using OOP, support modifications in a more structured way.
Currently, we largely have 2 types of modifications: applications, which add whole new areas and functionality to your site (all of our applications: IP.Blog, IP.Gallery, IP.Downloads, IP.Chat, IP.Content and IP.Nexus use this architecture) and hooks which modify or extend the functionality of the IPS Social Suite or of applications.
Applications themselves are sort of self-governing so there isn't much to say about them, with one exception: applications will now be able to be downloaded and subsequently installed into your Admin CP as one file - you will not have to FTP upload application source files. The file will just be a regular .tar file, so course, if you were so inclined, you could open it and go old skool.
For the rest of this blog entry, I'm going to focus on hooks. Though parts of this blog entry will be more technical in nature than our others, I've tried to keep it just to what everyone will be interested in, and leave the boring stuff until the end.
The term "hook" in 3.x is ambiguous. Sometimes it refers to the whole thing (e.g. "install a hook") and sometimes it refers to a specific technical part of that - the code which overloads other code (e.g. "skin hook", "library hook"), which are, even more confusingly, sometimes called "hook files".
In 4.0, we've decided to rename hooks to plugins. The technical parts which make up a plugin will still be referred to as hooks.
Plugins, by their nature, extend functionality already present on your site. Up until now, if a plugin experiences a problem (for example, if a new version is installed which the plugin doesn't support) it can cause an error on your site, which disabling the plugin fixes.
Starting in 4.0, plugins will be sandboxed. This means that if a plugin experiences an unexpected error (such as a database driver error), your site will automatically fallback to the default behaviour, and your users will never know anything went wrong.
Simple (yet advanced) settings
In IP.Board 3.x, the Admin CP maintained a massive central area for managing most (though not all) settings. Plugins could add settings to this area, though there was no real standard to where to do that. Also, because this area was separate from the area where you install plugins, it could sometimes be confusing how to configure a plugin after installing it.
In 4.0, each plugin is allocated a settings page which is accessed just by hitting the "Edit" button on the list of plugins. Plugin authors can manage this page how they like - rather than being confined to the strictly tabular layout and specific input types in 3.x.
In 3.x, unlike with applications, there was no particularly clear way to upgrade a plugin from one version to another. In 4.x, plugins now support full versioning, so you can just upload a new version, and an upgrader will take care of it.
In 3.x, there were several different underlying types of hooks:
- Action overloaders - which allowed overloading the PHP class for any controller.
- Library hooks - which allowed overloading the PHP class for some (though not all) other classes.
- Data hooks - which allowed the modification of variables at specific, defined places in the code.
- Skin overloaders - which allowed overloading the compiled PHP class representing a group of templates.
- Template hooks - which allowed content to be inserted at specific points in templates.
For 4.0, we've made some quite radical changes:
The first 3 have been merged into one concept we call "Code Hooks". Code Hooks can overload any class (even things which presently can't be overloaded like extensions) through a technique called monkey-patching (more details have been mentioned in the developer channel). This, combined with the use of Active Record models for all content items (so "Topic", etc. is a class that can be overloaded) also makes data hooks obsolete.
The last 2 have also been merged into a concept called "Theme Hooks" (we're also renaming "skin" to "theme"). The way the current template hooks work is to insert content around certain pre-defined tags in the template. The problem is, not always is the point the plugin author needs available, also this is done in a way the content being inserted isn't aware of it's surroundings, which makes it difficult for things like adding a button to every post, which would need to know information about that post.
After thinking for ages about a better way to facilitate theme hooks (I was halfway through a system which injected hook points automatically at compile time), our designer Rikki reminded us that a pretty well-known method for selecting HTML elements already exists... CSS selectors.
What's really cool about this is that the content used acts as if it was part of the template - if for example, it's inserted in a foreach loop, the variables created by that are available. It can also use template logic and everything else templates themselves can do.
On the back-end, these are compiled into a file which behaves like a 3.x skin overloader - so if it is necessary (or just desired) to overload the compiled version of the template, that is still possible.
Theme hooks work for the Admin CP as well as the front-end.
Developers no doubt would like to know the technical information of how this all works. Rather than write a blog entry covering all the different parts of plugins, we thought you might be interested to just see the developer documentation. We have 2 articles we can show you - one covering all the technical details of plugins, and another which provides a step-by-step guide for how to create a plugin.