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

Refactor theme config loading #29667

Closed
wants to merge 3 commits into from
Closed

Conversation

youknowriad
Copy link
Contributor

@youknowriad youknowriad commented Mar 9, 2021

Motivation In this PR #29335 I tried to get the "layout" setting from theme.json and I had to call 4 functions with the right arguments in order to do it.

While working with the Theme config abstraction in the backend, it became very clear to me that the classes and APIs were built initially to map the theme.json file and format, but they were too low level to work with which resulted in a lot of indirection and duplication each time you want to access a config or something in the backend.

This PR makes a step into simplifying the APIs by introducing a WP_Theme_Config object that you can access with:

// Gets the config from the cache or load it
$config = WP_Theme_Config_Resolver::load_config();

// Get settings
$config->get_settings();

Notice that I didn't have to pass any argument or anything, everything is abstracted from the consumer, making it easier to reason about the current config without actually knowing how it's assembled, what kind of theme it is...

Later, I'd like us to probably introduce a function similar to the useEditorFeature hook we have in the frontend.

Also note that in the PR, I keep the WP_Theme_JSON class but in reality this class becomes just a private implementation detail that shouldn't be accessed directly at all. A future refactor might remove it entirely.

@github-actions
Copy link

github-actions bot commented Mar 9, 2021

Size Change: +3.68 kB (0%)

Total Size: 1.4 MB

