-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Discussion: Move FSE auto-draft creation into a read-time filter #27284
Comments
Currently, I believe it is executed only on That's an interesting idea, and it seems like it could theoretically work. I wonder if we could go even further by asking the question, "when can a template file change?" I believe only a few times:
I wonder if we could simplify everything by only running the database sync op on theme activate or update. We wouldn't check the files outside of that. Then we could add a specific dev mode which does the sync op on wp_load to make sure development changes exist. I think the main limitation of this approach is "what if the data goes missing or gets corrupted at some point". The benefit of doing the sync all the time is that we are constantly making sure that it's there when it needs to be. I could see someone deleting the "auto-drafts" (or whatever they will become), and then not having a working theme any more. |
I think we had a quite in-depth discussion here: #26383 Originally we wanted this:
But we ditched it. We had synchronization code laying around everywhere, rather than one place to handle it. We are already checking for file modification times, which should be enough to prevent perf problems. We aren't reading the files if they haven't changed since the last check time.
This would overcomplicate everything 😬
If we don't have CPTs for all the templates then we can't show them in the navigation sidebar or in the I'd lean towards this PR: #27277 This cleans up all the |
Thanks for the issue and this is exactly why we did the recent refactoring in the first place. So it seems like you're suggesting that it's not working as intended? you're basically suggesting to move from |
Thanks @noahtallen, @david-szabo97, and @youknowriad! To be clear, my main concern is less about performance, but about 'correctness' and stability. I was recently dealing with an issue that was also related to synchronization, and some takeaways from there got me thinking about how could apply them to FSE. 'Correctness' not for correctness' sake: Synchronization can be messy and fragile, in that one must be careful to add the required sync step(s) whenever an operation is performed that requires it. This isn't obvious to contributors that haven't worked on the project before and who'd like to extend it -- bugs can crop up easily there. I believe that our code is most stable when it best expresses semantically what we're trying to achieve -- this is why I've emphasized the requirements (create a template CPT: only at read time, when there's no CPT yet for the template in the DB, etc). @youknowriad I didn't just want to move the sync logic from @noahtallen It's true however that I missed cases such as theme updates or switches that would still require syncing. (Thanks for pointing those out to me!) I still think it might be worth exploring an alternative a bit more, if y'all are willing to indulge me 😬 Let me restate the problem: Let's think of the case of a freshly activated FSE theme whose templates haven't seen any modifications by the user in the Site Editor yet. If that website is loaded on the frontend, we wouldn't even need CPTs at all for things to work -- it'd be enough to load the relevant template file instead. Let's assume for a moment we start by implementing a first iteration of FSE just like that -- completely ignoring the Site Editor and Let's now consider the Site Editor as the next iteration, added on top of that first stage. We decide to use a Only once the editor comes in do we need the CPT to be actually created -- because that's how the editor works: It requires a post-like object. This is where things get tricky. Our current solution has lumped together template resolution and CPT creation (the latter through auto-drafts, at the moment). This turned out difficult to get right, and has necessitated the sync logic. But that solution is firmly based on the requirement that the editor needs a post-like object for editing. This has allowed us to make minimal adjustments to the editor, but has required a lot of logic at a lower level. But since it's proven quite difficult to do all that to make the editor work, maybe it's reasonable to instead change the editor to accomodate for a system that otherwise works fine? How about we extend the concept of a 'blank' initial, unsaved, state (that's e.g. currently used for a new post in the post editor) into a customized one, that can be provided to the editor, basically as a prop? I.e. a post-like object -- but without all the DB ties, i.e. no ID etc. Really just a continuation of the blank slate into more customized territory. A bit like a template (for lack of a better word) in a word processor 😉 |
That's really interesting, Bernie, thanks for sharing! I definitely understand the first few phases, and I buy into that idea a bit. I do wonder how performance compares though. For example, is rendering a template by reading from the database significantly faster than rendering a template by reading from the filesystem? If it is much faster, maybe we would prefer to keep the CPT approach for rendering? Changing the editor, though, would definitely be the challenging part of this. I'm not sure what I think, but some thoughts:
|
Yep, sounds like we did have the same idea -- yay for alignment!
We don't -- the issue title doesn't really apply to this idea anymore. I'll close this issue in favor of #27321. |
Since the inception of Full Site Editing, auto-draft creation has been a pain point. The original requirements seem simple enough:
In order to leverage the block editor's existing functionality and patterns, it was decided to store templates in
wp_template
CPT objects (and template parts inwp_template_part
), which can then be edited in Gutenberg. But this means we still need a bridge from template files to those CPTs, when first editing a template.This is where auto-draft creation comes in: Whenever attempting to load a template, we first check whether there's already a CPT object for it; and if there isn't, we check if the current theme includes a template file for it. If the latter, we then create an on-the-fly
wp_template
object for it (with its post status set toauto-draft
) and persist it to the DB. This doesn't just apply to loading in the editor, but also on the frontend, or more generally to any read access to a template -- e.g. when bundling all templates for export in a zip. Only once it's actually been edited and saved, thewp_template
object will get thepublish
post status.auto-draft creation has proven notoriously tricky for as long as people have worked on them: It had to be extended multiple times, e.g. to work for querying templates via the REST API; to accomodate for cases when the CPTs were deleted; etc. This also necessitated storing a number of additional meta data, and updating them through a number of actions.
I think that all of these things are inherent in what is basically a sync workflow: Whenever a
wp_template
object is read or modified, we need to do a bunch of bookkeeping to make sure it doesn't "disagree" with the underlying template file. This process is necessarily manual, and error-prone, as it's easy to miss instances where running these methods is required.I had a quick Slack chat with our lovely FSE folks earlier today, and they have a few good ideas how to circumvent some of the issues inherent in the
auto-draft
post status (e.g. by using a different post status).I wanted to discuss an idea that might be complementary to these efforts.
Cycling back to the first paragraphs of this issue, we really only need the auto-draft when:
wp_template
objectThe first item -- trying to read a
wp_template
object -- is relevant: I think it basically boils down to this call ingutenberg_resolve_template
:gutenberg/lib/template-loader.php
Lines 127 to 145 in 3d5c413
(There's at least one copy of sorts of this logic, in
gutenberg_edit_site_export
.)My suggestion is basically the following: Knowing that we need to provide the auto-draft at read time, how about creating it inside of a filter that is applied at read time? The best candidate that I could find is
the_posts
(but there are a few 'nearby' ones). That filter allows to modify the results list, and gets the original query as an additional argument. We could do something likeOne major advantage of this approach would IMO be that we'd separate concerns much better: We'd only ever create the auto-draft for the one template that is being queried (after template resolution is done, and cleanly separated from it), rather than creating them in bulk upon first loading, such as
_gutenberg_synchronize_theme_templates
does now. In fact, I hope that this would allow us to get rid of about pretty much all other synchronization logic.One downside is that it would quite clearly add side effects to a filter -- that go as far as to write to the database in such a way that changes the results that are returned for the original read operation. (Tho we're kinda doing that already -- there might not be a way around that, given the prerequisites for FSE).
I was originally hoping we could even get away with 'simulating' a
wp_template
object when there really isn't one in the DB, and have thethe_posts
filter return it, but I now think that that wouldn't work: We'd probably need to include anID
that would be used by the editor when modifying the object, and we can't just pull one out of thin air.Curious to hear your thoughts: @vindl @Copons @david-szabo97 @Addison-Stavlo @noahtallen @jeyip @mattwiebe and of course @youknowriad 😄
The text was updated successfully, but these errors were encountered: