Meta tags share a lot of different properties, code, and UI. I think it might make sense to look into using an OOP architecture for meta tags. We would provide a base 'DrupalMetaTag' class which is then extended by the default meta tag classes (e.g. 'DrupalMetaTagDescription', 'DrupalMetaTagKeywords'). Other modules can provide alternate implementations. For example several other modules might want to generate the Description meta tag based on different methods. They both have a class that extends 'DrupalMetaTagDescription', and we expose a simple UI select field in the Description meta tag settings that gives you all the possible options: 'Default', 'Module A', 'Module B'.

Stub example code:

class DrupalMetaTag {
  abstract function getInfo() {
    //return array();
  }

  public function getForm() {
    // Return Drupal FAPI code here.
  }

  abstract function process($node) {
  }
}

class DrupalMetaTagDescription extends DrupalMetaTag {
  public function getInfo() {
    return array(
      'name' => 'Default',
      'provider' => 'meta_tags',
      'type' => 'description',
    );
  }

  public function process($node) {
    return truncate_utf8($node->body, 155);
  }
}

class ModuleAMetaTagDescription extends DrupalMetaTagDescription {
  public function getInfo() {
    return array(
      'type' => 'description',
      'provider' => 'module_a',
      'name' => 'Module A description method',
    );
  }

  public function process($node) {
    return module_a_summary($node);
  }
}

class ModuleBMetaTagDescription extends DrupalMetaTagDescription {
  public function getInfo() {
    return array(
      'type' => 'description',
      'provider' => 'module_B',
      'name' => 'Module B description method',
    );
  }

  public function process($node) {
    return module_b_summary($node);
  }
}

Comments

DamienMcKenna’s picture

Does it need to be this complicated? Can't it just deal with a set of strings?

apaderno’s picture

An OOP architecture can help, depending on how the code is then developed.
In the case you want to extend the module to allow users (I am referring to users with permission to administer meta tags) to define their own custom meta tags without to write any custom code, OO code helps.

Dave Reid’s picture

Status: Active » Fixed

Have decided on an OOP 'plugin' model for the meta tags after a consultation with Crell.

The current code in Git is nice as the basics for 'outputting' a meta tag are:


function metatag_get_instance($metatag, array $data = array()) {
  $info = metatag_get_info($metatag);
  return new $info['class']($info, $data);
}

function metatag_entity_view($entity, $type, $view_mode, $langcode) {
  if (metatag_entity_supports_metatags($type) && $view_mode == 'full' && _metatag_entity_is_page($type, $entity)) {
    // Build options for meta tag rendering.
    $options = array(
      'view mode' => $view_mode,
      'entity' => $entity,
      'entity type' => $type,
    );
    $options['token data'][token_get_entity_mapping('token', $type)] = $entity;

    $tag = metatag_get_instance('canonical', array('value' => '[current-page:url]'));
    $entity->content['metatags']['canonical'] = $tag->getElement($options);
  }
}
valthebald’s picture

This design strongly resembles Field API:

Compare:

DrupalMetaTagInterface::getForm <=> hook_field_widget_form
DrupalMetaTagInterface::getElement <=> hook_field_formatter_view

Do you see added value in using interfaces instead of hooks (except for the general OOP/non-OOP holywar)?

Dave Reid’s picture

Yes admittedly this is very Field-API-*like* but meta tags are not 'visible' content like Fields (don't need different formatters). Using OOP allows me to easily extend a base functionality (like make a Link meta tag type that simply extends the Text meta tag type) without having to re-declare everything.

valthebald’s picture

Does that mean that meta tags won't be extendable by 3d-party modules (hook_field_info-like?)

Dave Reid’s picture

3rd party modules can add their own meta tags via hook_metatag_info() and hook_metatag_info_alter().

valthebald’s picture

Ok, fine.
In that case I would suggest to add version number to the DrupalMetaTagInterface interface (to ease future changes)

Dave Reid’s picture

Will take that into consideration. Thanks for helping sanity-check this.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.