Contribute  :  Support  :  Downloads  :  Forum  :  Links  :  Polls  :  Calendar  :  Directory  :  Advanced Search  
Geeklog The Ultimate Weblog System
Welcome to Geeklog
Thursday, May 15 2008 @ 11:36 PM EDT
   

GL2 Plugin API (Draft)

Geeklog 2I've just published a draft of the plugin specification for Geeklog 2. The GL2 Plugin API doc contains an outline of what plugins will look like in GL2.

I'm looking for any suggestions that will improve the API or the documentation. I'm especially interested in recommendations to expand on Apendix B and improvements to the readability of the document.

This is another big step forward in moving towards a real implementation of GL2. If you check out GL2's cvs, you can see we're slowly moving away from vaporware.

Thanks,
Vinny

Discuss this in the forum

Story Options

GL2 Plugin API (Draft) | 11 comments | Create New Account
The following comments are owned by whomever posted them. This site is not responsible for what they say.
GL2 Plugin API (Draft)
Authored by: James Fryer on Wednesday, April 28 2004 @ 05:34 AM EDT
Here are a few comments I have after a first reading of the document.

> It is especially important to note that GL2 is being planned to use PHP 5

Why PHP5? Wouldn't PHP4 give you wider compatibility? What features of PHP5 are essential for GL2?

> The GL2 plugin architecture will be event based. 
> Each plugin will register to listen for events that are generated by
> the GL2 kernel and other plugins. 

I'd like more detail about the event based architecture you propose.
- What are its advantages over a conventional function call architecture?
- How will it work in practise? I'd like to see an example of how a page is generated from event calls.
- You realise you will have a domain terminology problem with internal events and calendar events?

I'm slightly skeptical about attempts to introduce event-based and MVC paradigms into web programming, which doesn't easily fit this model. An event model to me implies there is a running server, whereas PHP generates pages on demand. What happens to an event that occurs when no one is looking at the site?

> The Plugin Interface Class

One of the main difficulties at the moment is that plugins are quite hard to write. I hope you will consider the needs of plugin authors at every stage of the design process.


> class glPluginInterface {
> /**************************************************
> * Installs and registers the plugin with the GL2 kernel
> *
> * Handles the creation of data structures, security setup, and
> * registers for events.
> *
> * @access public
> **************************************************/
> public function install();

What do these functions return? This should be documented.

> Handling Events
> At that point it is the responsiblitiy of the plugin to do any required processing
> and to return an appropriate value.

How is this value returned? As strings of HTML code from the handle event function, which are then assembled by the event dispatcher?

How will different formats be handled, e.g. if I want a text or XML version of a page?

> Triggering Events

It may also be useful to have a function or option that delays triggering an event until a particular time.

> Directory Structure
> <plugin name>.class.php (interface class)

Why does this have a unique name? You already have the directory name to identify the plugin. I would give this file a standard name, e.g. 'main.class.php'. Advantages to this are, it makes it easier to create a new plugin by copying an old one, and it simplifies the code for manipulating plugins.

> Templates
> GL2 will only support HTML_Template_Flexy. 

Why this library in particular? Why not Smarty?

I don't have time to go into this in detail but a big problem with the current template system is that it does not properly separate display and application logic. The current templates are so simplistic that any complex display logic has to be carried out in the code before the template is called. Thus you lose the advantage of a template system which is separating the two kinds of logic. I hope this will be addressed in the new system.

> core.adduser A new user gets added (not self registered)
> core.newuser A new user registers with the site

Is it really necessary to have separate events for these? I think this will lead to duplication of code. Wouldn't it be better to have one event for adding users, with a parameter to say whether it is added by the admin or by registration?

> core.header.display Insert javascript/CSS in html <header>

Supposing I want to add something extra to the headers added in this event? Can I do this with the event system?
GL2 Plugin API (Draft)
Authored by: Dirk on Wednesday, April 28 2004 @ 08:44 AM EDT

One of the main difficulties at the moment is that plugins are quite hard to write.

What exactly, apart from the not exactly stellar documention, are your problems with the current API?

Plugins can be fairly simplistic (and easy to write), as you don't have to implement all the plugin API functions. See, say, my Manual Digest plugin or the "MacIG" sample plugin for examples.

bye, Dirk

GL2 Plugin API (Draft)
Authored by: Tony on Wednesday, April 28 2004 @ 09:39 AM EDT
Good questions. As you might have guessed, we have answers already:

1) Why PHP5? Wouldn't PHP4 give you wider compatibility? What features of PHP5 are essential for GL2?

