
Problem
- The preprocessing and rendering for the
maintenance-page
andinstall-page
templates requires tons of ugly hacks and workarounds, because the two pages are not wrapped into the usualhtml
template.
Proposed solution
- Remove that special casing and wrap the page output into the
html
template as usual.
Comment | File | Size | Author |
---|---|---|---|
#57 | interdiff.txt | 4.79 KB | sun |
#57 | theme.maintenance.57.patch | 49.36 KB | sun |
#41 | theme.maintenance.41.patch | 46.04 KB | sun |
#39 | interdiff.txt | 6.75 KB | sun |
#39 | theme.maintenance.39.patch | 46.04 KB | sun |
Comments
Comment #1
sunMy latest & greatest trick to further simplify the early installer environment:
:-)
Comment #3
sunI... have no idea how this patch manages to do this, but it only occurs with Standard profile:
Comment #4
sunThis backtrace clarifies it:
block_page_build()
kicks in, because Block module is installed by Standard profile.This patch removes all the special-casing for the install page, so
hook_page_build()
of Block module is actually executed as soon as it is installed! :-)And
block.block.seven_login.yml
contains:So we have these options:
3) + 4) are plain silly, so only 1) + 2) are sensible options.
My favorite would be (1), but I already guess that the module list is actively used for much more when modules are installed (e.g., to discover/install config for other modules).
But let's try that first:
Intentionally cripple the installer environment to system + ?user + ?profile modules.
Comment #5
sunComment #7
sunOK, that ends with:
Thus, only option (2) remains. Which is essentially the same as HEAD.
However, HEAD bakes that special case into
template_preprocess_maintenance_page()
, which is invoked at the very end of the page rendering chain and thus that doesn't work with this patch. Instead, we need to cover the special case directly indrupal_prepare_page()
.Comment #9
sunBut now... I'm unable to reproduce that installation failure reported by the testbot.
Installation with Standard profile works perfectly fine for me.
Another incident of #1808220: Remove run-tests.sh dependency on existing/installed parent site ?
Comment #10
dawehnerManually tried to reproduce the failure. Both manual install, run-tests and drush si worked fine.
Just a random guess: do the testbot have sqlite installed?
As far as I understand these reason for changes is that we want to "boot" up the system module. In a normal drupal we could use the DrupalKernel which would register the module as well as adapt the classloader.
So tryed to use it, though this opens all kind of problems. How did that worked before? Afaik previously system_page_build was not fired so that it never needed its classes? What do you think about checking in _drupal_render_process_post_render_cache that we actually can call the render_cache callback? In an ideal world something like render cache would not fire at all during the installer.
Do we already have a dependecy on sqlite somewhere else? This feels like a pretty big additional tbh.
Let's construct at least a proper response object now.
Additional I realized that the drupal_get_header() call is the last remaining one, so it would be pretty nice to already add it to the response object,
which we will use later as well. Question: Is this actually needed in the installer? This code would not be needed if FinishResponseSubscriber could fire.
Comment #12
tstoecklerWould a solution to this problem be making the installer design a separate theme alltogether? I've never understood why it is officially the 'seven' theme even though it looks nothing like the Seven theme in the actual admin interface.
Comment #13
sun@tstoeckler: Nope, forcing all installation profiles to ship with a separate theme for the installer would be crazy. ;-) Typically the installer appearance should follow the overall experience and just loads some additional asset libraries.
@dawehner:
install.core.inc
only thus far. — Yes, normallyDrupalKernel
takes care of registering the modules, but we are manually overriding the module list. — In light of this, I wonder whether these manual module list overrides aren't architecturally broken... IMHO, such code should call a method onDrupalKernel
, instead of manually futzing withModuleHandler
. → Speaking of, all we're missing is a call toDrupalKernel::updateModules()
._drupal_render_process_post_render_cache()
is debatable, since assigning non-existing callback should normally blow up... Therefore, I'd like to revert that. It's also a bit out of scope, as we've fixed the classloader registration already.hook_page_build()
for the maintenance page and install page. Therefore, my suggestion is to simply wrap the invocation intoif (!defined('MAINTENANCE_MODE'))
.Let's see how this performs:
Interdiff is against #7.
Comment #14
sunComment #16
sunComment #18
sunAlright... let's further strip this down until we're able to pinpoint the testbot installation problem.
(btw, the recent testbot runs were based on PIFR 2.x and thus did not use
drush site-install
but manually walked through the interactive installer instead.)Comment #20
sunAt least we have test results now :-)
Comment #21
sunThis is ugly, but the current legacy code paths do not leave much room for a cleaner alternative right now:
Added *temporary* DefaultHtmlPageRenderer::renderPage() helper, in order to move forward.
Comment #23
dawehnerIt would be cool if you could explain with a few words why there is no alternative.
Comment #24
sunre #23: The maintenance page is rendered by all of the special front controllers (install.php, update.php, authorize.php, etc), which are not converted to a kernel + request/response architecture at all yet. — Converting (rewriting) those is out of scope here, so we need a temporary helper function that allows to render a maintenance/install page.
But even that is a step forward; centralizing all those special cases to call a single helper function will help us to convert those special front controllers.
Comment #26
sunComment #28
sunMerged 8.x.
Comment #30
mgiffordThe output looks good. Here are some screenshots from SimplyTest.me:
Eventually we should remove the Skip links on the Maintenance Page, but that should be in a different issue.
Comment #31
sunResolving the last test failures:
Fixed bogus variable name in update_check_requirements().
Not going to fix the
InstallerTranslationTest
failures, because those test assertions will be removed entirely with #318975: Remove confirmation page after installation, which is RTBC already.The only remaining @todo that is also added in code by this patch is whether we want to try to rename the templates as part of this patch?
I'd prefer to do that in a separate follow-up issue, but could be convinced to do it here if someone comes up with a good reason for doing so.
Comment #33
sun31: theme.maintenance.31.patch queued for re-testing.
Comment #34
sunYay! :-)
Comment #35
mgiffordWhat testing should be done before this is marked RTBC? Glad the tests are in place.
Comment #36
sunSince the new code mostly goes through the regular HTML page rendering pipeline, no special testing is required for this patch.
In fact, this patch removes a test for
#theme maintenance_page
, as mentioned in #26, because that test is pointless now.From my perspective, this patch only needs technical reviews, because the UI is not changed at all (aside from adding the standard "Skip to content" link that we discussed already.)
The changes to
drupal_prepare_page()
could potentially be reverted, because that function is not invoked anymore. At the same time, that function only seems to get invoked from very similar edge-cases (e.g. BatchController), so we might as well keep those changes (and/or just don't care).hook_page_build()
is intentionally not invoked from the new helper method. I already considered to document that, but how do you document that some non-existing code is not executed, because you intentionally did not include/call the code? :P — j/k, I'll add some.In any case, the new helper method needs reviews, and also, I'm not happy about the amount of added
!defined('MAINTENANCE_MODE')
conditions, although I don't think we can do much about the latter.Comment #37
joelpittetThis is looking awesome! Nice work @sun.
page--maintenance.html.twig
andpage--install.html.twig
as normal suggestions would be my suggestion suggestion;) Though with theme suggestions it would have been nice to have their respective preprocess functions override the default template_preprocess_page in this case to avoid the !defined('MAINTENANCE_MODE'), though I don't think that's possible...Needs a small re-roll on some bartik/seven maintenance page tweaks that have been commited.
Comment #38
sunUpdated for new .maintenance-background HTML class in Seven theme.
Comment #39
sunComment #40
sun39: theme.maintenance.39.patch queued for re-testing.
Comment #41
sunMerged 8.x.
Comment #42
jessebeach CreditAttribution: jessebeach commentedI've manually tested maintenance pages and install pages in standard and minimal profiles. No issues.
The code looks much better than what we have now for maintenance page and install page rendering. This patch doesn't completely eliminate their special flower status, but it moves us in the right direction.
I had reservations introducing
\Drupal\Core\Page\DefaultHtmlPageRenderer::renderPage()
. It's highly specific to maintenance and install page rendering. But then, these two pages are special flowers already and this is an intermediate step to integrate these pages into a normal page render flow. The method is marked as@internal
and the docblock warns devs not to use it.I've gone through the patch and created issues for all the
@todos
. None are blocking or Major/Critical. This is follow-on work we can do at leisure.Follow up issues
#2231853: Rename maintenance-page template into page--maintenance + install-page into page--maintenance--install
#2231857: Rename install-page.html.twig to page--install.html.twig
Comment #43
sunAs this happens to affect the (critical) #1067408: Themes do not have an installation status, I guess we should at least bump this to major?
Comment #44
alexpottCommitted 10b0389 and pushed to 8.x. Thanks!
I was debating the need for a change notice - afaics we don't need one yet - the followups will though.
Removed unused uses during commit
Comment #46
tim.plunkettrdf_preprocess_html() calls rdf_get_namespaces() which invokes hooks. Hitting /update.php with rdf.module turned on will throw exceptions.
Before this patch, it was completely reasonable for a module to invoke hooks in hook_preprocess_html/hook_preprocess_page, with this patch it is not.
Comment #47
sunThere are two conflicting expectations:
hook_preprocess*
is invoked for a page.→ If any hook_preprocess implementation calls any hook that isn't allowed, update.php blows up.
hook_preprocess* itself is allowed. But
rdf_preprocess_html()
tries to invokehook_rdf_namespaces()
. Thus, when visiting update.php when RDF module is enabled, then the exception is triggered.Due to the conflicting expectations, I don't really have a proposal for how to resolve this.
As a matter of fact, it's pure coincidence that this patch revealed that problem. The same code path can be triggered through plenty of other mechanisms; e.g., #pre_render/#process/#after_build callbacks on form elements (that happen to be used on the update.php page), and most likely a lot more call chains. Just invoke a hook that happens to be not allowed in any of these, ka-boom.
We can't easily prevent the theme system from invoking preprocess functions in modules, because the "offline theme registry" (formerly used on the maintenance page) was removed a long time ago.
I'm aware why that hook limitation for update.php was introduced, but I'm not sure whether it is still necessary...?
IMO, this regression is a completely separate problem space — in essence, this change here is not flawed; it's the change that introduced that hook limitation that is flawed; because as we can see, the idea does not work out.
Comment #48
jessebeach CreditAttribution: jessebeach commentedThis is back to being a beta blocker.
Comment #50
webchickFlawed assumption or not, we can't sit around with broken update.php. Therefore, I've rolled this back for now until we can come to a resolution.
We also need to open a critical for test coverage of this code path, because that should never have happened.
Comment #51
alexpottTagging...
Comment #52
alexpottSo I added the beta blocker tag because I thought it had been removed by accident. I was wrong. At most this is a soft blocker for #1067408: Themes do not have an installation status
Comment #53
xjmI'd suggest we make the test coverage blocking for this issue, not a followup.
Comment #54
sunThis patch only revealed a problem with the current update.php environment. The changes of this patch itself are fine on their own; there's nothing this patch could do to fix a problem that it didn't introduce. But yes, of course, we want update.php to work :-)
Created #2233403: Let update.php invoke hooks again
Comment #55
sun41: theme.maintenance.41.patch queued for re-testing.
Comment #57
sun#2233403: Let update.php invoke hooks again is resolved.
Comment #58
dawehnerThis is quite a WTF but okay as this function is just temporary.
Comment #59
webchickOk, cool. Let's try this again.
Committed and pushed to 8.x. Thanks!
Comment #60
sunDoesn't appear to have been committed/pushed.
Comment #61
webchickSorry about that! Try now. :)
Comment #64
wim leersRelated: #2327277: [Meta] Page rendering meta discussion.