Make WordPress Core

Opened 3 years ago

Last modified 2 years ago

#54829 new enhancement

Allow classic themes to be optionally block themes if 'templates' and 'parts' folders exists

Reported by: exstheme's profile exstheme Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 5.9
Component: Themes Keywords: has-patch has-unit-tests needs-testing 2nd-opinion early
Focuses: Cc:

Description

Hello!

I have created folders 'templates' and 'parts' inside classic WordPress theme folder (and 'index.html' file) as noted here: https://developer.wordpress.org/block-editor/how-to-guides/themes/block-theme-overview/.

This automatically converts classic theme to a block theme.

But I want to this conversion was optionally - depending of theme's settings.

I was able to create two filters.
First filter will disable 'Appearance -> Editor' admin menu item and return 'Appearance -> Customize' menu item.

if ( ! function_exists( 'disable_block_dirs' ) ) :
  function disable_block_dirs( $path, $file ) {
    //Custom logic to check settings to make block theme from classic theme here:
    if ( 'templates/index.html' === $file ) {
      $path = 'SOME_NOT_EXISTING_PATH';
    }
    return $path;
  }
endif;
add_filter( 'theme_file_path', 'disable_block_dirs', 10, 2 );

This filter is used in the 'wp-includes/class-wp-theme.php' in the public function get_file_path, which is used in the public function is_block_theme

Can we patch this file to add some filter public function is_block_theme that we could hook to before returning true or false?

Second filter is more harmful.
It will disable using custom HTML block templates on the front end. But it can be potentially very harmful because it's changing theme_root folder for the WordPress itself.

if ( ! function_exists( 'disable_block_dirs_second' ) ) :
  function disable_block_dirs_second( $path ) {
    //Custom logic to check settings to make block theme from classic theme here before return:
    return 'SOME_NOT_EXISTING_PATH';
  }
endif;
add_filter( 'theme_root', 'disable_block_dirs_second');

This filter is used in the 'wp-includes/block-template-utils.php' in the function get_block_theme_folders

Can we patch this file to add some filter to the get_block_theme_folders function to filter array that this function is returning that we could hook to?

---

Anyway now 'get_block_theme_folders' and 'wp_get_theme()->is_block_theme' are working independent from each other that does not make any sense. This should be fixed, I guess.

Hope this make sense.
Best regards!

Change History (18)

#1 @costdev
3 years ago

  • Keywords reporter-feedback added

Hi @exstheme! Welcome to Trac and thanks for opening this ticket.

I'm assuming that this is an example use case:

  • A theme wants to offer its users the option of 1) Using Blocks or 2) Using a "Classic" approach to create/manage their website.
  • If the user selects "Blocks", WP_Theme::is_block_theme() should return true, provided that prerequisites are met.
    • The "Site Editor" will be available.
    • The "Customizer" will also be available, but only if customize_register has been hooked.
  • If the user selects "Classic", then WP_Theme::is_block_theme() should always return false, even if prerequisites for a block theme have been met.
    • The "Site Editor" will not be available.
    • The "Customizer" will be available.

Would satisfying this use case also satisfy your own use case?

#2 @exstheme
3 years ago

Hello, dear @costdev !

Many thanks for your quick response and understanding!

Yes, you're absolutely right!
We have Classic theme but want to add an option to our users to use new WP5.9 full site editor feature if they want to use it - without changing their theme.

But as I mentioned earlier, currently even if WP_Theme::is_block_theme() is returning false - front end is using HTML block templates from templates and parts folders. So we need to add filter on the theme_root hook to return some dummy path - this is the only way that I could change this behavior if templates and parts folders exists.

It would be great if we could just use, for example, some add_theme_support( 'use_full_site_editing' ) feature on the after_theme_setup hook if user is check the appropriate theme option and only then templates and parts folders start to work as in a regular block theme.

Thank you very much once again!
Best regards!

Last edited 3 years ago by exstheme (previous) (diff)

This ticket was mentioned in PR #2175 on WordPress/wordpress-develop by costdev.


3 years ago
#3

  • Keywords has-patch has-unit-tests added; needs-patch removed

