0

I'm looking for a way to pass post meta data to each of the blocks in the editor for the purpose of styling the content. My actual use case is hard to explain briefly, but for the sake of example, pretend it's the ability to display the post either in dark or light mode depending on a post meta value that the user sets.

The most obvious way to do this, for me, would be to add a class to the <div class="block-editor"> element like <div class="block-editor dark-editor-mode">. But I don't see an obvious way to do that. Everything I find via search is about modifying the individual blocks, but I want to modify the editor. Is there a hook for this? Either in JS or PHP?

9
  • I don't believe you need this to do what you're trying to achieve. CSS can handle all of this, you just need to put a toggle in a sidebar somewhere to control dark/light. Even then, I'd still say the solution here is actually composition, aka a containing block that's dark, or a containing block that's light. Otherwise you would fetch the meta from within the block, you wouldn't give it to the block
    – Tom J Nowell
    Commented May 1, 2020 at 11:19
  • Also, if you're going to show posts filtered by dark/light, this should be a term not a post meta for performance reasons
    – Tom J Nowell
    Commented May 1, 2020 at 11:20
  • As I said in my question, the dark/light is just an example, and the real use case has nothing to do with dark/light mode, but is too complicated to explain in the context of this question. Commented May 1, 2020 at 11:52
  • The problem I'm trying to solve is to apply different styles depending on the value of a the post meta. And no, it's not possible to do that only with CSS if there is no class in the HTML for the CSS selectors to use, and no variable being passed to the CSS. Commented May 1, 2020 at 11:53
  • Regarding the use of a containing block, if you can provide an answer for how to wrap the entire post editor in a containing block that has the post meta value as a class name, I'll accept the answer. Commented May 1, 2020 at 11:55

2 Answers 2

0

I was able to solve this problem by using the admin_body_class filter to add a class name to the <body> element of the admin page, and writing selectors for that class in my stylesheet.

add_filter( 'admin_body_class', 'add_status_classes' );
function add_status_classes( $classes ) {
  $post_meta = get_post_meta( get_the_ID() );
  $is_darkmode = $post_meta['_is_post_dark_mode'];
  if ( $is_darkmode ) {
    $classes = $classes . ' dark-editor-mode';
  }
  return $classes;
}
/* Normal Styles */
p:after {
  content: "Walking on sunshine!";
}
/* Styles when custom post meta option is true */
.dark-editor-mode p {
  content: "It sure is dark in here!";
}

Again, the dark mode is just a simple example, since my real use case is too complex to explain here, but the concept is the same.

Unfortunately, the drawback of this solution is that the editor has to be refreshed after the user changes the post meta setting, since the class isn't tied to a JavaScript store. If anyone knows how to hook into a data store that controls a classname on a parent element to the editor panel in Gutenberg, please add to my answer.

-1

Your proposed solution is not possible. There is no hook or filter that would allow you to apply a CSS class to the block list or the styles wrapper div, and no means to insert one.

This appears to be intentional, and also runs contrary to how things would work going forward, or how blocks in general work ( how would this work inside if the post meta was present in a reusable block post, or a site footer rather than a page/post? ).

Your next step if you absolutely must take this route, is to open a feature request in the github issues for the gutenberg repo, or write a pull request.

You can very easily just wait until the editor is initialised and grab the post meta from the data store, but there's no way to set a HTML class to apply the styling at an editor level.

Alternatives include:

  • Using your own custom blocks, and checking the post meta via the data store for each block
  • Using a containing block with child blocks, where the child blocks are then styled according to the settings of the parent block ( this also allows the post meta to be eliminated entirely, and futureproofs the functionality for full site editing and reusable blocks )
  • Using block styles ( perhaps bulk setting of block styles is an equivalent to what you want to achieve? )
2
  • I have a solution, but since you so confidently told me it's not possible, and my question is "contrary to how things work", I guess I'm wrong. Commented May 1, 2020 at 21:02
  • If you have an answer, I'd like to hear it, please post it as an answer. My answers based on searching through the Gutenberg code base looking for hooks to add classes to the editor style wrap div
    – Tom J Nowell
    Commented May 2, 2020 at 12:10

Your Answer

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

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