WordPress.org

Make WordPress Core

Opened 6 years ago

Closed 6 years ago

Last modified 6 years ago

#25964 closed defect (bug) (fixed)

Appearance Themes: find a way to provide a no-js fallback

Reported by: matveb Owned by: nacin
Milestone: 3.8 Priority: highest omg bbq
Severity: blocker Version: 3.8
Component: Customize Keywords:
Focuses: Cc:
PR Number:

Description

Right now all the views are rendered with wp.Backbone. We need to provide a functioning experience for no-js scenarios in a way that doesn't burden the normal experience excessively, nor breaks the advantage of having live views.

Attachments (1)

25964.diff (14.4 KB) - added by adamsilverstein 6 years ago.
first pass at no-js solution

Download all attachments as: .zip

Change History (12)

#1 @SergeyBiryukov
6 years ago

  • Milestone changed from Awaiting Review to 3.8

#2 @dd32
6 years ago

It appears that the only way we'll be able to do this is to render a similar output that the JS creates within a <noscript> tag.

We may however want to investigate how screen readers and other accessibility tools access our new page, as we may want to create the no-js version as an accessibility mode instead which uses little JS.

#3 @samuelsidler
6 years ago

  • Priority changed from normal to high

#4 @nacin
6 years ago

  • Priority changed from high to highest omg bbq
  • Severity changed from normal to blocker
  • Type changed from enhancement to defect (bug)

#5 @markjaquith
6 years ago

NB: <noscript> won't suffice, because we also have to take into consideration a JS error making it such that you can't change your theme (and what if the JS error is from the theme?). Recommended approach is to do an initial PHP render, then have Backbone take over and re-render on top (resulting in no visual changes, if done right). I'm okay with Search not being done with PHP. Just the initial list of themes with the Activate buttons available should suffice.

@adamsilverstein
6 years ago

first pass at no-js solution

#6 @adamsilverstein
6 years ago

possible nojs solution, uses themes.php from 3.7.1: 25964.diff​

  • include a copy of themes.php from WordPress 3.7.1 renamed as themes-no-js and includes removed
  • include this file wrapped in a div in new themes.php
  • add JS to app startup that removes old page html from DOM
  • tested a bit with js off seems to work fine, new HTML already wrapped in <script> tags so not displayed

#7 follow-up: @matt
6 years ago

If there is a specific use case we want to support, like activating a theme that breaks JS and you can no longer deactivate it, perhaps we could constrain the no-js functionality to something small like that: Text listing of current theme and a deactivate link.

This ticket isn't the time or place to debate it, but it's interesting to think about where we draw the line functionally as wp-admin shifts to be basically a JS application passing data back and forth to PHP rather than HTML whether it's worth it to essentially write everything twice, or leave the existing legacy HTML interfaces as gradually every screen in wp-admin, and the majority of the admin codebase, becomes client-side javascript.

#8 @nacin
6 years ago

  • Owner set to nacin
  • Status changed from new to accepted

I'm almost done with a patch here.

Last edited 6 years ago by nacin (previous) (diff)

#9 in reply to: ↑ 7 @adamsilverstein
6 years ago

Replying to matt:

If there is a specific use case we want to support, like activating a theme that breaks JS and you can no longer deactivate it, perhaps we could constrain the no-js functionality to something small like that: Text listing of current theme and a deactivate link.

This ticket isn't the time or place to debate it, but it's interesting to think about where we draw the line functionally as wp-admin shifts to be basically a JS application passing data back and forth to PHP rather than HTML whether it's worth it to essentially write everything twice, or leave the existing legacy HTML interfaces as gradually every screen in wp-admin, and the majority of the admin codebase, becomes client-side javascript.

Yea! I am all for switching the admin to primarily JS tied to a PHP backend and glad to hear you are thinking along the same lines! I can envision the day when the page never 'reloads' from the moment you hit the login screen. I agree we would be better off with nojs support of only the most basic, required features.

#10 @nacin
6 years ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 26726:

No-JavaScript and no-Customizer support for the new Themes screen.

JavaScript is rarely disabled, but graceful degradation is still important. For example, syntax errors can occur, usually with major WP updates that overhaul entire experiences and update external libraries combined with themes or plugins doing weird or old things. If this error is due to their current theme, a user needs to be able to access the themes screen to switch away from the theme. A more subtle issue could make things painful to diagnose.

This commit renders the grid in PHP (the template is duplicated, but it lightweight, fairly mundane, and easy to sync). On Backbone render, the grid is then re-rendered from JavaScript so searches can occur. Customize and Live Preview is disabled if JS fails to kick in. If JS is disabled, old-school "Preview" links are displayed.

No-Customizer support: The customizer is only supported when the browser supports postMessage (IE8+), and if the frontend is a different domain, CORS (IE10+). We use the .hide-if-no-customize class for this. Pre-customize "Preview" links should use .hide-if-customize.

The .load-customize class should be used to declare a link that opens the customizer. This enables customize-loader.js to intercept this link and load the customizer on top of the current window, making for a smoother experience.

fixes #25964.

#11 @nacin
6 years ago

Syncing this single 33-line template is going to be really easy. But, I see a point in the future where the same PHP file can be used as a PHP template and, with minor transformations done automatically, a Backbone template. At you can see, the syntax is nearly the same. If bracket notation was used instead of object notation in this Backbone template, it'd be even closer. Some kind of template sharing is a bit of a wheel reinvention, but it avoids us unnecessarily diving into new templating languages for the moment. For now, [26726] works as a graceful fallback. Maybe a shared template could work for more things along these lines. Just something to think about.

We've used a few different techniques when an entire legacy interface becomes JavaScript. We've left existing HTML interfaces (media), declared the whole thing a value-add you only get with JavaScript (revisions), and provided baseline behavior in no-JS mode (themes). This baseline behavior is also how the rest of WordPress already handles no-JS, and it was the clear best choice here, with the least amount of code and pain.

Note: See TracTickets for help on using tickets.