#4 @costdev
3 years ago

  • Keywords needs-testing added; reporter-feedback removed
  • Milestone changed from Awaiting Review to 6.0

This makes sense to me. Not only does it allow for a wider range of conditions by extenders, but it also allows Core to make adjustments when directly modifying WP_Theme::is_block_theme() may not be appropriate, which may also include the test suite.

@exstheme, I've added a PR to implement an 'is_block_theme' filter.

Please apply the changes in the PR and let me know if this works for you when using these callbacks:

<?php

// Option 1 - Force disable block theme functionality.
add_filter( 'is_block_theme', '__return_false' );

// Option 2 - Force enable block theme functionality.
add_filter( 'is_block_theme', '__return_true' );

For review of the ticket and the PR, I'm pinging @noisysocks and @poena regarding the impact on block themes and @hellofromTonya regarding the unit tests given that she wrote the is_block_theme() tests and may have some insight to better test the filter in context.

#5 @poena
3 years ago

I don't understand the use case.
Because you can use the template editing mode and the user can then choose to edit and create new templates, and if they don't want to edit them, they don't need to.

#6 @poena
3 years ago

I disagree with the concept of "two themes in one".
If you make all parts editable then the editing is still optional and the user is free to choose, which is one of the goals you wanted to accomplish.
The only time the user would need to use any template editing is to set up their menu.

#7 follow-up: @costdev
3 years ago

Thanks for the feedback @poena!

Here are two further potential use cases to allow us to make sure that we've explored this ticket's proposal for multiple use cases:

  1. Backwards compatibility: If an existing classic theme has a templates/index.html file, it will be deemed a block theme after updating to 5.9. This could be the case when using a templating engine, for example. The filter would allow the classic theme developer to correctly identify their theme as a classic theme rather than restructure their codebase and update references. In the event that said classic theme is no longer maintained, one line in functions.php would prevent a UI change for end users, and is a more straightforward fix for the support forum to advise.
  1. Extensibility: As we expand FSE, we may add alternative prerequisites to determine if a theme is a block theme (we changed block-templates to templates for example). By adding this filter, PRs to the Gutenberg repo, or feature plugins, can add the new prerequisites and write tests for them without having to modify Core. This would also allow manual testing to be carried out by a wider audience without each tester needing to make manual changes to WP_Theme - a plugin could simply add a setting to enable an experimental feature, which in turn would add a filter callback with additional ways to determine a block theme.
Last edited 3 years ago by costdev (previous) (diff)

#8 @exstheme
3 years ago

Hello, dear @costdev !

Thank you very much for this commit:
https://github.com/WordPress/wordpress-develop/pull/2175/commits/daeade936c57fb00824be4c954cf2bbd2ee2f75b
It is exactly what we're looking for:

  1. Now even if file 'templates/index.html' exists we're able to disable 'block theme' functionality with this filter:

add_filter( 'is_block_theme', '__return_false' );

  1. Now the only source of truth to check if theme is a block theme is this method:

wp_get_theme()->is_block_theme()
which is great!

So now if user wants to just check new FSE feature it can just check the appropriate settings checkbox. And if he decide to switch back - he can uncheck this setting.

Dear @poena !

I guess that adding ability to easily convert classic theme to a block theme and back is a good opportunity to let users to check and experiment with the new FSE feature with their theme of choice. And if anything will be broken they can always switch back without changing their theme.

And for theme's authors it is a great ability to update their existing themes without creating, supporting and maintaining new ones.

Hope this make sense for you.

Many thanks to everyone once again for your quick actions!
Best regards!

#9 @poena
3 years ago

Conceptually I strongly disagree that having code and files for both a classic theme and full site editing in the same theme makes them easier to maintain.
The theme will have a large amount of unused files once the user has decided which "version" to use.
I recommend trying to narrow down what problem you are trying to solve.

Version 0, edited 3 years ago by poena (next)

#10 @exstheme
3 years ago

Dear @poena !