Filename Size Change
build/blob/index.js 665 B +1 B (0%)
build/block-directory/index.js 8.63 kB -4 B (0%)
build/block-editor/index.js 125 kB +232 B (0%)
build/block-editor/style-rtl.css 12.4 kB +158 B (+1%)
build/block-editor/style.css 12.4 kB +160 B (+1%)
build/block-library/blocks/cover/editor-rtl.css 605 B +6 B (+1%)
build/block-library/blocks/cover/editor.css 605 B +6 B (+1%)
build/block-library/blocks/freeform/editor-rtl.css 2.46 kB +7 B (0%)
build/block-library/blocks/freeform/editor.css 2.46 kB +7 B (0%)
build/block-library/blocks/gallery/editor-rtl.css 696 B +7 B (+1%)
build/block-library/blocks/gallery/editor.css 696 B +6 B (+1%)
build/block-library/blocks/gallery/style-rtl.css 1.11 kB +30 B (+3%)
build/block-library/blocks/gallery/style.css 1.1 kB +30 B (+3%)
build/block-library/blocks/navigation/editor-rtl.css 1.09 kB +6 B (+1%)
build/block-library/blocks/navigation/editor.css 1.1 kB +7 B (+1%)
build/block-library/blocks/query/editor-rtl.css 820 B +6 B (+1%)
build/block-library/blocks/query/editor.css 819 B +7 B (+1%)
build/block-library/blocks/shortcode/editor-rtl.css 512 B +8 B (+2%)
build/block-library/blocks/shortcode/editor.css 512 B +8 B (+2%)
build/block-library/blocks/social-links/editor-rtl.css 776 B +80 B (+11%) ⚠️
build/block-library/blocks/social-links/editor.css 776 B +80 B (+11%) ⚠️
build/block-library/blocks/social-links/style-rtl.css 1.32 kB +8 B (+1%)
build/block-library/blocks/social-links/style.css 1.33 kB +8 B (+1%)
build/block-library/blocks/template-part/editor-rtl.css 552 B -5 B (-1%)
build/block-library/blocks/template-part/editor.css 551 B -5 B (-1%)
build/block-library/blocks/verse/editor-rtl.css 50 B -12 B (-19%) 👏
build/block-library/blocks/verse/editor.css 50 B -12 B (-19%) 👏
build/block-library/editor-rtl.css 9.58 kB +46 B (0%)
build/block-library/editor.css 9.58 kB +48 B (+1%)
build/block-library/index.js 147 kB +144 B (0%)
build/block-library/style-rtl.css 8.86 kB +31 B (0%)
build/block-library/style.css 8.86 kB +30 B (0%)
build/blocks/index.js 48.3 kB +21 B (0%)
build/components/index.js 284 kB +420 B (0%)
build/components/style-rtl.css 16.2 kB +601 B (+4%)
build/components/style.css 16.2 kB +604 B (+4%)
build/compose/index.js 11.2 kB +91 B (+1%)
build/core-data/index.js 16.7 kB +3 B (0%)
build/customize-widgets/index.js 3.95 kB -1 B (0%)
build/data-controls/index.js 830 B +1 B (0%)
build/data/index.js 8.87 kB -2 B (0%)
build/date/index.js 31.8 kB +1 B (0%)
build/dom/index.js 4.96 kB +33 B (+1%)
build/edit-navigation/index.js 11.9 kB +17 B (0%)
build/edit-navigation/style.css 1.31 kB -1 B (0%)
build/edit-post/index.js 307 kB +484 B (0%)
build/edit-post/style-rtl.css 6.88 kB +55 B (+1%)
build/edit-post/style.css 6.87 kB +55 B (+1%)
build/edit-site/index.js 27.2 kB +33 B (0%)
build/edit-site/style-rtl.css 4.5 kB +14 B (0%)
build/edit-site/style.css 4.5 kB +14 B (0%)
build/edit-widgets/index.js 20.2 kB +30 B (0%)
build/editor/index.js 41.8 kB +58 B (0%)
build/editor/style-rtl.css 3.9 kB +4 B (0%)
build/editor/style.css 3.9 kB +4 B (0%)
build/element/index.js 4.61 kB +1 B (0%)
build/format-library/index.js 6.75 kB -3 B (0%)
build/keyboard-shortcuts/index.js 2.53 kB +4 B (0%)
build/media-utils/index.js 5.34 kB +1 B (0%)
build/notices/index.js 1.85 kB +3 B (0%)
build/nux/index.js 3.41 kB -1 B (0%)
build/primitives/index.js 1.42 kB +1 B (0%)
build/react-i18n/index.js 1.46 kB +2 B (0%)
build/redux-routine/index.js 2.84 kB +1 B (0%)
build/rich-text/index.js 13.4 kB +3 B (0%)
build/shortcode/index.js 1.7 kB -1 B (0%)
build/url/index.js 3.02 kB +1 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.14 kB 0 B
build/annotations/index.js 3.78 kB 0 B
build/api-fetch/index.js 3.4 kB 0 B
build/autop/index.js 2.82 kB 0 B
build/block-directory/style-rtl.css 1 kB 0 B
build/block-directory/style.css 1.01 kB 0 B
build/block-library/blocks/archives/editor-rtl.css 61 B 0 B
build/block-library/blocks/archives/editor.css 60 B 0 B
build/block-library/blocks/audio/editor-rtl.css 58 B 0 B
build/block-library/blocks/audio/editor.css 58 B 0 B
build/block-library/blocks/audio/style-rtl.css 112 B 0 B
build/block-library/blocks/audio/style.css 112 B 0 B
build/block-library/blocks/block/editor-rtl.css 161 B 0 B
build/block-library/blocks/block/editor.css 161 B 0 B
build/block-library/blocks/button/editor-rtl.css 475 B 0 B
build/block-library/blocks/button/editor.css 474 B 0 B
build/block-library/blocks/button/style-rtl.css 479 B 0 B
build/block-library/blocks/button/style.css 479 B 0 B
build/block-library/blocks/buttons/editor-rtl.css 315 B 0 B
build/block-library/blocks/buttons/editor.css 315 B 0 B
build/block-library/blocks/buttons/style-rtl.css 364 B 0 B
build/block-library/blocks/buttons/style.css 363 B 0 B
build/block-library/blocks/calendar/style-rtl.css 208 B 0 B
build/block-library/blocks/calendar/style.css 208 B 0 B
build/block-library/blocks/categories/editor-rtl.css 84 B 0 B
build/block-library/blocks/categories/editor.css 83 B 0 B
build/block-library/blocks/categories/style-rtl.css 79 B 0 B
build/block-library/blocks/categories/style.css 79 B 0 B
build/block-library/blocks/code/style-rtl.css 90 B 0 B
build/block-library/blocks/code/style.css 90 B 0 B
build/block-library/blocks/columns/editor-rtl.css 190 B 0 B
build/block-library/blocks/columns/editor.css 190 B 0 B
build/block-library/blocks/columns/style-rtl.css 421 B 0 B
build/block-library/blocks/columns/style.css 421 B 0 B
build/block-library/blocks/cover/style-rtl.css 1.24 kB 0 B
build/block-library/blocks/cover/style.css 1.24 kB 0 B
build/block-library/blocks/embed/editor-rtl.css 486 B 0 B
build/block-library/blocks/embed/editor.css 486 B 0 B
build/block-library/blocks/embed/style-rtl.css 401 B 0 B
build/block-library/blocks/embed/style.css 400 B 0 B
build/block-library/blocks/file/editor-rtl.css 199 B 0 B
build/block-library/blocks/file/editor.css 198 B 0 B
build/block-library/blocks/file/style-rtl.css 248 B 0 B
build/block-library/blocks/file/style.css 248 B 0 B
build/block-library/blocks/group/editor-rtl.css 318 B 0 B
build/block-library/blocks/group/editor.css 317 B 0 B
build/block-library/blocks/group/style-rtl.css 57 B 0 B
build/block-library/blocks/group/style.css 57 B 0 B
build/block-library/blocks/heading/editor-rtl.css 129 B 0 B
build/block-library/blocks/heading/editor.css 129 B 0 B
build/block-library/blocks/heading/style-rtl.css 76 B 0 B
build/block-library/blocks/heading/style.css 76 B 0 B
build/block-library/blocks/html/editor-rtl.css 281 B 0 B
build/block-library/blocks/html/editor.css 281 B 0 B
build/block-library/blocks/image/editor-rtl.css 717 B 0 B
build/block-library/blocks/image/editor.css 716 B 0 B
build/block-library/blocks/image/style-rtl.css 476 B 0 B
build/block-library/blocks/image/style.css 478 B 0 B
build/block-library/blocks/latest-comments/editor-rtl.css 159 B 0 B
build/block-library/blocks/latest-comments/editor.css 158 B 0 B
build/block-library/blocks/latest-comments/style-rtl.css 269 B 0 B
build/block-library/blocks/latest-comments/style.css 269 B 0 B
build/block-library/blocks/latest-posts/editor-rtl.css 137 B 0 B
build/block-library/blocks/latest-posts/editor.css 137 B 0 B
build/block-library/blocks/latest-posts/style-rtl.css 523 B 0 B
build/block-library/blocks/latest-posts/style.css 522 B 0 B
build/block-library/blocks/list/editor-rtl.css 65 B 0 B
build/block-library/blocks/list/editor.css 65 B 0 B
build/block-library/blocks/list/style-rtl.css 63 B 0 B
build/block-library/blocks/list/style.css 63 B 0 B
build/block-library/blocks/media-text/editor-rtl.css 191 B 0 B
build/block-library/blocks/media-text/editor.css 191 B 0 B
build/block-library/blocks/media-text/style-rtl.css 535 B 0 B
build/block-library/blocks/media-text/style.css 532 B 0 B
build/block-library/blocks/more/editor-rtl.css 434 B 0 B
build/block-library/blocks/more/editor.css 434 B 0 B
build/block-library/blocks/navigation-link/editor-rtl.css 620 B 0 B
build/block-library/blocks/navigation-link/editor.css 621 B 0 B
build/block-library/blocks/navigation-link/style-rtl.css 671 B 0 B
build/block-library/blocks/navigation-link/style.css 668 B 0 B
build/block-library/blocks/navigation/style-rtl.css 204 B 0 B
build/block-library/blocks/navigation/style.css 205 B 0 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B 0 B
build/block-library/blocks/nextpage/editor.css 395 B 0 B
build/block-library/blocks/page-list/editor-rtl.css 215 B 0 B
build/block-library/blocks/page-list/editor.css 215 B 0 B
build/block-library/blocks/page-list/style-rtl.css 527 B 0 B
build/block-library/blocks/page-list/style.css 526 B 0 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B 0 B
build/block-library/blocks/paragraph/editor.css 157 B 0 B
build/block-library/blocks/paragraph/style-rtl.css 247 B 0 B
build/block-library/blocks/paragraph/style.css 248 B 0 B
build/block-library/blocks/post-author/editor-rtl.css 209 B 0 B
build/block-library/blocks/post-author/editor.css 209 B 0 B
build/block-library/blocks/post-author/style-rtl.css 183 B 0 B
build/block-library/blocks/post-author/style.css 184 B 0 B
build/block-library/blocks/post-comments-form/style-rtl.css 250 B 0 B
build/block-library/blocks/post-comments-form/style.css 250 B 0 B
build/block-library/blocks/post-content/editor-rtl.css 139 B 0 B
build/block-library/blocks/post-content/editor.css 139 B 0 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B 0 B
build/block-library/blocks/post-excerpt/editor.css 73 B 0 B
build/block-library/blocks/post-featured-image/editor-rtl.css 338 B 0 B
build/block-library/blocks/post-featured-image/editor.css 338 B 0 B
build/block-library/blocks/post-featured-image/style-rtl.css 100 B 0 B
build/block-library/blocks/post-featured-image/style.css 100 B 0 B
build/block-library/blocks/preformatted/style-rtl.css 63 B 0 B
build/block-library/blocks/preformatted/style.css 63 B 0 B
build/block-library/blocks/pullquote/editor-rtl.css 183 B 0 B
build/block-library/blocks/pullquote/editor.css 183 B 0 B
build/block-library/blocks/pullquote/style-rtl.css 318 B 0 B
build/block-library/blocks/pullquote/style.css 318 B 0 B
build/block-library/blocks/query-loop/editor-rtl.css 90 B 0 B
build/block-library/blocks/query-loop/editor.css 89 B 0 B
build/block-library/blocks/query-loop/style-rtl.css 315 B 0 B
build/block-library/blocks/query-loop/style.css 317 B 0 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B 0 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B 0 B
build/block-library/blocks/query-pagination/editor-rtl.css 270 B 0 B
build/block-library/blocks/query-pagination/editor.css 262 B 0 B
build/block-library/blocks/query-pagination/style-rtl.css 168 B 0 B
build/block-library/blocks/query-pagination/style.css 168 B 0 B
build/block-library/blocks/query-title/editor-rtl.css 86 B 0 B
build/block-library/blocks/query-title/editor.css 86 B 0 B
build/block-library/blocks/quote/editor-rtl.css 61 B 0 B
build/block-library/blocks/quote/editor.css 61 B 0 B
build/block-library/blocks/quote/style-rtl.css 169 B 0 B
build/block-library/blocks/quote/style.css 169 B 0 B
build/block-library/blocks/rss/editor-rtl.css 201 B 0 B
build/block-library/blocks/rss/editor.css 202 B 0 B
build/block-library/blocks/rss/style-rtl.css 290 B 0 B
build/block-library/blocks/rss/style.css 290 B 0 B
build/block-library/blocks/search/editor-rtl.css 165 B 0 B
build/block-library/blocks/search/editor.css 165 B 0 B
build/block-library/blocks/search/style-rtl.css 342 B 0 B
build/block-library/blocks/search/style.css 344 B 0 B
build/block-library/blocks/separator/editor-rtl.css 99 B 0 B
build/block-library/blocks/separator/editor.css 99 B 0 B
build/block-library/blocks/separator/style-rtl.css 236 B 0 B
build/block-library/blocks/separator/style.css 236 B 0 B
build/block-library/blocks/site-logo/editor-rtl.css 201 B 0 B
build/block-library/blocks/site-logo/editor.css 201 B 0 B
build/block-library/blocks/site-logo/style-rtl.css 115 B 0 B
build/block-library/blocks/site-logo/style.css 115 B 0 B
build/block-library/blocks/social-link/editor-rtl.css 164 B 0 B
build/block-library/blocks/social-link/editor.css 165 B 0 B
build/block-library/blocks/spacer/editor-rtl.css 317 B 0 B
build/block-library/blocks/spacer/editor.css 317 B 0 B
build/block-library/blocks/spacer/style-rtl.css 48 B 0 B
build/block-library/blocks/spacer/style.css 48 B 0 B
build/block-library/blocks/table/editor-rtl.css 478 B 0 B
build/block-library/blocks/table/editor.css 478 B 0 B
build/block-library/blocks/table/style-rtl.css 402 B 0 B
build/block-library/blocks/table/style.css 402 B 0 B
build/block-library/blocks/tag-cloud/editor-rtl.css 118 B 0 B
build/block-library/blocks/tag-cloud/editor.css 118 B 0 B
build/block-library/blocks/tag-cloud/style-rtl.css 94 B 0 B
build/block-library/blocks/tag-cloud/style.css 94 B 0 B
build/block-library/blocks/term-description/editor-rtl.css 90 B 0 B
build/block-library/blocks/term-description/editor.css 90 B 0 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B 0 B
build/block-library/blocks/text-columns/editor.css 95 B 0 B
build/block-library/blocks/text-columns/style-rtl.css 166 B 0 B
build/block-library/blocks/text-columns/style.css 166 B 0 B
build/block-library/blocks/verse/style-rtl.css 87 B 0 B
build/block-library/blocks/verse/style.css 87 B 0 B
build/block-library/blocks/video/editor-rtl.css 504 B 0 B
build/block-library/blocks/video/editor.css 503 B 0 B
build/block-library/blocks/video/style-rtl.css 187 B 0 B
build/block-library/blocks/video/style.css 187 B 0 B
build/block-library/common-rtl.css 1.1 kB 0 B
build/block-library/common.css 1.1 kB 0 B
build/block-library/theme-rtl.css 700 B 0 B
build/block-library/theme.css 701 B 0 B
build/block-serialization-default-parser/index.js 1.87 kB 0 B
build/block-serialization-spec-parser/index.js 3.06 kB 0 B
build/customize-widgets/style-rtl.css 168 B 0 B
build/customize-widgets/style.css 168 B 0 B
build/deprecated/index.js 769 B 0 B
build/dom-ready/index.js 576 B 0 B
build/edit-navigation/style-rtl.css 1.31 kB 0 B
build/edit-widgets/style-rtl.css 3.2 kB 0 B
build/edit-widgets/style.css 3.2 kB 0 B
build/editor/editor-styles-rtl.css 347 B 0 B
build/editor/editor-styles.css 347 B 0 B
build/escape-html/index.js 735 B 0 B
build/format-library/style-rtl.css 637 B 0 B
build/format-library/style.css 639 B 0 B
build/hooks/index.js 2.28 kB 0 B
build/html-entities/index.js 623 B 0 B
build/i18n/index.js 4.01 kB 0 B
build/is-shallow-equal/index.js 698 B 0 B
build/keycodes/index.js 1.95 kB 0 B
build/list-reusable-blocks/index.js 3.14 kB 0 B
build/list-reusable-blocks/style-rtl.css 629 B 0 B
build/list-reusable-blocks/style.css 628 B 0 B
build/nux/style-rtl.css 731 B 0 B
build/nux/style.css 727 B 0 B
build/plugins/index.js 2.89 kB 0 B
build/priority-queue/index.js 791 B 0 B
build/reusable-blocks/index.js 3.78 kB 0 B
build/reusable-blocks/style-rtl.css 225 B 0 B
build/reusable-blocks/style.css 225 B 0 B
build/server-side-render/index.js 2.58 kB 0 B
build/token-list/index.js 1.27 kB 0 B
build/viewport/index.js 1.86 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.22 kB 0 B

