5

I am working on a WordPress child theme where I do not have access to any markup other than the header.php. (I have access to child functions.php and the style.css)

The site has a body and a div#wrapper, but I would really like there to be 1 or 2 divs between those because I don't want to use body to create a column and currently, the only way to wrangle the whacky markup would be with the body. I would like to get a div that actually wraps the page contents in this case.

<html>
  <body>
   <section class='NEW-WRAPPING-ELEMENT'>
     <div id='wrapper'>
       ...
     </div>
     <div id="footer'></div>
     <div id="other'></div>
   </section>
  </body>
</html>

This markup probably worked just fine in most cases with a classic 960px absolutely positioned layout, but it's hard to work with when you want a malleable responsive layout.

I can use JavaScript and wrap them on page load, but it seems like it would be better to build it on the server - since I'm using PHP anyway. ALSO, you can see the flash of styling when the .master wrapper kicks in. No good!

I am removing p tags from images and wrapping things like inline images with a figure with preg_wrap. Can I / should I - use a similar technique to 'wrap' my everything in the body with another div? I do not know regex at all. I hacked this together but no go so far. Thoughts???

function wrap_wrapper( $content ) {
    // A regular expression of what to look for.
    $pattern = '/<body>(.*?)<\/body>/i';
    // What to replace it with. $1 refers to the content in the first 'capture group', in parentheses above
    $replacement = '<section class="new-master">$1</section>';
    return preg_replace( $pattern, $replacement, $content );
}
add_filter( 'the_content', 'wrap_wrapper' );

Here is a CodePen with full markup example of what I have to work with:

5
  • Can you explain why you do not have access to anything other than the style-sheet and a header.php? It would be interesting to see the reason.
    – Laxmana
    Mar 16, 2017 at 18:49
  • The reason is that the company I am contracting with set things up that way. It is not ideal and I hope that one day I can convince them to rewrite their theme in a modern way. Mar 16, 2017 at 23:32
  • When you say your access is restricted, surely you still have read access to those other files? Your question would be easier to address if we could see where certain template tags are used in the current implementation, notably get_header(), get_footer(), and wp_footer(). get_template_part() calls could also be useful.
    – bosco
    Mar 21, 2017 at 23:30
  • Since you have access to header.php, it doesn't make sense that you don't have access to footer.php. If they don't let you modify the footer.php of the main theme, then you can always copy the footer.php to the child theme and then modify as needed. There are so many possibilities, but you didn't provide enough details to answer them correctly.
    – Fayaz
    Mar 23, 2017 at 2:10
  • I provided all of the details. I understand that it's hard to get passed not having access to the footer - or being allowed to copy the parent theme footer - but that's the constraint to work within for this question. : ) Mar 23, 2017 at 2:26

2 Answers 2

3
+100

Can I use a similar technique to 'wrap' my everything in the body with another div?

Absolutely. Almost everything is possible. But you're going to have to do something a little hackish.

The the_content filter doesn't actually filter the content of the entire page. That particular filter is used throughout WordPress to filter a variety of different contents.

Unfortunately, there isn't a good way to filter the entire page.

One way to accomplish this would be to use ob_start() and ob_get_clean() attached to appropriate hooks. We need to hook into before anything is output to the page and start an output buffer. Then we need to hook in at the last possible moment and get the buffer.

Then we can do something with the content. Your regex was close, but not quite right.

In your functions.php, add the following:

//* Hook into WordPress immediately before it starts output
add_action( 'wp_head', 'wpse_wp', -1 );
function wpse_wp() {

  //* Start out buffering
  ob_start();

  //* Add action to get the buffer on shutdown
  add_action( 'shutdown', 'wpse_shutdown', -1 );
}

function wpse_shutdown() {

  //* Get the output buffer
  $content = ob_get_clean();

  //* Do something useful with the buffer

  //* Use preg_replace to add a <section> wrapper inside the <body> tag
  $pattern = "/<body(.*?)>(.*?)<\/body>/is";
  $replacement = '<body$1><section class="new-master">$2</section></body>';

  //* Print the content to the screen
  print( preg_replace( $pattern, $replacement, $content ) );
}

Should I use a similar technique to 'wrap' my everything in the body with another div?

It depends. A better, faster way to accomplish this would be to edit the template files. Since you state that you don't have access to the template files, then I believe that something like this would be your only option.

7
  • If I just had the footer.php! I'll try this out today. Thanks! Mar 20, 2017 at 18:56
  • Ok. I finally got to put it in place and try it, but I'm not getting the result. Have you used it in a PHP environment? Mar 22, 2017 at 20:41
  • Try the regex with the /s flag on the $pattern. (I've edited the code to show where.) I've tested it on a fresh WP install with no plugins and Twenty Fifteen theme. Mar 22, 2017 at 20:50
  • Awesome! This is going to be really helpful. Thank you. : ) Mar 22, 2017 at 22:44
  • You shouldn't use regex, regex with HTML may break when similar regex unexpectedly matches within HTML content. Use PHP DOM extension classes instead.
    – Fayaz
    Mar 23, 2017 at 2:02
5

You say,

I do not have access to anything other than the style-sheet and a header.php.

...but you do not state why this is. It seems to me that for a child theme to work well, you'd need at least a functions.php if not a template for content as well. If you can't access those or create those, I would say to your client, "Here's your shitty website. This is the best I could do with the tools you gave me. I can do better if you grant access to more files."

That's my first thought. My second thought is, your plan seems like it may work, if all the modifications you need are in the header.

My last thought is more of a wondering: Can you create a plugin that would take over the work of the theme files you can't access?

3
  • I cannot add any plugins. I also have *feelings about this... but they aren't really relevant. This is a very successful large company and I'm trying to work within their limitations for a while before I outline how brittle the system is. There is a lot of legacy code involved that runs over 800 sites. I DO have access to a functions file. That is where I would place the proposed function. Mar 16, 2017 at 23:36
  • I'll amend my post to include that I have a functions file. Mar 17, 2017 at 1:35
  • So, the question still stands. I also think my plan would work, but I don't know how to employ it properly. I'm not new to programming, I just try to stay away from PHP when I can. : ) Mar 17, 2017 at 1:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.