I am creating a field formatter - a Drupal 8 version of a D7 field formatter module I wrote. I'm having a hard time getting it to work properly - there are a couple of issues, and I need some assistance in figuring out why this does not work.

As you can see in the code below, I've tried a couple different things in the render array - only when I have very simple html, in a "#markup" item, does it display. When I try the <iframe> it displays nothing - the field is completely empty, both visually and in the rendered HTML. And when I instead specify a '#theme' element my hook_theme() never fires. Additionally, I find that the viewElements method is only being called once - I have to do a cache rebuild in order to get the method to run again.

My ultimate goal here is put the field formatting into a template and just pass variables into it via the theme hook.

Seems like there's more than one issue going on here but I'm not sure where one ends and another begins.

This is the heart of the field formatter, in GdocFieldFormatter.php

public function viewElements(FieldItemListInterface $items, $langcode) {
    $elements = array();

    foreach ($this->getEntitiesToView($items, $langcode) as $delta => $file) {
      $file_uri = $file->getFileUri();
      $filename = $file->getFileName();
      $uri_scheme = \Drupal::service("file_system")->uriScheme($file_uri);
      if ($uri_scheme == 'public') {
        $url = file_create_url($file->getFileUri());
        $elements[$delta] = array(
          '#markup' => '<strong>https://docs.google.com/gview?embedded=true&url=' . $url . '</strong>',
//          '#markup' => '<iframe class="gdoc-field" style="width:300px;height:400px;" src="https://docs.google.com/gview?embedded=true&url=' . $url . '"></iframe>',
/*          '#theme' => 'gdoc_field',
          '#url' => file_create_url($file->getFileUri()),
          '#filename' => $filename,*/

      else {
          t('The file (%file) is not publicly accessible. It must be publicly available in order for the Google Docs viewer to be able to access it.',
          array('%file' => $filename)

    return $elements;

Here's the theme hook I wrote - but it's not firing and I don't know why. Note it is in gdoc_field.module

function gdoc_field_theme($existing, $type, $theme, $path) {
  return array(
    'gdoc_field_formatter' => array(
      'variables' => array('url' => NULL, 'name' => NULL),
      'template' => 'gdoc-field',

So - several questions:

  • Why is the theme hook not being called?
  • Why is the <iframe> being stripped?
  • Why is the field formatter method viewElements only being called once, after a cache rebuild, instead of on every page view (even with caching turned off)?
  • So far, you stated facts without asking an explicit question. – kiamlaluno Nov 2 '15 at 6:05
  • Sorry the questions were implicit rather than explicit. I have explicitly restated them at the bottom. – jmarkel Nov 5 '15 at 12:02
  • As reference code, see UserNameFormatter::viewElements(). – kiamlaluno Nov 5 '15 at 19:06
  • 1
    You never reference gdoc_field_formatter in your formatter, of course it wouldn't fire. You would need something like '#theme' => 'gdoc_field_formatter', in your render array. – tim.plunkett Nov 8 '15 at 19:05

Your Answer

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

Browse other questions tagged or ask your own question.