If we add an alter hook, the structured data for any page could be altered to add additional properties. I think this could be a doable approach to specifying custom schema types rather than trying to account for everything through an admin form beyond what you already have. I'll provide a patch. Thoughts?

Comments

apmsooner created an issue. See original summary.

apmsooner’s picture

Status: Active » Needs review
StatusFileSize
new567 bytes
apmsooner’s picture

Example using new alter to update structured data. Works for me....

function food_recipe_structured_data_preprocess_html_alter(&$structured_data) {
  $node = menu_get_object();
  if (!isset($node->nid)) {
    // Try to get node without menu_get_object().
    if (arg(0) == 'node' && is_numeric(arg(1))) {
      $node = node_load(arg(1));
    }
  }
  if (isset($node->nid) && !arg(2) && $node->type == 'food_recipe') {
    $structured_data['@type'] = 'Recipe';
  }
}
ajayg’s picture

Status: Needs review » Needs work

Since you have started with 'Recipe Type' would it be possible to show the complete all fields required by "Recipes" ? Showing one field is proof of concept, but would be useful to see the hook can handle multiple fields typically required to support a content type. What I am trying to figure out the hook is flexible and does not choke as you add new structured data types.

apmsooner’s picture

Status: Needs work » Needs review

Here is an example of how i'm using the alter hook. Note that some things you have setup as defaults are assumed at only the site level so i'm unsetting those as they will produce errors when testing in the google structured data tool for recipes. For recipe, an image is required per finding out via testing through the structured data tool. An alter hook allows me to specify what i need and don't need but i would recommend probably removing the stuff like logo, address, etc... from your implementation as it seems to only be pertinent to the front page? Anyhow, i have some extra code here that is grabbing my ingredient data but i think you can get an idea from below...

function food_recipe_structured_data_preprocess_html_alter(&$structured_data) {
  $node = menu_get_object();
  if (!isset($node->nid)) {
    // Try to get node without menu_get_object().
    if (arg(0) == 'node' && is_numeric(arg(1))) {
      $node = node_load(arg(1));
    }
  }
  if (isset($node->nid) && !arg(2) && $node->type == 'food_recipe') {
    $structured_data['@type'] = 'Recipe';
    // Logo and address aren't recognized in recipes.
    unset($structured_data['logo']);
    unset($structured_data['address']);
    $image_field = field_get_items('node', $node, 'field_image');
    if ($image_field) {
      $uri = $image_field[0]['uri'];
      $structured_data['image'] = file_create_url($uri);
    }
    $ingredients = food_recipe_load_ingredients($node->nid);
    if (!empty($ingredients)) {
      $items = array();
      foreach ($ingredients as $ingredient) {
        $structured_data['recipeIngredient'][] = t(food_decimal_to_common_fraction((float) $ingredient['amount']) . ' ' .
        $ingredient['measure_desc'] . ' ' . $ingredient['name']);
      }
    }
  }
}
apmsooner’s picture

I should add... technically i shouldn't be trying to output structured data at all if an image doesn't exist for my recipe since it is required but the code above was just what i was playing around with to get basic recipe context setup. Here is an example recipe per google as well although not all those fields are required in order to work. I havn't found a specific document outlining minimum requirements per @type so i've just been relying on what the testing tool outputs in its results.

<script type="application/ld+json">
{
  "@context": "http://schema.org/",
  "@type": "Recipe",
  "name": "Grandma's Holiday Apple Pie",
  "author": "Elaine Smith",
  "image": "http://images.edge-generalmills.com/56459281-6fe6-4d9d-984f-385c9488d824.jpg",
  "description": "A classic apple pie.",
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": "4",
    "reviewCount": "276",
    "bestRating": "5",
    "worstRating": "1"
  },
  "prepTime": "PT30M",
  "totalTime": "PT1H",
  "recipeYield": "8",
  "nutrition": {
    "@type": "NutritionInformation",
    "servingSize": "1 medium slice",
    "calories": "230 calories",
    "fatContent": "1 g",
    "carbohydrateContent": "43 g",
  },
  "recipeIngredient": [
    "1 box refrigerated pie crusts, softened as directed on box",
    "6 cups thinly sliced, peeled apples (6 medium)",
    "..."
  ],
  "recipeInstructions": [
    "1...",
    "2..."
   ]
}
</script>
apmsooner’s picture

Oh found it! Although in this link it says image isn't required, the testing tool produced an error when i tried to test structured data without one... could be a bug in the tool maybe. Here is for recipe and the sidebar shows list of other types which may help explain further: https://developers.google.com/search/docs/data-types/recipes

alasda’s picture

Status: Needs review » Reviewed & tested by the community

Applied patch. Created custom hook in utility module. json+ld page output modified as expected.

Tested and working.

alasda’s picture