Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ideas for Global Block Settings #1224

Closed
ataylorme opened this issue Jun 17, 2017 · 30 comments
Closed

Ideas for Global Block Settings #1224

ataylorme opened this issue Jun 17, 2017 · 30 comments
Labels
Customization Issues related to Phase 2: Customization efforts [Feature] Blocks Overall functionality of blocks
Milestone

Comments

@ataylorme
Copy link

There are situations where a setting should be applied to all blocks of a certain type rather than each individual block. Some examples are an API key, theme (e.g. dark/light), etc.

What is the best way to handle a global setting for all blocks of a certain type?

@jasmussen
Copy link
Contributor

Ah, interesting. Can you think of more examples? I'm sure there are many I have no doubt, but a solution might present itself better if we can think up more use cases.

First thought is a metabox, "Global Block Settings", or something in that vein.

@jasmussen jasmussen added [Feature] Blocks Overall functionality of blocks [Type] Question Questions about the design or development of the editor. labels Jun 17, 2017
@ataylorme
Copy link
Author

ataylorme commented Jun 17, 2017

I think it would be a great place to store default values for blocks that are user defined, rather than what we, as developers, assume a user wants for a default.

For example, the image block could have a default alignment defined in the global settings so all new image blocks added are pre-aligned the way the user wants rather than having to align them each time.

Some defaults may one be know by the user, such as username. An example would be a GitHub Gist block. Username could be a global setting and/or default and then Gist ID would be supplied to each block.

Or a block for creating Wufoo forms could save a username, API key, etc.

If we want plugins to make use of blocks I think license key is another great example. A block could have standard features but unlock more features if a valid license is supplied.

Happy to chat more and brainstorm ideas as well. One thought I had was global block settings being right under other inspector controls, with their own heading. When edited they would apply to all blocks. In the API key example rather than having to go elsewhere if a user needs to update their API key to cycle it, etc. they can do so quickly and easily.

@ataylorme
Copy link
Author

One thought I had was global block settings being right under other inspector controls, with their own heading. When edited they would apply to all blocks. In the API key example rather than having to go elsewhere if a user needs to update their API key to cycle it, etc. they can do so quickly and easily.

Just to clarify this could be restricted by user roles as well, for example being only open to editor or admin by default and editable via a filter.

@westonruter
Copy link
Member

One way this could be implemented today is adding a React component to <InspectorControls> which gets its state directly from, say, the settings endpoint of the REST API. This component could be styled in a way to distinguish it from other inline block attribute controls.

I realize this is probably an not ideal React architecture in that the state of the component isn't being managed by the Redux store.

@westonruter
Copy link
Member

westonruter commented Jun 17, 2017

There is also overlap here with the idea of blocks being lifted out of the post content to be then stored externally, such as in a block post type for re-use in multiple places such as sidebars (local => global). Additionally the idea relates to the idea of private block attributes which cannot be stored in post content and instead need to be stored in somewhere private like postmeta when local (or options when global).

@westonruter
Copy link
Member

I want to disavow my suggestion that components can directly write their state to the site via the REST API. If this is done, it eliminates the ability to preview changes. All state needs to be stored in the Redux store, but we need a way to indicate where the data will be stored, whether on the post itself, the postmeta, options, or somewhere else.

@jasmussen jasmussen added the Customization Issues related to Phase 2: Customization efforts label Aug 18, 2017
@mtias
Copy link
Member

mtias commented Aug 18, 2017

Seems the way to handle this is to interact with default values in the attributes object of a block definition.

@jasmussen
Copy link
Contributor

Here are some mockups!

When you select a block and click the "Block" tab in the Settings sidebar, you see the properties for a block:

editor w sidebar block selected

What if, when you were on this Block tab of the inspector but did not have a block selected, you saw global block settings? It could look something like this:

editor w sidebar no block selected

@ataylorme
Copy link
Author

Wondering if anyone has further thoughts here. I would like to work on a Google Maps block where the user can enter an address and a map of the location will be displayed.

This is a great use case for a global block setting as this will require a Google Maps API key. The API key should be entered once and used by all blocks of the same type as well as be easily updatable in one place.

Is there a preferred way to create such a global setting for a specific block type?

@pyronaur
Copy link
Contributor

Google maps API key sounds like a plugin, or a global "generic" setting to me, not a "Gutenberg" specific setting. Having such settings anywhere near Gutenberg is probably going to clog up the editor quite quickly.

@ataylorme
Copy link
Author