ANSWER: Well GL2 is a long ways from being production ready and the 1.3.x tree will live for quite some time (even after the GL2 release). PHP5 brings many missing object oriented features that were missing in 4. I could run through them all but I'd simply refer you to the Zend site or the PHP site. At a high level the big advantages are: 1) Much improved exception handling. In PHP4 the best way to handle exceptions is using PEAR::Error, in PHP5 we have the "try...catch" clause. PHP5 also forces private, public, protected methods and properties to be honored. PHP5 introduces abstract classes as well as interfaces.

2) I'm slightly skeptical about attempts to introduce event-based and MVC paradigms into web programming, which doesn't easily fit this model. An event model to me implies there is a running server, whereas PHP generates pages on demand. What happens to an event that occurs when no one is looking at the site?

ANSWER: Uh, I'm not following you at all here. MVC fits any paradigm that has a user interface, business logic and a backend database. I couldn't diagree with you more here. To be clear, the 'event' model can be thought of more as the Observable/Observer design pattern. We don't want to over engineer GL2 however some of the classic design patterns made popular by Java make sense for use in any language. All the event model does is allow plugins to specify which kernel events they care to listen to. In 1.3.x we are terribly inefficient because for each 'event' the GL 1.3.x attempts to call the corresponding AP method on the plugin even if the plugin doesn't implement ti.

3) One of the main difficulties at the moment is that plugins are quite hard to write. I hope you will consider the needs of plugin authors at every stage of the design process.

COMMENT: Dirk has already addressed this well. You seem a bit hostile (though deriving context from posts on the internet is hard). If you have a vested interest in this I'd encourage to become a part of the process. That doesn't mean you have to code but if you have specific ways we can make improvements we'd love to hear them. However, making broad sweeping statements without giving justification of what you mean will only upset people.

4) What do these functions return? This should be documented.

ANSWER: Good point. We haven't begun working on exception handling yet so what they return is still in the air. I will say, though, we will be using PHPDoc so don't worry too much it will be documented

5) How is this value returned? As strings of HTML code from the handle event function, which are then assembled by the event dispatcher? How will different formats be handled, e.g. if I want a text or XML version of a page?

ANSWER: much of this will depend on the event that was fired. Each event may return different things, one may return and object, one my return a string an other may return nothing at all. You have to take this into context. The other part of your question is output format. We will be publishing at a later time how the layout stuff will work (much work has already started) but to give you an answer, if your plugin supports multiple output formats (e.g. XHTML, XML, WAP, etc) great, you will be able to do that. Where we are most concerned now is when we need to show pages that integrate information from multiple plugins.

6) It may also be useful to have a function or option that delays triggering an event until a particular time.

COMMENT: Can you give an example where this would be useful?

7) Why does this have a unique name? You already have the directory name to identify the plugin. I would give this file a standard name, e.g. 'main.class.php'. Advantages to this are, it makes it easier to create a new plugin by copying an old one, and it simplifies the code for manipulating plugins.

ANSWER: We will have to look at this more. Our ultimate goal is to not have any such requirements other than plugins go into the directories with unique names. The only other problem we must manage is the potential for classes in different plugins with the same name. Any suggestions on how to best avoid this is welcome.

8) Why this library in particular? Why not Smarty?