Yes, I agree that maintaining theme that has ability to be 'block theme' and 'classic theme' at the same time depending of user settings is harder than maintaining one of them. But it will be easier than maintain two separate themes:

  • No need to register and maintain new site for the new theme.
  • No need to create a new Brand for new theme.
  • No need to promote new theme separately.
  • No need to seek new customers for the new theme.
  • Etc.

And for customers that already has trust for theme that they know will be less scary than using absolutely new theme.

I guess that this is a smooth way to transition from the classic to the block theme.

And according to unused files, as we can see - block theme requires very small amount of HTML files - nothing more. So there will not be huge amount of unnecessary files.

And both of versions can share same color schemes, block patterns and block styles - which is good.

Thank you for your opinion and your attention to this ticket!

Last edited 3 years ago by exstheme (previous) (diff)

#11 in reply to: ↑ 7 @exstheme
3 years ago

Hello, @costdev !

Can you please tell about any plans to merge your PR ?

Replying to costdev:

Thanks for the feedback @poena!

Here are two further potential use cases to allow us to make sure that we've explored this ticket's proposal for multiple use cases:

  1. Backwards compatibility: If an existing classic theme has a templates/index.html file, it will be deemed a block theme after updating to 5.9. This could be the case when using a templating engine, for example. The filter would allow the classic theme developer to correctly identify their theme as a classic theme rather than restructure their codebase and update references. In the event that said classic theme is no longer maintained, one line in functions.php would prevent a UI change for end users, and is a more straightforward fix for the support forum to advise.
  1. Extensibility: As we expand FSE, we may add alternative prerequisites to determine if a theme is a block theme (we changed block-templates to templates for example). By adding this filter, PRs to the Gutenberg repo, or feature plugins, can add the new prerequisites and write tests for them without having to modify Core. This would also allow manual testing to be carried out by a wider audience without each tester needing to make manual changes to WP_Theme - a plugin could simply add a setting to enable an experimental feature, which in turn would add a filter callback with additional ways to determine a block theme.

#12 @costdev
3 years ago

  • Keywords 2nd-opinion early added
  • Milestone changed from 6.0 to Future Release

While this ticket has a PR and unit tests, it still needs more input as we don't have consensus.

As today is Beta 1 for WordPress 6.0, I'm moving this ticket to Future Release to be pulled into the 6.1 milestone. I'm also adding 2nd-opinion and early so that discussion continues as soon as possible.

#13 @exstheme
3 years ago

Dear @costdev ! Thank you very much for your attention to this ticket.
Is there are potential problems may cause if this PR will be merged?

Dear @poena ! Can you please check my previous answer and let us know what you're think about it?

https://core.trac.wordpress.org/ticket/54829#comment:10

Thank you!

#14 @costdev
3 years ago

@exstheme Is there are potential problems may cause if this PR will be merged?

I don't believe the PR will cause a bug, but we have other areas to consider:

  • Backwards compatibility: Every enhancement may introduce something that we can't just remove in future without potentially breaking websites.
  • Vision: We must ensure that an enhancement aligns with the original intention of a feature - in this case, block themes.

This means that an enhancement must have a clear usage and it must be considered beneficial by the community. I don't feel that our three opinions are enough to make this determination for this particular enhancement, especially as we have not reached a conclusion with regards to difference of opinion. It is therefore preferable that we encourage others in the community to join the discussion to add more opinions and insight.

#16 @exstheme
2 years ago

Hello, dear @poena !

Thank you for your attention to this ticket.
I have recently updated to the WordPress v6.1 nightly and there is no changes here, unfortunately:

https://i.imgur.com/vmyNQNe.png

#17 follow-up: @poena
2 years ago

@exstheme I don't understand what that is an image of.

#18 in reply to: ↑ 17 @exstheme
2 years ago

Replying to poena:

@exstheme I don't understand what that is an image of.

Sorry, my bad. This is a screenshot of underlying method that is inside 'wp_is_block_theme' function.
And there is no changes here. No additional 'apply_filters' that we could hook to.
So if the file 'index.html' exists inside 'theme_root/templates/' or 'theme_root/block-templates' (this one is for back compatibility) - the theme will be treated as a block theme. Else - theme is no block theme. So still there is no ability to modify this behavior.

Note: See TracTickets for help on using tickets.