compressed-size-action

@oandregal oandregal self-requested a review March 9, 2021 10:42
@youknowriad youknowriad self-assigned this Mar 9, 2021
@youknowriad youknowriad added the [Type] Code Quality Issues or PRs that relate to code quality label Mar 9, 2021
@youknowriad youknowriad marked this pull request as ready for review March 9, 2021 12:20
@youknowriad youknowriad added the Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json label Mar 9, 2021
@oandregal oandregal mentioned this pull request Mar 11, 2021
82 tasks
@youknowriad
Copy link
Contributor Author

Any reviews on this one.

@oandregal
Copy link
Member

I'm looking into this today.

@oandregal
Copy link
Member

I agree with the goal of this PR: parts of the existing API are too low-level. It's been on my mind to do these sort of changes for months but didn't find the time, so thanks for this push. I've created an alternative at #29905 Hopefully, that addresses your concerns.

There are upcoming changes to how we work with theme.json #29773 #29891 and we also need to consider hooks and versioning. I'm working on those changes in the coming weeks, so I'd like to take that as an opportunity to keep iterating on the API.

@youknowriad
Copy link
Contributor Author

@nosolosw It's unclear to me what are the goals of the alternative PR compared to the API proposed here? What didn't you like here? For me the alternative PR is still too low level.

