You are here

function scald_render in Scald: Media Management made easy 7

Same name and namespace in other branches
  1. 6 scald.module \scald_render()

Render a Scald Atom.

Info: "Rendering" takes an Atom and generates output (typically XHTML) based on the "Context" which is specified. The Context is essentially a template.

NOTE: scald_render() gets called recursively until a viable output is generated. It may return FALSE on a given call, but it will ultimately fall back to the 'title' Context which is provided by Scald Core and *always* generates *something*. Even if a

Parameters

mixed $sid: A Scald ID *OR* a Scald Atom object.

string $context: A valid Scald Context slug (a text string).

mixed $options: An optional text string or array specifying additional Scald Context-specific options that get passed to the Scald Context for rendering (e.g. a mechanism for specifying the size of an image). Usually it is the JSON format of an array of options.

bool $rebuild: Set to true to force a rebuild of the rendering.

Return value

mixed The rendered Scald Atom (usually an XHTML string ready for display) FALSE if the rendering failed for whatever reason

16 calls to scald_render()
atom_reference_field_formatter_view in modules/fields/atom_reference/atom_reference.module
Implements hook_field_formatter_view.
atom_reference_field_widget_form_process in modules/fields/atom_reference/atom_reference.module
Process the Atom Reference widget element.
mee_ajax_widget_expand in modules/fields/mee/mee.module
Ajax callback: returns the expanded HTML atom widget.
mee_field_widget_form_alter in modules/fields/mee/mee.module
Implements hook_field_widget_form_alter().
ScaldAtomEntityTestCase::testScaldAtomPermissions in tests/scald.test
Permission tests.

... See full list

File

./scald.module, line 1335
The Scald Core, which handles all Scald Registries and dispatch.

Code

function scald_render($sid, $context, $options = array(), $rebuild = FALSE) {

  // Validates the arguments.
  if (!is_numeric($sid)) {
    if (!empty($sid->sid)) {
      $atom = $sid;
      $sid = $atom->sid;
    }
    else {
      return FALSE;
    }
  }

  // Load the Atom Object in order to use it for determining the current Actions
  // bitstring and for recursive scald_render() calls.
  $atom_reg = scald_is_registered($sid, $rebuild);
  if (empty($atom)) {
    $atom = $atom_reg;
  }

  // SID doesn't correspond to a registered Atom; drop through to render the
  // "Invalid ID" message.
  if (empty($atom)) {
    return scald_scald_render($atom, 'invalid-id');
  }

  // Drop through to no-access rendering if current user can't view.
  if (!scald_action_permitted($atom, 'view')) {
    return scald_scald_render($atom, 'no-access');
  }
  $contexts = scald_contexts();

  // In the event of an invalid Context, initiate fallbacks.  Immediate return
  // avoids caching a different rendering as the specified Context.
  if (empty($contexts[$context])) {
    return scald_render($atom, _scald_context_fallback($atom->type, $context), $options, $rebuild);
  }

  // Check the cache unless explicitly rebuilding the rendering of the Atom.
  $action_bitstream = 0;
  foreach (scald_atom_actions_available($atom) as $action) {
    $action_bitstream |= $action['bitmask'];
  }
  $cache_parts = array_merge(array(
    $sid,
    $context,
    $action_bitstream,
  ), drupal_render_cid_parts());
  $cache_parts[] = $GLOBALS['is_https'] ? 'secure' : 'plain';
  if (!empty($options)) {
    if (is_array($options)) {
      $cache_parts[] = md5(drupal_json_encode($options));
    }
    elseif (is_string($options)) {
      $cache_parts[] = md5($options);
    }
    else {
      $cache_parts[] = $options;
    }
  }
  $cache_id = implode(':', $cache_parts);
  if (!$rebuild && !variable_get('scald_always_rebuild', FALSE)) {
    $cache = cache_get($cache_id, 'cache_scald');

    // If cache data is available, we attach 'rendered' property into atom as it
    // could be used by other functions, and we return the rendered text.
    if (!empty($cache)) {
      $data = $cache->data;
      $atom->rendered = $data['rendered'];
      return is_array($data['content']) ? drupal_render($data['content']) : $data['content'];
    }
  }

  // Either a cache miss or an explicit rebuild.  Pull in the rest of the Atom.
  if (!scald_is_fetched($atom)) {

    // If the atom cannot be fetched, render it with the "no-access" context.
    if (!($atom = scald_fetch($sid))) {
      return scald_scald_render($atom, 'no-access', array());
    }
  }

  // If $options is not a JSON string or a single value, give other modules a
  // chance to handle it.
  if ($options && !is_array($options)) {
    if (!is_array($decoded = drupal_json_decode($options))) {
      $options = array(
        'option' => $options,
      );
      drupal_alter('scald_render_options', $options, $atom, $context);
    }
    else {
      $options = $decoded;
    }
  }
  scald_prerender($atom, $context, $options);

  // Context Provider does the final rendering.
  $content = module_invoke($contexts[$context]['provider'], 'scald_render', $atom, $context, $options);

  // The Context exists but rendering is failing hard for some reason.  Output
  // still needs to be ensured, however.  Also note that an empty string is
  // valid output.  However, hook_scald_render() should return FALSE upon
  // failure and module_invoke() will return NULL if the function does not
  // exist.
  if ($content === FALSE || is_null($content)) {
    return scald_render($atom, _scald_context_fallback($atom->type, $context), $options, $rebuild);
  }
  if (!is_array($content)) {
    $content = array(
      '#markup' => $content,
    );
  }

  // For so-called "parsable" Contexts, ensure a standard format for the
  // enclosing comments.
  if ($contexts[$context]['parseable']) {
    $content += array(
      '#prefix' => '',
      '#suffix' => '',
    );
    $content['#prefix'] = '<!-- scald=' . $atom->sid . ':' . $context . ($options ? ' ' . drupal_json_encode($options) : '') . ' -->' . $content['#prefix'];
    $content['#suffix'] .= '<!-- END scald=' . $atom->sid . ' -->';
  }

  // Only cache the Atom if Contexts, etc. have not indicated that the rendering
  // is not cacheable (e.g. it contains the current user's username).
  if (!$atom->rendered->nocache) {

    // Note that cached renderings of an Atom will stick around until
    // scald_update_atom() is called on the Atom.  This is usually the
    // responsibility of the Atom Provider as it has the best idea when the base
    // entity is changing.
    $data = array(
      'content' => $content,
      'rendered' => $atom->rendered,
    );
    cache_set($cache_id, $data, 'cache_scald', CACHE_PERMANENT);
  }
  return drupal_render($content);
}