drupal
Introducing the concept of Extendable Object Faces (API)
Preliminary Warning:
"If you're afraid of classes and objects in PHP, run away now." - jpetso.
Update: For simplicity the API has been changed so that all faces are incorporated, thus modules have to care about naming collisions theirself. Also in the meantime file inclusions support has been added.
While figuring out a object oriented design for the rules engine I recognized the need for a possibility to allow modules extend objects in various places. Thus I developed a generic concept which does just that: Allowing modules to extend objects. I called the concept "Extendable Object Faces", which basically implements the Facade pattern in a modular way.
So let's have a closer look at that. A module that wants to extend an object may only do so on top of a defined interface, preventing uncontrolled growing objects. Thus one can write some code, define an interface for it and attach it to potential any extendable object out there. Then other modules have an easy way to test whether some object has a functionality in place by checking for the availability of a certain interface.
To use that functionality the caller has to use the right "Face" of the object - corresponding to a certain interface. This approach using different "Object Faces" make sure there can't be conflicting method names, so modules don't need to prefix their methods with the module's name which would result in ugly and not readable code.
I've already implemented an initial version of the Extendable Object Faces API. As of now you can:
- Extend an object by providing an Extender Class
- Extend an object simply by some functions, each implementing a method
- Override any dynamically added method by providing functions or an Extender Class
- Easily lazy load huge parts of an objects implementation, invisible for the caller.
- Allow modules to dynamically alter an implementation by using overriding.
Dreaming...
If we would have an object oriented "Data API" in drupal core, this could serve as a way to let modules extend those objects. So instead of writing node-centric code code could would be written in a generic way - attachable to potentially each of those data objects (users, comments, terms). Having such generic code would allow us to finally end the "Everything should be a node" debate. Apart from that this would help us to easily lazy load big chunks of code, just exploiting the code registry!Reactive rules for drupal have grown-up!
Finally, after over 1 year of development the rules module has reached the 1.0 version! You can download it from the project page.
Reactive rules?
Reactive rules (or ECA-rules) are rules triggered upon a given event. This allows one to conditionally fire actions based on arbitrary events. As modules can provide further conditions, actions and events this enables site builders to automate a lot of things using reactive rules! As of now a lot of popular drupal modules provide already rules integration: CCK, Organic Groups, Token, Flag, Content Profile, Content Access, ViewsBulkOperations and many more.
Features?
The modules comes with a bunch of useful features, e.g. a flexible input evaluation system that allows to use token replacements or even PHP evaluation in your rules. To ease the management of rules the module supports tagging of rules as well as Import/Export. Often used behaviour can be put into Rule-Sets and is easily invoked by provided actions. Not enough, the execution of those Rule-Sets can be scheduled easily with help of the provided action, thus providing a powerful scheduling system, which allows you to schedule arbitrary tasks!
It's finally grown-up?
Rules is already stable for quite a time, however I didn't consider it to be complete. During the last months I added missing important features, fixed bugs and translation issues and completed the documentation! While there was quite a bunch of useful developer documentation for a while, now there is also a complete hook reference in the doxygen format.
So it's grown up, but it's not (yet) perfect. So what comes next?
Rules 1.0-rc1 is out!
I've just released the first release candidate for rules 1.0. Read more at groups.drupal.org!
Lighttpd and a convenient way to support clean URLs
A lot of people run drupal with lighttpd, a light and fast webserver, which uses FastCGI to support PHP. As lighttpd doesn't read .htaccess files, some extra config is required to get drupal's clean urls working right.
I'm doing so already for a while now, finally I found the best way to do clean urls with lighttpd. I started with some url-rewriting regexes, which isn't ideal as there are problems with some special paths or dots. I've improved the regexes a bit, but still there were problems.
Another common way is to use a lua-script. The big advantage of this script is that one can do the url rewriting based on the condition whether there is a file for the requested path - so no regex magic is required. Thus there also no problems with dots.
The disadvantage of that approach is it's inflexibility. When you want to install multiple drupal instances in several different sub directories or use a script to generate settings for all your drupal instances, it's odd that the lua variant needs one script per drupal prefix, because you have to set the prefix in the lua script!
Finally I found a way to work around this inflexibility. First off I looked into passing the prefix variable into the lua script, but I had no luck with that. So I decided to go for another approach: I wrote a simple wrapper script, that creates the needed lua script with the right prefix set on the fly. So when lighttpd parses your configuration it calls the wrapper script, which makes sure there is a lua script in place and returns the suiting configuration for your drupal installation.
Ok, enough talk. Let's see how it works.
Relevance feedback for drupal's search
For the second exercise of my Information Retrieval course at the university I had to do implement a relevance feedback system - so I thought: Why not build it upon drupal's search?
So that's what I did. The result is a working proof of concept module, which you can find in my sandbox and test at the demo site.
The system has two operation modes: One that uses "implicit feedback" and one that let's the user give "explicit feedback". The implicit feedback mode just tracks which search results the user has viewed, takes these results as relevant to generate an optimised search query and shows the improved results to the user.
The explicit system works the same way, but provides some UI for users to mark results as relevant and non-relevant, as you can see on the screenshot:
You can test the system at the demo site, which runs in explicit feedback mode. Once you have provided three positive results as feedback the system makes use of the Rocchio algorithm to generate an optimised search query and redirects you to the improved search results.
major pageroute update, status
I've just committed a major update to the pageroute module. I've reorganized the page types and created a new one: the node management type.
The node management page allows one to add/edit/delete nodes from a configurable content type. It shows a themeable list of already created nodes and allows editing and deleting if the user has access.
The node management page type was the last important piece missing for nodeprofiles: A userfriendly way to create several nodes of the same type.
separated modules into own projects
I've separated the modules into own projects, as they are not only for nodeprofiles useful.
Now there are the following drupal projects:
Node Profile
Node Family
Views Fusion
Pageroute
drupal api docs firefox search plugin
I've created an updated version of the firefox search plugin. (there was already a plugin which still used drupaldocs.org and so was broken)
additional to the updated HEAD plugin i added a plugin for 4.7.
nodefamily, status update
i've started development of the node relations module, i called it nodefamily module.
As the module might be useful not only for profile nodes, I've written it generally, so that it may be used without nodeprofiles at all.