@justnorris I'm also working on adding syntax highlighting to the core code block. I would like the user to be able to select a color scheme for the syntax highlighting. This doesn't make sense as a block-specific options as it would be very tedious to change the color scheme site wide.

I think ideally there would be a global block option, perhaps showing up with other block options in InspectorControls, that would change the color scheme for all blocks when edited. If it were saved to a setting I could simply enqueue different CSS for the color scheme based on the option chosen.

Having the user navigate to a separate settings page for this seems counter intuitive in my opinion. I don't think we should dismiss this idea because an API key isn't the right fit.

@jasmussen
Copy link
Contributor

Could the mockups shown here address things? #1224 (comment)

@ataylorme
Copy link
Author

@jasmussen I think the first one definitely.

What if, when you were on this Block tab of the inspector but did not have a block selected, you saw global block settings? It could look something like this

I think a generic global area could be very cluttered. What I'm thinking is when you select a specific block adding options, like you can now, but rather than being tied to the state of the block a global option would also be stored in a global place, like the settings API, so when it is updated the update effects all blocks.

@pyronaur
Copy link
Contributor

pyronaur commented Jan 2, 2018

Ah. Turns out I've misunderstood the idea a bit. If the "Global" setting only appears for the currently selected block then I see no problem with that.

@ataylorme
Copy link
Author

I've created a Googe Maps plugin that requires an API key. Without a global block setting to enter the key once and use it across all blocks I needed to register a settings page/field and a custom REST API endpoint to expose the data. I then read API key with withAPIData.

This all works but added 188 lines of PHP and an additional settings submenu. This is a big ask to bother developers and users. As a developer, it is a lot of code to write. For the plugin users, I had to document adding the API key very clearly and it's not intuitive to go to a settings page when adding a new block for the first time.

I don't think this is a must have but don't feel it should be disregarded either. I'm happy to have further discussion as needed.

@ataylorme
Copy link
Author

I just realized I will need to convert my block into a dynamic one rendering with PHP instead of JavaScript. The API key is used in the markup for the block, which is currently saved to post content when the post is updated.

If the API key is changed in the settings menu all of the existing blocks won't be updated as the markup with the old API key is already saved in the content.

I can't think of a way to have the global setting (API key) updated in the context of settings API without using a dynamic block to fetch the current value from the database on each page load.

@leahkoerper
Copy link
Contributor

I agree that there's a lot of user cases for global block settings. However, I'm unclear on the intended reach of these hypothetical settings. It seems like there might be some conflicting ideas presented. My main concern in reviewing this issue was the idea that a user could make a change that influences their whole site from a single post or page- it would require some helper text and/or very careful UI to avoid confusion.

Some of the above suggests that the global settings would only impact new/future blocks:

For example, the image block could have a default alignment defined in the global settings so all new image blocks added are pre-aligned the way the user wants rather than having to align them each time.

While others perhaps suggest that it would impact existing blocks on other pages/posts:

I would like the user to be able to select a color scheme for the syntax highlighting. This doesn't make sense as a block-specific options as it would be very tedious to change the color scheme site wide.

Is there a consensus on how that might work? Anything that can make retroactive changes to multiple pages and posts seems to me to belong somewhere like the general WP settings, although I see the argument for ease of use in the block settings.

@ataylorme
Copy link
Author

Anything that can make retroactive changes to multiple pages and posts seems to me to belong somewhere like the general WP settings, although I see the argument for ease of use in the block settings.

I'm hoping for something that will impact existing pages/posts. Currently without this when creating a block that needs such a global settings one must:

  • Add a settings and settings page for the value to be stored
    • This could get unwieldy with many plugins creating a settings page for 1 or 2 options they need in blocks
  • Register a custom REAST API endpoint to return the setting value from the database
  • Use withAPIData to fetch the value from the endpoint
  • Create a dynamic block so the frontend is rendered with PHP
    • Without doing this the post content gets saved in the database saved with the current setting value. If that setting is updated int he future existing blocks would not receive the new setting value in the already rendered and stored post content until if/when that post is edited again in the future.

I understand the argument that it should belong as a plugin setting as well but just wanted to make my case clear and highlight the amount of work needed to do this currently.

@leahkoerper
Copy link
Contributor

Ah, I definitely wasn't considering it enough from the viewpoint of a plugin adding their own blocks. Good call. In that case I would just say it should be made extremely clear in the UI for standard blocks (and plugin blocks, but of course that's on the plugin devs) that changes made in the global block settings can impact existing blocks on other posts and pages and could thus change the layout or appearance elsewhere on their site.

@ataylorme
Copy link
Author