ANSWER: Well simply because Flexy is better. Flexy is a lexical parser that compiles the templates into PHP code to avoid costly regex string parsing that other template classes use. Flexy also includes most of the bells and whistles of Smarty (control structures, etc).

9) I don't have time to go into this in detail but a big problem with the current template system is that it does not properly separate display and application logic. The current templates are so simplistic that any complex display logic has to be carried out in the code before the template is called. Thus you lose the advantage of a template system which is separating the two kinds of logic. I hope this will be addressed in the new system.

COMMENT: the Utopia you are after doesn't exist. With our implementation of PHPLib you do have to write more PHP to handle complex display (e.g. nested templates). However, this is still nice because the web-design guy doesn't need to see that PHP code and can work on the templates themselves. With newer template system like Flexy, you can basically add code to them to handle the complex displays but then you have a problem where the average Joe web designer now has to make sure he didn't break the template because of removing a close to a for loop or something like that. In the end you have to strike the middle ground...I agree that IT/PHPLib isn't the greatest but at the time we decided to use it it was the most mature. Look into Flexy, it is almost at it's first stable release and I think you will like what you see.

10) Is it really necessary to have separate events for these? I think this will lead to duplication of code. Wouldn't it be better to have one event for adding users, with a parameter to say whether it is added by the admin or by registration?

ANSWER: we are always for considering alternatives. Keep in mind that we created the event-based model because it introduces a level of consistency in how things get triggered. I will say, however, I do enjoy the use of encapsulation. Depending on your plugin you may do radically different things between the two events, one muddy the code by putting it all in one function when you can make it more atomic by splitting it up?

11) Supposing I want to add something extra to the headers added in this event? Can I do this with the event system?

ANSWER: Yes.


---
The reason people blame things on previous generations is that there's only one other choice.
GL2 Plugin API (Draft)
Authored by: vinny on Wednesday, April 28 2004 @ 09:51 AM EDT
Thanks James, exactly the type of comments I was looking for, I'll try to answer everything...

> "Why PHP5? Wouldn't PHP4 give you wider compatibility? What features of PHP5 are essential for GL2?"

The biggest reason is the better handling of classes in PHP5. We plan to use many of the features that are included in PHP5. Also, since GL2 is (at a minimum) 6 months away, we think that PHP5 will be gathering momentum at that point and we'll start to see a large installed base. If necessary we can back-port to PHP4.

> I'd like more detail about the event based architecture you propose.
> - What are its advantages over a conventional function call architecture?

I'm not sure that I can articulate this well, but I'll try. Since plugins register for functions, only those plugins that want to respond to an event will need to do so. If we used functions architechture (similar to what we have in GL 1.3.x) we would have to check for the existence of the function for a particular plugin or else have every plugin return a result for every function call.
Also we think we'll increase portability between versions of GL2 by this implementation.
We could force a function model to do all the same things, but we believe that implementation would not be as clean (and hence make plugin development slightly more difficult). We think that this event architechure gives devlopers more flexibility without increasing complexity. We're open to comments for or against this. If you think functions are the better way to go, let us know and we'll consider you're arguments.

> - How will it work in practise? I'd like to see an example of how a page is generated from event calls.

We're working on an example.

> - You realise you will have a domain terminology problem with internal events and calendar events?

No I wasn't thinking about this at the time, but I agree completely. Recommendations for new terminology are welcome.

> "I'm slightly skeptical about attempts to introduce event-based and MVC paradigms into web programming, which doesn't easily fit this model. An event model to me implies there is a running server, whereas PHP generates pages on demand. What happens to an event that occurs when no one is looking at the site?"

Presumably if no-one was looking at the site and an event was generated there would be no View class executed. A command would execute, do what it needed, and then terminate. Though if the event was to send an email for instance, then the View would handle the formating of the email and send it.
Tony's MVCnPHP was crafted with web development in mind. To minimize memmory footprint and processing it loads only classes (Views and Commands) that it needs to execute. I think you'll find this implementation is usefully for making efficient (and maintainable) web pages.

