Meh, just a thought - feel free to ignore or discuss :o) Drupal is moving away from hard drupal_add_css/_js calls and onto render arrays (of doom *cough*), anyways - the idea is that instead of using the standard drupal_add_js calls for example, we go to using (in hook_page_alter);

$page['content']['#attached']['js'][] = $plugin_path . '/src/jquery.poshytip.min.js';

Obviously it can be whatever it needs to be (content/ header/ footer/ etc) and it allows for easier override from other places.

Thanks again for a great little module!

Pobster

Comments

pobster’s picture

...I made a couple of other small adjustments as well - all minor.

Thanks,

Pobster

Drave Robber’s picture

Title: Move away from hook_init... » Move towards best practices
Priority: Minor » Normal

These adjustments make sense; none are urgent though, so I'm going to deal with them one-by-one.

One thing I'm not quite sure of is exit vs drupal_exit(); that local proxy thing is "not really a page", and implementations of hook_exit() mostly do not seem relevant or welcome there. (Seeing statistics_exit() on that list gives some interesting thoughts, however.)

Drave Robber’s picture

Committed the first step - doing away with clippedme_branding(). (I initially thought it might have more to do, but a separate function for getting just one URL is a sort of overkill.)

pobster’s picture

Agreed that it's not a page but it is still a callback in the sense that say, an ajax autocomplete is a callback, isn't it relevant for e.g. that statistics hook to fire to count the number of times that callback is fired? It's a backend call which can't be cached with Varnish, it's kind of useful to know that page is being hit x number of times?

I was taking my lead from http://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_e... which states "There should rarely be a reason to call exit instead of drupal_exit();" - I do however agree with what you're saying... TBH though, neither approach is how Drupal is supposed to do it! We're supposed to implement "delivery callback" in hook_menu() (for reference see ajax_deliver or wysiwyg_deliver_dialog_page for a perhaps neater one). I myself think this is absolute balls though... I don't see why every module needs to implement their own ajax-type delivery callback, it makes no sense?! Why isn't this already in core?! Anyways, if you're interested in this approach then this is one I wrote last year sometime;

function example_ajax_deliver($page_callback_result) {
  if (is_null(drupal_get_http_header('Content-Type'))) {
    drupal_add_http_header('Content-Type', 'application/json; charset=utf-8');
  }
  if (is_int($page_callback_result)) {
    switch ($page_callback_result) {
      case MENU_NOT_FOUND:
        drupal_add_http_header('Status', '404 Not Found');
        drupal_exit();
      case MENU_ACCESS_DENIED:
        drupal_add_http_header('Status', '403 Forbidden');
        drupal_exit();
      case MENU_SITE_OFFLINE:
        drupal_add_http_header('Status', '503 Service unavailable');
        drupal_exit();
    }
  }
  elseif (isset($page_callback_result['http_status'])) {
    drupal_add_http_header('Status', (int) $page_callback_result['http_status']);
  }
  drupal_json_output($page_callback_result);
  drupal_exit();
}

(edit)
And then call it using;

function example_menu() {
  $items['api/blocked-user/%user'] = array(
    'title' => 'example I just made up',
    'page callback' => 'example_callback',
    'page arguments' => array(2),
    'delivery callback' => 'example_ajax_deliver',
    'type' => MENU_CALLBACK,
  );
  return $items;
}

function example_callback($account) {
  return array('blocked' => (bool) user_is_blocked($account->name));
}

(edit)

I think you're right though - ignore this one! And thanks, I enjoy the discussion! :o)

Thanks,

Pobster

Drave Robber’s picture

I don't see why every module needs to implement their own ajax-type delivery callback, it makes no sense?! Why isn't this already in core?!

Now that I think of it, there actually is ajax_deliver(). What it does is probably mostly redundant for delivering a simple JSON though. Having a custom delivery callback that cuts it down to bare minimum seems a promising idea - thanks for it!

pobster’s picture

Yeah ajax_deliver() is really geared towards forms (and only for forms I'd say, I agree there's far too much going on), it's a shame there isn't anything nice and lightweight for simple RESTful JSON responses. I guess that's one of the things driving D8 forward (http://groups.drupal.org/node/226479).

Don't discount the change from hook_init() to hook_page_alter() BTW, the change to renderable content arrays allows other modules to alter the content array if they need to. When it's all hardcoded into hook_init() there's nothing they can do except hack the module.

Thanks,

Pobster

Drave Robber’s picture

Not discounting it, quite the opposite - that particular change is going to be accepted without much discussion.

Just that I prefer small, incremental one-thing-at-a-time microcommits - the progress might be slower but when something breaks it's easier to debug.

Drave Robber’s picture

Committed: removed redundant wrappers on $data (cruft left over from the early stage of development); cid doesn't really need to be passed around.

Drave Robber’s picture

Does this look good enough? Changes compared to your initial patch:

  • hook_page_build() instead of hook_page_alter() - so that modules wishing to mess with this in hook_page_alter() wouldn't have to worry about weights;
  • both pieces of js have 'scope' => 'footer' - they're unlikely to be needed before page is fully loaded;
  • everything is attached to $page['content'] - CSS and js isn't going to stay there anyway so this is purely formal.
pobster’s picture

Yep looks good to me! :o)

Thanks,

Pobster

Drave Robber’s picture

#9 committed.

alpha3 should be out shortly. (new release because of #1911686: Not working for sites using non-latin alphabets)