Hi @leahkoerper. I ended up making the field display inline in the block but had to load an instance of wp.api outside of my edit callback (link).

Then watch the model for changes and update the state accordingly in each block (link).

While this works it is still quite a bit of effort and seems a little hacky compared to having a global setting available to blocks from Gutenberg.

google-map-embed-block-api-key

@karmatosed karmatosed removed the Design label Mar 10, 2018
@karmatosed karmatosed removed the Needs Design Feedback Needs general design feedback. label Jul 15, 2018
@lkraav
Copy link

lkraav commented Jul 15, 2018

What if, when you were on this Block tab of the inspector but did not have a block selected, you saw global block settings?
...
I think the designs in #1224 (comment) solve this perhaps? Let's for now remove design feedback label.

Separate explicitly labelled "Global" (or similar) tab would probably be the clearer way. Having to decipher the contents of any panel based on the state of some other element is usually a frustrating excercise for the users.

@mtias mtias added the Future label Jul 16, 2018
@ZebulanStanphill
Copy link
Member

Divi is implementing something pretty similar to this called Global Defaults:

https://www.elegantthemes.com/blog/theme-sneak-peeks/divi-feature-sneak-peek-global-defaults

In a comment on a later blog post, they also mentioned that they would be adding something called Global Presets, which would presumably be something similar to the class system in Oxygen or even the block style variations already in Gutenberg, albeit user-made (similar to what is proposed in #7551).

@mtias mtias changed the title How should we handle global block settings? Ideas for Global Block Settings Oct 7, 2018
@mtias mtias removed the [Type] Question Questions about the design or development of the editor. label Oct 7, 2018
@mtias mtias added this to the Future: Phase 2 milestone Oct 12, 2018
@timelsass
Copy link
Contributor

@paaljoachim had said:

I think we need more use cases and experiment with what the most intuitive process would be.

i was working on something similar in a theme and ran across this need. I have a lot of customizer options, and felt that some were applicable to editing content. Things like typography for body/headings, fontsizes, and theme's color palette were some of them. I decided to register a global settings plugin to resolve the issue for now. I used the rest API to get/set the theme mods with a few options to apply the "Global" defaults only on the current page/post or globally to all pages/posts via the postmeta. Since it's registered as a plugin - I added the dashicons-admin-site icon, so a global icon appears at the top, which seemed to be pretty intuitive overall.

@joyously had said:

It is important that the scope of the activity is confined. Editing a single page or post should not impact other pages or posts.

This was the biggest part I had to work around. It seemed like I was duplicating some logic here and there, but providing global settings to users who can manage them, and options for just page/post meta seemed to address a lot of what I was trying to achieve. When I had created customizer options, I mostly just threw everything under manage_options and didn't give thought to role scopes in terms of who should be able to access what settings initially. For the plugin scripts in wp I just enqueue it based on the role, and have some checks on the rest api endpoints created based on role. I'm not sure if I really did this the right way, but it everything seems to be working for my needs so far.

I did most of this as an experiment to just get familiar with gutenberg, but I hope in Phase 2 connectivity between global site options (theme_mods) and per page/post settings (postmeta) is more cohesive. I think providing a way to do this more easily in core would be a great feature to help bridge some of the gaps between editing and customizing.

@KawaiiHannah
Copy link
Contributor

KawaiiHannah commented Feb 19, 2019

Another use case I've just run into is contact details. A pattern I've used for a while is to have a field in the Customiser to hold the site's main phone number. That way, I can pull it out in several places throughout the theme and within the content (was using a shortcode before).

There have been a few instances where a client has changed their phone number and I've saved myself quite a bit of effort in needing to change it throughout the site. I've been struggling to find a nice way to include this in my custom blocks, but I think I'm going to have to go with the ServerSideRender for now.

Edit // I do want to note that it's the pure data that I want, so I can include it within several different blocks. A phone number may be included in a tel:link or within a button, or even within paragraph text. Would shortcodes still win over in this case? For the tel:link and within a button, that could be some kind of global attribute. Not sure how the paragraph one would be handled though.

@mapk
Copy link
Contributor

mapk commented Oct 21, 2019

Related: #15450

@enriquesanchez
Copy link
Contributor

It seems all the recent work for Global Styles is going to allow for most of the suggestions proposed here. See #20367 and the Global Styles project board.

I'm closing this issue but feel free to reopen or add feedback to the current Global Styles issues if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Customization Issues related to Phase 2: Customization efforts [Feature] Blocks Overall functionality of blocks
Projects
None yet
Development

No branches or pull requests