> "One of the main difficulties at the moment is that plugins are quite hard to write. I hope you will consider the needs of plugin authors at every stage of the design process."

We're trying hard to fix that in GL2. We're trying to make a "Hello World" plugin be simple to implement but still grant developments flexibility and power for more complex plugins.

> What do these functions return? This should be documented.

You're right, I'll fix that in the next version of document. The current plan is for install(), upgrade() and uninstall() to return "true" on success and either "false" or an error message on failure. We're still working on the details. Suggestions are welcome in this area (as in any other).
The handlEvent() function will return a single variable (possibly a reference to structure or array) which will be defined per event. That too needs to be added to the documentation.

> "How is this value returned? As strings of HTML code from the handle event function, which are then assembled by the event dispatcher?"

That was poorly written. I think the last half of the answer to the previous question covers it. Basically the return type will be on a per event basis. Likely this will not be HTML (as HTML/xml/email/text will be generated by the Views).

> "How will different formats be handled, e.g. if I want a text or XML version of a page?"

The Views will handle outputing different formats. Tony and I are still working on a specificication for how Views should handle different formats.

> "It may also be useful to have a function or option that delays triggering an event until a particular time."

Something I hadn't thought about but that might be a good idea. Can you think of an example where this might be usefull?

> "Why does this have a unique name? You already have the directory name to identify the plugin. I would give this file a standard name, e.g. 'main.class.php'. Advantages to this are, it makes it easier to create a new plugin by copying an old one, and it simplifies the code for manipulating plugins."

Absolutely correct. Again, something I just wasn't thinking about when I drafted the document. What do you think of 'interface.class.php', or do you think 'main.class.php' (or something else) would make more sense?

> "Why this library in particular? Why not Smarty? I don't have time to go into this in detail but a big problem with the current template system is that it does not properly separate display and application logic. The current templates are so simplistic that any complex display logic has to be carried out in the code before the template is called. Thus you lose the advantage of a template system which is separating the two kinds of logic. I hope this will be addressed in the new system."

I think you should check out HTML_Template_Flexy. It supports most (if not all) of the template logic that Smarty supports. It also can use pre-compiled (or compiled on demand) templates. The big advantage of it over Smarty is that it fits into the MVC architechture much cleaner.

> "Is it really necessary to have separate events for these? I think this will lead to duplication of code. Wouldn't it be better to have one event for adding users, with a parameter to say whether it is added by the admin or by registration?"

Basically those were both added to increase flexibility. Though a plugin would have to register for each event seperately, a plugin could handle the two events with the same code:

function handleEvent($event, $var = '') {
switch ($event) {
case 'core.newuser':
case 'core.adduser':
//do stuff
break;
}
}

> "Supposing I want to add something extra to the headers added in this event? Can I do this with the event system?"

Thinking about this we should probably add events for the different html meta tags so they can be combined into a single HTML tag. Is that what you had in mind? Otherwise I envision this event allowing you to add anything you want between <head> and </head>.

-Vinny
GL2 Plugin API (Draft)
Authored by: James Fryer on Wednesday, April 28 2004 @ 04:55 PM EDT
Tony and Vinny raise some of the same points, so I am answering both here.

Tony:

> PHP5

Fair enough, your reasons make sense. It is a risk though, what if PHP5 takeup is not as high as expected? (c.f. Apache 2). Rewriting the software is a risk in itself, I would say reduce other risks as much as possible.

> Uh, I'm not following you at all here. MVC fits any paradigm that has a user interface, business logic and a
backend database.

I think that replying to these messages has helped me 'get' what you are talking about. Tell me if this is correct.

1. The user makes a request for a GL2 page.

2. GL2 gets data from the database and creates a Model object representing the GL2 page

3. If the user has submitted a form then changes are made to the Model as appropriate

4. GL2 creates a View object with the Model object as parameter

5. The View is rendered as HTML (or whatever) and sent to the user

I can see then how MVC can work here. One difference is that with a desktop application the model will continually update the view, whereas with a web application you might as well create the view at the end, but this is a minor point.

> In 1.3.x we are terribly inefficient because for each 'event' the GL 1.3.x attempts to call the corresponding AP method on the plugin even if the plugin doesn't implement ti.

Has this inefficiency been measured? Is it a real problem with GL installations? I find GL quite speedy.

> You seem a bit hostile

I didn't mean to come across that way. I was trying to be helpful by constructively (but robustly) criticising the paper. You acknowledge that GL1 has architectural faults, hence the development of GL2. If the current plugin system was ideal, we would not be having this discussion, so bringing up its shortcomings seems appropriate. If I have upset anyone I apologise. (NB I will reply to Dirk's message separately.)

> Each event may return different things, one may return an object, one my return a string

Doesn't this makes it difficult to interpret or use the results of an event unless the caller knows the type of the event?

> 6) It may also be useful to have a function or option that delays triggering an event until a particular time.
> COMMENT: Can you give an example where this would be useful?

A 'Quote of the Day' plugin which updates every day.

> Well simply because Flexy is better.

Fair enough.

> the [template] Utopia you are after doesn't exist.

No, but it is possible to come quite close. I don't see any way to avoid loops and conditionals inside templates. I agree this means it's a more skilled job maintaining them. I think that separating application logic from display logic (as you are doing with your View and Model classes) is essential if you want an application to be flexible.

> Depending on your plugin you may do radically different things between the two events [adding a user as an admin or by registering] one muddy the code by putting it all in one function when you can make it more atomic by splitting it up?

I would imagine that most plugins that handle these events will handle them very similarly. This level of granularity needs justifying with examples where one case is not a subset of the other.

Vinny:

> We're working on an example [of how a page is generated from event calls]

Just a basic pseudocode walkthough would make it a lot clearer.

> What do you think of 'interface.class.php', or do you think 'main.class.php' (or something else) would make more sense?

My preference is for 'main'. 'Interface' to me implies that the file doesn't contain an implementation. It doesn't really matter though, as long as it's consistent.

> Thinking about this we should probably add events for the different html meta tags so they can be combined into a single HTML tag. Is that what you had in mind? Otherwise I envision this event allowing you to add anything you want between <head> and </head>.

I was thinking about meta-tags but there might also be a need to add other stuff. For example a plugin might need to add JavaScript functions to support its client-side interface. Or a plugin might want to add CSS tags. Could this be handled?
GL2 Plugin API (Draft)
Authored by: Tony on Thursday, April 29 2004 @ 02:49 PM EDT
Thanks for the rebuttal. My turn ;-)

<snip>
Fair enough, your reasons make sense. It is a risk though, what if PHP5 takeup is not as high as expected? (c.f. Apache 2). Rewriting the software is a risk in itself, I would say reduce other risks as much as possible.
</snip>

Keep in mind that 1.3.x is around and is supported under many old (really old) versions of PHP4. We haven't been very good at changing the minimum requirements for PHP nor the database mainly because users insist that we don't. However, even when GL2 is here under PHP5 1.3.x will still be around until PHP5 has enough adopters. GL2 is a great place to change the minimum requiremetns and we have taken that liberty not to alienate users but to build a better product. So, to be clear, this is a good thing...users will have more choice.

<snip>
I think that replying to these messages has helped me 'get' what you are talking about. Tell me if this is correct..
</snip>

Uh, sorta. Not exactly. I really must refer you to the MVCnPHP code:

http://cvs.geeklog.net/cvs.php/MVCnPHP

The README should help explain a few things and there is a rudimentary sample app included. I will have a working classified plugin that uses MVCnPHP that will show how to use it in a real world application. I plan on releasing that this weekend.

