Proper Way to Inject into Head using ACF / Sage 10

I need to add an ACF field, callable on any blade template, that will inject editable code into the document head. (In this case, schema.org json LD schemas). I’m wondering if there’s a way I can call sage to do it at the index.php level like this:

site/web/app/themes/mytheme/index.php

<!doctype html>
<html <?php language_attributes(); ?>>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <?php wp_head(); ?>
    
  </head>

  <body <?php body_class(); ?>>
    <?php wp_body_open(); ?>
    <?php do_action('get_header'); ?>

    <div id="app">
      <?php echo \Roots\view(\Roots\app('sage.view'), \Roots\app('sage.data'))->render(); ?>
    </div>

    <?php do_action('get_footer'); ?>
    <?php wp_footer(); ?>
  </body>
</html>

I noticed it’s echoing Sage in the app div. Can I call a template to render in head, even though it’s outside sage?

Maybe I should refactor the whole html document to live inside sage? :thinking:

I dug into this for a bit. I think because the ThemeServiceProvider is (as you called) booted inside the Roots\app instance, you’re going to have a tough time loading your views/templates outside of that instance.

If you were going to refactor everything inside the roots\app instance, you could probably just do this:

site/web/app/themes/mytheme/index.php

<!doctype html>
<html <?php language_attributes(); ?>>
<?php  echo \Roots\view(\Roots\app('sage.view'), \Roots\app('sage.data'))->render(); ?>
</html>

Then in site/web/app/themes/mytheme/resources/views/layouts/app.php

<head>
    <meta  charset="utf-8">
	<meta  http-equiv="x-ua-compatible"  content="ie=edge">
	<meta  name="viewport"  content="width=device-width, initial-scale=1, shrink-to-fit=no">
    @yeild('head'); //This is, I think, the best way to add in blade template content to the <head>
</head>
<body  <?php  body_class(); ?>>
    <?php      wp_body_open(); ?>    //Default WP Stuff
    <?php  do_action('get_header'); ?> //Default WP Stuff
    <div  id="app"> //Now we're back to the app
	    <main  class="main">//This is normally in views.layouts.app
		    @yeild('content');
	    </main>
    <?php  do_action('get_footer'); ?>
    @yield('footer') //Add in footer scripts, because why not!
    <?php  wp_footer(); ?>
</body>

Lastly, in one of your templates, like template.product-schema.blade.php

@extends('layouts.app')

@section('head')
    //Your <head> content here
@endsection

@section ('content')
    //Your <main> content here
@endsection

@section ('footer')
    //Your pre-</body> content here
@endsection

I haven’t tested this, so your milage may vary. Still, I think this is the best way to make this work for you, if if you need it. ( Note: I don’t think you need it for schemas. My work with Shopify, et. al, makes me think it’s perfectly acceptable to include these outside of the <head>, specifically at the end of the <body>).

1 Like

I’m a little confused by this. Are you referring to a template in the WordPress sense, or to any blade partial?

My guess is you have a situation that’s something like this:

  • Some pages/posts/cpts/etc have an ACF field available on them
  • When this field has certain content, you want to use that content to generate a JSON-LD schema chunk in the <head>

If that’s the case, imo the best way to approach it would just be to hook into the wp_head action, i.e.:

add_action('wp_head', function() {
  $value = get_field('the_acf_field');
  if ($value) {
    echo convert_to_json_ld_string($value);
  }
});

If for some reason you want to use a blade template to generate that string, you could do:

- echo convert_to_json_ld_string($value);
+ echo \Roots\view('your-blade-file', ['json_string' => convert_to_json_ld_string($value)])

…or something similar, depending on your needs.

Not in the way you’re probably thinking of it, no. You can use the above technique to do stuff in the head, but it’s not “inside” of the Sage template renderer.

I would not recommend this. It is the way it is to allow various WordPress plugins that need to do things with the header and footer hooks to do those things…appropriately. If you put it all inside Sage you may run into issues with plugins not working in the way you expect, or not working at all.

2 Likes

Hey @alwaysblank,

Incidentally I did try a method that @evankford detailed, as it was along the same lines as my originally proposed solution. It did work, but now you’ve got me scared per your comment!:

So I refactored per your suggestion using the wp_head hook. It’s working perfectly well, thank you!

@evankford Thank you so much for looking into a solution, it seems we were thinking similarly. And thank you for the note about the schema being able to exist outside the head, that may make the <head> business unnecessary.

:pray::pray: :pray:

This topic was automatically closed after 42 days. New replies are no longer allowed.