Pluggable Page Response Attachments

Events happening in the community are now at Drupal community events on www.drupal.org.
mfer's picture

The idea is to standardize the 'page' attachments (js, css, libraries, html head, response headers) into a common (or very similar) interface and pluggable system.

Imagine something like:

<?php
drupal_attach
('js')
  ->
add('/path/to/file')
  ->
add(array('foo' => 'bar'), array('type' => 'setting'));
?>

The interface would have methods for:

  • add - add something to the queue (ordering is though weighting?).
  • get - get a list of what has been added.
  • render - convert the content to html or what other ways it should be sent (for example, being sent with an AJAX response to be loaded in a page).

There would be a default class for each of these and they could be overridden with variables or if there is a plugin config system in place for it.

drupal_attach() is a factory to get the right object based on the properly configured class.

Note: adding this to the butler group because it fit with the idea of a context response or being part of the context. Something I spoke with Crell about. The objects from here could easily be attached to the context object.

Comments

Passed response object

Crell's picture

Personally I'd prefer for the "response object" to be separate from the context, but otherwise yes, having an object that gets passed around on which we set things like HTTP headers, JS, CSS, etc. is a good thing.

It's probably getting into implementation details, but why a "js" parameter and then add() methods? Why not

<?php
drupal_response
()
  ->
jsFile('/path/to/file.js')
  ->
cssFile('/path/to/css.css')
  ->
httpHeader('X-Something', 'A value');
?>

Pluggable Systems

mfer's picture

I was thinking that, at least, js and css were whole subsystems that should be plugable. Files, inline, and external scripts (plus js settings) are managed and rendered for each. This includes preprocessing. And, someone may want to use one use one contrib plugin for js and another for css.

I was thinking that drupal_attach() would be a factory that dealt with adding and using the context object. Maybe it could even have a second parameter for a passed in context object.

There may be a better way to handle this but I like the idea of JS and CSS being pluggable.

*Strokes goatee*

Crell's picture

Hm. Well, given that CSS and JS currently use different aggregators anyway, I suppose I can see the logic there. Although that means we're then heading toward a response object with pluggable collector objects on it, which we would then in turn need to have a way to manage and integrate when formatting the page. That's not a bad thing, necessarily, and there are reasons we may want to go there, but I'm just pointing out that rabbit hole can get rather deep.

I was also talking with Dries the other night (it still feels weird to say that) and he pointed out that the "Display Controller" object should have a more generic name if we're going all out ReST-ish with it and doing things other than "Display", like maybe "Response Controller". Which got me thinking, perhaps that IS the "response object" that we're passing down through the blocks along with the context. So each block object gets 2 objects in its constructor: The context (incoming data) and response (outogoing metadata), and it returns the main body response.

To be fair I've been against

merlinofchaos's picture

To be fair I've been against the name "Display Controller" all along. I keep calling it the RequestDispatcher or RequestHandler. =)

Chaining

robloach's picture

Sometimes chaining makes complete sense when dealing with and manipulating single objects. It makes perfect sense with PDO and the new Database Layer as we're manipulating and building upon the query object and building up a result set. What is the benefit for JavaScript and CSS files here though? You could accomplish the same thing in the same amount of code using drupal_add_js/css, what benefit does drupal_attach/jsFile/cssFile give us?

Single object

Crell's picture

The advantage is a single response object that can be passed around, and therefore mocked, rather than what amounts to little more than a wrapper around global variables. As with the incoming context, having a single object that we can pass around rather than calling out to globals gives us much more flexibility, testability, and control over the logic flow. In a sense we're manipulating and building upon the response object, just over a much longer period than we would a database query object.

Whether the method calls on that object are fluent (chainable) or not is a minor detail not relevant to the above statement.

chaining for adding

mfer's picture

I really like the idea of chaining for adding (or where ever else it makes sense). I would just be less to type :).

stephen.moz's picture

When I saw that Drupal-land had adopted jQuery, I was shocked (but delighted), since jQuery has given this kind of programming methodology a lot of street-cred.

The problem is most people see things like this and consider it a cute oddity, rather than a credible way to construct programs in any context with a high degree of extensibility and quality.

Another problem is, people routinely see this in JavaScript, C#, Ruby and other contexts quite naturally, but PHP not so much, because PHP is ... PHP.

Mocking

dmitrig01's picture

I think it would make mocking a lot easier if we had something like this:

$response->attach('js')
  ->add('/path/to/file')
  ->add(array('foo' => 'bar'), array('type' => 'setting'));

That way it's not tied to a procedural function and the actual attach function can be changed.

Nice and powerfull

Stalski's picture

This seems very nice and loose coupled. This level of flexibility is certainly the way to go imho.

Improvements to core

Group categories

Category

Group notifications

This group offers an RSS feed. Or subscribe to these personalized, sitewide feeds:

Hot content this week