Is still uses WP_Theme_JSON_Resolver to get resolve the config but for me WP_Theme_JSON_Resolver should just gives us a config model from which we can consume configs if that make sense. It only resolves the config object.

Also, the proposed API still leave a lot of things to the consumer instead of absorbing the complexity. Example:

WP_Theme_JSON_Resolver::get_settings( $theme_support_data ); 

Why I need to pass "theme support data" here. It's the role of the resolver to know how to merge things, As a consumer of the config, I don't care where the config comes from.

@youknowriad
Copy link
Contributor Author

The things related to the Post Type (registration...) I think are things that should be moved outside the resolver class (they should just be function called directly by the hooks, I don't see any value in adding these to the class but I left this separate.

@oandregal
Copy link
Member

While I agree with some of the choices this PR makes and other ideas you shared, I wasn't sure I was bought on the overall direction. I thought I'd share a proposal that clarifies what we have (WP_Theme_JSON mimics the format + WP_Theme_JSON_Resolver implements the business logic). I don't think these should be final but I'd like to have a clearer picture before making radical changes (implement the things in the queue, etc).

I've also noticed that this PR doesn't take into account the different code paths the API is called from: the block_editor_settings hook needs to pass the settings given to the hook (which are filterable by 3rd parties and some hosts such as WordPress.com uses this to disable certain things) while the wp_enqueue_scripts hook doesn't have those hence pulls them from the theme. That's why the API needs to know the settings at the moment. I believe this is a complexity that needs to be absorbed and I was hoping to do it in a further step, as part of hooks work #27504

@gziolo
Copy link
Member

gziolo commented Mar 17, 2021

I like the proposed abstraction, it hides all the complexity that is necessary to process theme.json and all that stuff. I will leave it to @youknowriad and @nosolosw to sort out the direction.

On the technical level, I see one failing PHP unit test:

https://github.com/WordPress/gutenberg/pull/29667/checks?check_run_id=2110975877#step:8:42

Screen Shot 2021-03-17 at 09 39 26

So it would need to be resolved before we move forward with these changes.

self::$theme = new WP_Theme_JSON( $theme_json_data );
}

private static function get_theme_data( $theme_support_data = array() ) {
Copy link
Member

@gziolo gziolo Mar 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I use the get_theme_data method in the test I added in #29828 (still waiting for review), but I'm sure it can be changed to use higher-level API.


function test_presets_are_extracted() {
$actual = WP_Theme_JSON_Resolver::get_presets_to_translate();
$actual = WP_Theme_Config_Resolver::get_presets_to_translate();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can eventually remove this test in favor of the test I proposed #29828. It operates on a higher level and ensures that translations are applied. It would let us keep this method private since it is never used outside of the config resolver.

@youknowriad
Copy link
Contributor Author

while I think this PR is still valuable and a good direction, I don't want to distrupt the current work on theme.json format more. So I'm going to close this PR for now and I'll reopen it once we're done with the format adaptations.

@youknowriad youknowriad deleted the refactor/theme-config branch March 18, 2021 09:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Global Styles Anything related to the broader Global Styles efforts, including Styles Engine and theme.json [Type] Code Quality Issues or PRs that relate to code quality
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants