2

Drupal 8 has this new amazing in-built functionality for handling requests from browsers and via AJAX at the same URL using the Accept header, which makes the CTools way of adding "nojs" to URLs, and then changing that to "js" in the JavaScript seems like a clever but antiquated hack.

Is there a cleaner way to do this, that could be considered a "best practice" for Drupal 7 going forward, that is more inline with how things are now done in Drupal 8? Also, how does a traditional ajax response versus a json response factor into this?

Code examples would be highly useful here.

  • 1
    Probably not a small job - off the top of my head...you'd need to provide JSON versions of everything you want JSON representations of (I guess you could have something generic for, say, entities, but again, lots of code), and override all the relevant page delivery callbacks to become accept-header-sensitive. I think (only think, haven't checked) there'd be at least one core patch required. As far as AJAX/JSON goes, presumably you'd want to return the same data for both, so AJAX requests should include an accept header too. But, hey, it's Drupal - maybe someone's already done it :) – Clive Jun 17 '14 at 16:38
1

I am not sure whether this is clean or "best practice" but I am currently using something like this:

  // If the request has the header 'Accept: application/json'
  // return the output in JSON format and stop.
  if ($_SERVER['HTTP_ACCEPT'] == 'application/json') {
    drupal_add_http_header('Content-Type', 'application/json; utf-8');
    print json_encode($strings);
    exit;
  }

To see it in the context, here is the whole function:

<?php
/**
 * Menu callback: translations/search.
 *
 * Search strings and translations using various filters.
 *
 * If the request header 'Accept: application/json' is set, then
 * the output will be in JSON, otherwise it will be an HTML page.
 * For example:
 *   curl -k -i -H 'Accept: application/json' \
 *        'https://dev.l10n.org.xx/translations/search?lng=sq&words=space'
 */
function btrClient_search() {
  // Get the search parameters from the GET request.
  $params = btrClient_get_search_params();

  // Get the strings that match the search params.
  $btr = btr_user_is_authenticated() ?
    wsclient_service_load('btr') :
    wsclient_service_load('public_btr');
  $result = $btr->search($params);
  $filter = $result['filter'];
  $pager = $result['pager'];
  $strings = $result['strings'];

  // If the request has the header 'Accept: application/json'
  // return the output in JSON format and stop.
  if ($_SERVER['HTTP_ACCEPT'] == 'application/json') {
    drupal_add_http_header('Content-Type', 'application/json; utf-8');
    print json_encode($strings);
    exit;
  }

  // Add the CSS and JS files.
  drupal_add_css(drupal_get_path('module', 'btrClient') . '/editor/editor.css');
  drupal_add_js(drupal_get_path('module', 'btrClient') . '/editor/jquery.worddiff.js');
  drupal_add_js(drupal_get_path('module', 'btrClient') . '/editor/editor.js');

  // Add RTL style if the current language's direction is RTL.
  $languages = btrClient_get_languages();
  $lng = btrClient_get_translation_lng();
  if ($languages[$lng]['direction'] == LANGUAGE_RTL) {
    drupal_add_css(drupal_get_path('module', 'btrClient') . '/editor-rtl.css');
  }

  // Set the title.
  drupal_set_title(t('Search Translations'));

  // Add the filter form.
  $output = array(
    drupal_get_form('btrClient_filter_form', $filter),
  );

  // Output the strings.
  if (empty($strings)) {
    drupal_set_message(t('No strings found. Try adjusting the filter options.'));
  }
  else {
    pager_default_initialize($pager['number_of_items'], $pager['items_per_page']);
    $output[] = drupal_get_form('btrClient_translate_form', $strings, $lng);
  }

  return $output;
}

(Or check it out here: http://cgit.drupalcode.org/btrclient/tree/includes/search.inc

  • Thanks. This might be a good way to get going. I'm wondering now if its only part of the puzzle going on what @Clive said in his comment above. – JamesWilson Jun 25 '14 at 22:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.