-
Notifications
You must be signed in to change notification settings - Fork 385
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
Prevent infinite recursion error when active theme is set to be same as reader theme #5899
Conversation
…ional when active theme is same as reader theme
Codecov Report
@@ Coverage Diff @@
## develop #5899 +/- ##
=============================================
- Coverage 75.32% 75.28% -0.04%
- Complexity 5715 5722 +7
=============================================
Files 214 214
Lines 17261 17283 +22
=============================================
+ Hits 13001 13012 +11
- Misses 4260 4271 +11
Flags with carried forward coverage won't be shown. Click here to find out more.
|
Plugin builds for 9baed99 are ready 🛎️!
|
…ansitional when reader theme is same as active theme
…r-theme-recursion-edge-case * 'develop' of github.com:ampproject/amp-wp: Increase default Jest timeout to 30s Test that cron services are conditional Add comment for needed change to should_schedule_event Put SavePostValidationEvent and URLValidationCron behind a feature flag filter
@@ -159,7 +159,7 @@ export function ReaderThemeCarousel() { | |||
{ | |||
sprintf( | |||
/* translators: placeholder is the name of a WordPress theme. */ | |||
__( 'Your active theme “%s” is not available as a reader theme. If you wish to use it, Transitional mode may be the best option for you.', 'amp' ), | |||
__( 'Your active theme “%s” is not listed below because it is AMP-compatible. If you wish to use it, Transitional mode is what you should choose.', 'amp' ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The copy in assets/src/components/reader-theme-selection/index.js
would have to be updated as well:
__( 'Your active theme “%s” is not available as a reader theme. If you wish to use it, Transitional mode may be the best option for you.', 'amp' ), |
We should extract the relevant duplicate components from both files into its own component to prevent the onboarding wizard and settings page from being out of sync.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've extracted the common strings into a new component in 7e66e9f:
Settings Screen | Onboarding Wizard |
---|---|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The
ReaderThemesContextProvider
for the Onboarding Wizard screen is configured to not filter the currently active theme when displaying the list of reader themes to choose from.
Oh yeah, right. I remember we intentionally included the Reader mode-eligible active theme in the list of all Reader themes and then automatically switched to Transitional mode on the summary screen if they select the same one. But now this seems unnecessary. Perhaps we should align the behavior with what is on the settings screen: don't include the active theme in the list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've hidden the active theme in the lit of Reader themes in the Onboarding Wizard in 335d306. I don't feel strongly that this is the right way to go, however. Maybe we were thinking in the Onboarding Wizard that it was better to not force the user to make that decision up-front. If we do indeed eliminate showing the active theme among the reader themes, then this is dead code:
amp-wp/assets/src/onboarding-wizard/pages/summary/transitional.js
Lines 29 to 37 in 0ac7064
const { readerModeWasOverridden } = useContext( Options ); | |
return ( | |
<> | |
{ readerModeWasOverridden && ( | |
<AMPNotice type={ NOTICE_TYPE_INFO } size={ NOTICE_SIZE_LARGE }> | |
{ __( 'Because you selected a Reader theme that is the same as your site\'s active theme, your site has automatically been switched to Transitional template mode.', 'amp' ) } | |
</AMPNotice> | |
) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Scratch that. I've gone back to showing all themes in the Onboarding Wizard, but I've removed the notice from being displayed there.
…rding Wizard" This reverts commit 335d306.
… about active theme
… switched to Transitional
OK, now a notice appears in the “Template Mode” section and the “Customize Reader Theme” button his hidden when the active theme has been switched to be the same as the Reader theme: The implementation is not ideal because there remains a flash of unconfigured content when loading: flash-of-unconfigured-content.movThis isn't the end of the world since this is going to be a very rare occurrence, but one of you'd surely implement it better to avoid this. |
Oh no, actually the Reader themes are already being preloaded: amp-wp/src/Admin/OptionsMenu.php Lines 280 to 288 in fa806a7
I'm curious why there is a delay. |
As far as I understand, it's because the themes are requested only if they are really needed, i.e. when the amp-wp/assets/src/components/reader-themes-context-provider/index.js Lines 197 to 207 in 7f8b658
Those requests are triggered sequentially. First, the options need to be fetched. Once it's done and the In my first attempt, the entire "Template Mode" section rendering was delayed so that the state could become stable. However, it caused the next sections to jump around (as noted in the previous comment). Another way would be to wait with the rendering of the entire settings page until the state is stable, but I think it could impact the UX. The only other approach I could think of right now would be to somehow merge the two context providers ( @westonruter Do you have something else on your mind? Maybe something we could do on the backend like getting the overridden set of options from the very beginning so that we don't have to update the state on the frontend before it even gets rendered? |
…r-theme-recursion-edge-case * 'develop' of github.com:ampproject/amp-wp: (153 commits) Update test snapshots Bump @wordpress/plugins from 2.24.5 to 2.24.6 Add explanation for what sanitization entails Fix tests in WP 4.9 Remove extraneous sprintf() Set placeholder attribute when we are sure we will match Use xpath query to obtain the placeholder Combine conditions Remove extraneous sprintf() Add test for tumblr in embed block Test removal of Tumblr script when wpautop was not involved Make use of MarkupComparison Make sure that Tumblr embed has a link to use as a placeholder Opt to combine add_twentytwentyone_overflow_button_fix into amend_twentytwentyone_styles Make sure TT1 stylesheet is enqueued before adding inline style Add style rule to place overflow button in bottom left corner of AMP component Set button type Allow hyphens in Server-Timing keys Fix indentation Apply style rules for AMP iframe resize button via core sanitizer ...
@delawski Thanks for your detailed explanation. I tested out the latest changes and the template modes section is OK, but it turns out to show the loading placeholder even in the normal reader state when the template mode is not overridden: template-mode-not-overridden.movI thought that this would only be the case when an override is needed, but I see that it's needed now because we don't know if an override will be needed or not yet. In the case of when an override is needed, there is something else that is not ideal: the “Customize Reader Theme” momentarily appears and then gets hidden when the override happens at which time the notice is also displayed: template-mode-overridden.mov
Instead of having the loading state/skeleton maybe it would indeed be then preferable to hide the entire UI (showing a spinner) until all of the data has been loaded, as you suggested? Since the data is already preloaded, it means the UI would only be held from rendering for another fraction of a second. This is much preferable to there being layout shifting. |
This seems good to do even if we opt to set the overridden state in the options REST API response, since at present the initial render does not show the name of the selected Reader theme: reader-theme-name-not-shown-on-first-render.movSee how “Twenty Twenty-One” shows up a split second after the initial render. By hiding the UI until all data loads, we can avoid this and avoid showing the non-overridden state. We could also look at moving the override logic to the REST API, but still preventing rendering until all the state has been populated should be done to prevent the need to do any re-rendering. |
…case' into fix/reader-theme-recursion-edge-case
@westonruter I'm now leaning towards your approach, i.e. wait with the rendering until we have a stable state ready instead of showing skeleton components. This use case doesn't really require skeletons as we have the data already prefetched on the page. So the loading state shows up for a split of a second anyway. I've revered some of my previous changes and pushed the updated logic that makes the rendering wait until the state is stable. |
…r-theme-recursion-edge-case * 'develop' of github.com:ampproject/amp-wp: Make attribute assertion more specific Utilize wp_print_inline_script_tag() to print mobile redirection script
This looks great! The UI feels much more stable now: reader-theme-same-as-active-theme.movreader-theme-different-from-active-theme.mov |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is working great for me.
@pierlon Any changes you'd like to see or do you approve as well?
@@ -135,7 +136,7 @@ function Root( { appRoot } ) { | |||
}; | |||
}, [ fetchingOptions ] ); | |||
|
|||
if ( false !== fetchingOptions ) { | |||
if ( false !== fetchingOptions || null === templateModeWasOverridden ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of templateModeWasOverridden
maybe it would make more sense to use fetchingThemes
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess not since that's not sufficient to prevent the re-render.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not just check if fetchingOptions
is truthy?
if ( false !== fetchingOptions || null === templateModeWasOverridden ) { | |
if ( fetchingOptions || null === templateModeWasOverridden ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We want to show the loading spinner not only when the options are being fetched (true
), but also initially, when the state is not "stable" yet (null
).
Although now with the second condition this case is covered via templateModeWasOverriden
, I'd still keep the explicit false !== fetchingOptions
in here.
Co-authored-by: Pierre Gordon <[email protected]>
Investigating why the PHP 7.1 test job is failing. It's also occurring on the |
So the cause of the errors are due to the EXIF data for As for why it's only occurring on PHP 7.1, it seems the issue of reading EXIF data for motorola byte order encoded images was patched in PHP 7.2, but was not backported to 7.1 possibly due to the large set of changes to be made as alluded to by one of the release managers for PHP 7.0 in this bug report:
So to resolve this, I think all that's needed is to use a different image to test against and avoid |
Excellent sleuthing. I'm gonna try swapping with |
I've cherry-picked 9baed99 onto the |
QA Passed With the Reader theme set to Twenty-Twenty One, I made the active theme also Twenty-Twenty Once via the command
On the themes admin screen, Twenty-Twenty One is shown as the active theme, and no reader theme is shown: On the Settings page, the template mode is set to Transitional by default, and a notice is shown informing the user of the switch from Reader mode: On the frontend, transitional mode can be verified by taking a look at the meta generator tag: <meta name="generator" content="AMP Plugin v2.1.0-beta2; mode=transitional"> Paired Browsing is also available: |
Summary
In #4984 via 093b40c & 0064cbc the AMP plugin would dynamically set the template mode from
reader
totransitional
when the active theme has been changed to be the same as the selected reader theme. This switch is problematic because it involves a check for whether the request has an AMP endpoint, and as noted in a4f2ed4:Well, I just ran across this issue. I had set my Reader theme to be Twenty Twenty-One and then I switched my active theme to also be Twenty Twenty-One via
wp theme activate twentytwentyone
. Upon doing so, WP would error out with:If the issue with the undefined service is resolved by moving the
paired_routing
definition up higher in\AmpProject\AmpWP\AmpWpPlugin::SERVICES
then what happens is infinite recursion whereWP_Options_Manager::get_options()
callsPairedRouting::get_paired_url_structure()
which then callsWP_Options_Manager::get_options()
and so on.Instead of dynamically changing the template mode from
reader
totransitional
in the options, what is needed instead is to update the UI on the settings screen to set the template mode to Transitional upon landing on the screen. This was similarly done before if a user had selected a Reader theme, but when they went back to the settings screen that theme was no longer installed and the theme had to be switched back to Legacy (see #5170). The same settings screen switch which was done for the unavailable Reader theme needs to also be done for the template mode when the selected Reader theme is the same as the active theme.When the active theme is the same as the selected Reader theme and Reader mode is selected:
Checklist