<snip>
Has this inefficiency been measured? Is it a real problem with GL installations? I find GL quite speedy.
</snip>

Just depends on the number of plugins and the number of users you have. The fact you are making checks for the existence of a function is just overhead that isn't needed. Not a huge deal but something that bugs developers.

<snip>
If I have upset anyone I apologise
</snip>

No problem, your feedback has prompted a good discussion!

<snip>
Doesn't this makes it difficult to interpret or use the results of an event unless the caller knows the type of the event?
</snip>

Not really. We should make return values as consistent and predictable as possible but an event model will undoubted require different types of data to be passed around. PHP supports reflection so, in code, it will be easy enough to determine which object we are getting back. Besides, our documentation should nip this in the bud to a certain extent.

<snip>
This level of granularity needs justifying with examples where one case is not a subset of the other.
</snip>

Isn't encapsulation a good enough reason? If two events handle an event the same way you would either have one event call the handler of another or create a seperate private method that both events can call. Trust me, when we lift the hood on this you'll appreciate having this level of separation...it is more flexible and unltimately more maintainable IMHO.

--Tony


---
The reason people blame things on previous generations is that there's only one other choice.
GL2 Plugin API (Draft)
Authored by: tomw on Wednesday, April 28 2004 @ 10:04 AM EDT
Looks good -- The OO nature of the api does require more work for the casual programmer to understand but results in better and more maintainable code. And it is often faster. Once you understand the objects however you can write and modify the code much easer.

One question -- will the plugin directory be in or out of the webtree? If in the web tree, how will you handle security for config variables.
GL2 Plugin API (Draft)
Authored by: vinny on Wednesday, April 28 2004 @ 10:37 AM EDT
The plugin directory will be out of the web tree. Security concerns played a big factor in that decision.

-Vinny
GL2 Plugin API (Draft)
Authored by: Tony on Wednesday, April 28 2004 @ 11:09 AM EDT
As Vinny said, the plugin will *generally* reside outside of the webtree. Again, we have to plan for people on hosts who don't have permissions outside of the tree. Also, the power that MVCnPHP brings is that all your code, (commands, models, views) can be outside the webtree. The only issue is that we can't force plugins to use MVCnPHP mainly because a) it may not make sense (particularly true with smaller apps) b) because the author may not have the aptitude needed to use it (there is a fair amount of ramp-up).

So my question back is what is the best way to secure the config files? We could provide a checking machanism similar to Gallery that requires certain permissions on files but that may make plugins installation and configuration more complicated. I'm open for suggestions.

---
The reason people blame things on previous generations is that there's only one other choice.
GL2 Plugin API (Draft)
Authored by: jlhughes on Wednesday, April 28 2004 @ 06:09 PM EDT
QUOTE: So my question back is what is the best way to secure the config files?

All of my Geeklog sites (more than six) are on commercial servers running Linux. All I have is FTP access to these files.

Since I don't have access outside the webtree, my solution has been to put the non-webtree directories under the cgi-bin directory.

Is there a reason why this isn't a good option for those installations that don't have root access to the server?
GL2 Plugin API (Draft)
Authored by: tomw on Thursday, April 29 2004 @ 09:28 AM EDT
I don't have any real good answers to this. For security purposes having config info out of the web root is by far the best, but many people do not have this option. The biggest issue that I see with the current setup is the confusion caused by not being able to just uncompress the files and go, both for Geeklog and plugins.

Might I suggest the following scenario:

Have the default install of both plugins and the program itself be into the web root -- so that simply uncompressing the files in the correct spot will result in them being in the correct place and functioning. Then have a security howto that will tell the more astute how to move the sensitive files out of the webroot. If someone does not understand about paths, then they can leave it in the default configuration.

Imagine this if you will 'No more questions about how to set the path variables!' Well I am overly optimistic here. ;)

Good programing practices prevent people from viewing php files directly anyway.

TomW