studiopress / genesis-sample

This is the sample theme created for the Genesis Framework.
https://demo.studiopress.com/genesis-sample/
534 stars 280 forks source link

Automatic updates without losing customizations #252

Open seothemes opened 5 years ago

seothemes commented 5 years ago

Just wanted to start a conversation about the possibility of having automatic updates in child themes.

In the past this has been a bad idea because people like to place custom snippets in their child themes and there is no way to avoid overwriting them, but I think I've found a solution.

The idea is to place all of the child themes code in a non-editable folder. During an automatic update, this is the only folder that is changed, all other files outside of this folder are not touched.

For additional safety, a full backup is made of the original child theme version before running the update, just in case.

I've recreated Genesis Sample with this functionality built in. If anyone wants to test it out the project is available here. See the readme for full details.

So far I haven't found any downsides but I would like to hear others thoughts.

nikcree commented 5 years ago

Great idea! Currently I use the sample theme and have added a 'custom' directory containing our theme specific functions, stylesheet, js, etc. I have added 1 line the the sample theme functions.php to call the custom directory, but this does mean when updating the theme for clients we need to add the line back again. This idea to have update-able child themes has my support.

damiencarbery commented 5 years ago

I like this idea. I always use a custom functionality plugin so I don't have to edit the child theme at all.

jscmal commented 5 years ago

Great idea! Currently I use the sample theme and have added a 'custom' directory containing our theme specific functions, stylesheet, js, etc. I have added 1 line the the sample theme functions.php to call the custom directory, but this does mean when updating the theme for clients we need to add the line back again. This idea to have update-able child themes has my support.

I do the same thing for my websites. Indeed, I have Zero problems with my updates. This works marvelously without changing the sample theme code.

The customizations for all my personal websites are in a directory of the server that is linked in the sample them and 1 line added to the sample theme functions.php, to take my custom code from that linked directory. Of course, if I move the sample theme from a directory to another one, the link to the directory with my custom code remains.

nickcernis commented 5 years ago

The StudioPress team have discussed automatic updates for child themes, but so far we haven't found a guaranteed safe way to implement this that doesn't potentially jeopardise live sites upon update.

Speaking only for myself from here on, albeit informed by discussions I've had with other StudioPress team members.

I like @seothemes' test project. Thank you for putting it together and starting this discussion. I can see it could work for minor theme customisations and minor updates, and the auto-backup mechanism is a nice touch to give people a way back out. I think this is the best implementation of child theme updates I've seen so far.

But some general issues still remain, and I hope you won't take offence at the long list here. This is not specific to your implementation; I'm just sharing considerations we've run up against when discussing child theme updates in general:

Challenges with self-updating child themes

  1. People will edit files in the 'private' folder, even if you exclude it from the WP Editor and rename that folder to 'please dont touch stuff in here or the gates of hell shall open and spew forth horrible things', then add a similar message to the headers of your files and your theme documentation.
  2. Segregating custom PHP code and developer PHP code does not guarantee that updates to developer code will not conflict with custom PHP users have added. The promise that code will not be overwritten is worth something, but it's only half of the story.
  3. Similarly, you cannot guarantee that CSS you introduce in an update will not negatively affect customisations that site owners have made just because their CSS lives in a different file that you've promised not to touch. This is particularly true for large aesthetic changes such as those between a theme's 1.0 and 2.0 release.
  4. If customers do want to override content in the 'do not touch' folder, they now have the increased burden of having to figure out how to undo or modify what you did without touching the code you've told them they can't edit. (This also potentially renders many snippets and tutorials invalid, as the 'private' code in a theme is no longer openly visible and editable, so advice like “just go into functions.php and make these changes to the site header array to change your header size” won't work any more.)
  5. Customers need a better option to preview a child theme update as part of the upgrade process. At present they either have to take a leap of faith and trust that an update will work, use hosting that offers a staging area, or set up a local development environment. My experience of working in support suggests that site owners are still inclined to take the cross-your-fingers option, press the update button in production, and then come banging on the doors if the update goes badly.
  6. Because an automatic update system moves responsibility for updates from the customer to the developer, there is potential for the support burden to increase when updates cause styling or functional conflicts. (“Your update broke my site and I'm losing thousands a day.”)
  7. There is currently no update mechanism in place to upgrade block content, such as content installed on a homepage during one-click theme setup. Once you ship your theme and customers use your block-based content and start modifying it, you're prevented from updating or restyling the homepage again without also considering backwards-compatibility for every homepage variation you've ever shipped.
  8. If the theme backup process fails during update, who is responsible for the missing files? Offering a backup process is great, but the side-effects are that it encourages people to skip that step themselves, and it shifts responsibility for site integrity into developers' hands when before it was more clearly in the hands of site owners.
  9. It's worth considering the people who will be customising themes. Will the idea of a theme that periodically loads new and unknown code around their own customisations be a delight to them, or will it be a new vector for worry, panicked calls from clients who saw an update was available but it broke their site, and potential unpaid maintenance?
  10. Theme developers each have to find a way to host, secure, and maintain an update system unless a central private store of some kind is offered.

It's easy to say in response to many of the above points, “well, site owners can just revert to their theme backup if something goes wrong”. But then what? The customer probably still wants the theme updates they paid for. Support teams and developers must figure out why the update went wrong and offer a way forward that does not undo any customisations the site owner wants. This drifts from the realm of support to site customisation.

I don't mean to be entirely dismissive of auto updates. I recognise that they would help theme developers in some ways, and it feels like a potential improvement on the current suggestions for customers to “just diff your current theme version with the new version and re-apply any customisations manually”.

But we need to consider that people will be updating the live sites for their customers and own businesses and expecting it to just work, the same way WP core and plugin updates are supposed to.

We need to be careful not to further erode trust in the WordPress update system by claiming to be able to automatically update a codebase consistently that could be in a wide variety of unknown states. The update systems for plugins, for Genesis, and for WordPress core all assume a known state. And those updates still break sites from time to time.

Having spent some time with this problem, it seems possible to me that any system for self-updating child themes that could contain user edits cannot claim with an acceptable level of confidence to update your site without breaking it.

So what instead?

Alternatives

We have a few other options:

  1. We can offer child theme updates anyway, but with some big warnings first such as “take a backup and test first” (as WordPress core does), or “don't update your production site, please test in staging first”. But people will invariably update anyway, and really all such notices do is to make people feel more guilty when it goes wrong. Adding a notice doesn't actively absolve us of coming up with a solution that won't break people's sites. (And also, nobody reads them.)

  2. We could apply updates only if no single file has changed. (By shipping themes with a manifest containing a hash of every file, then checking all hashes match and no new files exist prior to update.) But how many live sites use themes where no changes were made at all? It seems likely that this would be a lot of work for little benefit to customers.

I think there's potentially a better option than both of these, and it's one that I can't take credit for — it emerged from discussions with the StudioPress team:

Let's work together to reduce the amount of code in child themes that requires an update in the first place

Themes have too much common logic and styling in them at present. They are supposed to be simple styling layers, but they're an increasingly large mess of logic, heavy CSS and JS.

As a community, we can work to undo some of the complexity that is common to all child themes. Work has already begun in the upcoming Genesis 3.0 (which introduces a new menu component hosted by the framework).

But we can continue this in two ways:

  1. Identify common theme functionality that would benefit more developers by moving to Genesis. When every theme you write starts to use similar boilerplate for missing functionality, that's a sign it could potentially be moved up to the framework from the theme. We can't hope to add every feature to Genesis, but we can help to make it more useful if every theme needs certain functionality that Genesis lacks.

  2. Identify functionality that doesn't belong in Genesis, but would work as a plugin. It's possible lesser-used functionality would be better moved from a child theme to feature plugins.

The advantage of both approaches are that:

The disadvantages are that Genesis potentially grows in complexity if we don't govern it carefully, and that theme developers still don't have a mechanism for automatically updating child theme CSS and PHP. However, given the choice of (a) reducing theme complexity while ensuring better stability at the cost of automatic child theme updates or (b) offering minor design and feature updates at the cost of potentially remotely wiping out sites en-masse, I'd opt for the former.

The direction StudioPress takes with child theme updates isn't set in stone yet, though. It also needn't affect community child theme developers, of course. Please feel free to continue to experiment with these ideas — I'm really interested in tracking them and seeing the results.

seothemes commented 5 years ago

@nickcernis Wow, thank you for taking the time to write all of that. Some great points there.

Not saying that this approach is the only way to go but I would like to attempt to address some of the points above:

Challenges

People will edit files in the 'private' folder, even if you exclude it from the WP Editor and rename that folder to 'please don't touch stuff in here or the gates of hell shall open and spew forth horrible things', then add a similar message to the headers of your files and your theme documentation.

This is true, but that can also happen with Genesis itself. There is nothing stopping people from editing Genesis core files or even plugin files. If they do that, they are aware of the risk.

Segregating custom PHP code and developer PHP code does not guarantee that updates to developer code will not conflict with custom PHP users have added. The promise that code will not be overwritten is worth something, but it's only half of the story. Similarly, you cannot guarantee that CSS you introduce in an update will not negatively affect customisations that site owners have made just because their CSS lives in a different file that you've promised not to touch.

This is a general backwards compatibility issue. Child themes would need to make backwards-compatible changes like any other theme or plugin. This issue also occurs with manual updates and "engine plugins" unless the developer enures backwards compatibility.

If customers do want to override content in the 'do not touch' folder, they now have the increased burden of having to figure out how to undo or modify what you did without touching the code you've told them they can't edit.

Users cannot edit Genesis directly but can customize everything with hooks. Child themes should be built the same. Even without automatic updates, I don't tell users to edit the child theme. Instead, customizations should be placed in a custom functionality plugin.

Customers need a better option to preview a child theme update as part of the upgrade process.

The automatic backup feature allows this. If the update breaks anything they can simply rollback to the last version. For an advanced preview they could use something like Staging Pilot.

Because an automatic update system moves responsibility for updates from the customer to the developer, there is potential for the support burden to increase when updates cause styling or functional conflicts.

I'd say this is better than the current situation. I'd rather push an update to fix 1000+ sites than have to answer 1000+ support tickets for the same issue. In my opinion, the support burden is always going to be decreased by having automatic updates.

There is currently no update mechanism in place to upgrade block content, such as content installed on a homepage during one-click theme setup.

This is probably a good thing. Content is separate to code and should never be updated. That being said, they could always run the demo import again to create a new home page with the updated content.

If the theme backup process fails during update, who is responsible for the missing files? Offering a backup process is great, but the side-effects are that it encourages people to skip that step themselves, and it shifts responsibility for site integrity into developers' hands when before it was more clearly in the hands of site owners.

Agreed, I think there should be a popup notice before proceeding with the update telling the user to create a full site backup before running the update. Like WP Engine hosted sites currently do.

In the example project I created, the update will not run if the backup is not successful. With some more testing I could almost guarantee that this is safe.

Theme developers each have to find a way to host, secure, and maintain an update system unless a central private store of some kind is offered.

There are plenty of existing solutions - EDD, Freemius, Plugin Update Checker. I'm sure most third party developers would be more than happy to do this considering the benefits that automatic updates would bring. StudioPress could just use something similar to what they already have with Genesis.

Alternatives

We can offer child theme updates anyway, but with some big warnings first.

There is always a risk when updating themes and plugins, child themes are no different. It's actually safer than updating the latter because of the built in backups. If the backup fails, then the update is stopped.

We could apply updates only if no single file has changed.

This is a possibility, checking that the updatable directory has not been modified. Will look into this.

Let's work together to reduce the amount of code in child themes that requires an update in the first place

This is great in theory but it will never work. There are always going to be bugs and new features in child themes. Until Gutenberg replaces the need for theme frameworks like Genesis, child themes will always need more complexity than Genesis can provide. Relying only on what Genesis provides is really limiting to developers and means we can't give users the features they want.

By the time Genesis could provide this amount of functionality, it would be almost obsolete because of blocks/Gutenberg. Themes will probably be reduced to a single stylesheet in the near future.

The real problem with this is solution is that child theme CSS can't be provided by Genesis. This is the main thing that requires updating.

Other options

The only other real option is to use an engine plugin. Below are the downsides to using engine plugins vs auto-updates. These are the things that have stopped me using engine plugins in the past. Please note that this is my opinion only:

Ask the community

I think it would be a cool idea to ask the community what they think in a survey. It would need a quick video demonstrating each of the options. It could be something simple like this:

Should Genesis child themes introduce automatic updates. If so, what is the best approach?

If enough people were on board with the idea, then it might be worth looking into.

jb510 commented 5 years ago

This is a great convo, thank you all. @seothemes wrote:

The real problem with this is solution is that child theme CSS can't be provided by Genesis. This is the main thing that requires updating.

I want to add a caveat to that statement as updating CSS is generally not our problem. Customers don't need CSS updates. However, updating custom WooCommerce templates is a massive problem and customers DO need those. Other templates for other plugins too, but mostly WooCommerce.

That is why we need customers to be able to update their child themes more than any other reason, every month it seems Woo releases a templates change and throws "Your templates could be incompatible!!!!!".

Those sorts of thing is never going to make it's way into Genesis core.

As others have said (and Mai to their credit have done) there is the option of moving that code into a plugin. We considered that, and need to again with G3 not being turned into a plugin. However, if the engineering effort to turn G3 into a plugin is too much, it's WAY too much to ask that every single child themes do it instead.

seothemes commented 5 years ago

@jb510 Good point about plugin templates. That is another big one. I noted CSS as the main reason due to all of the changes with Gutenberg, most themes needed an overhaul to include block styling. But I agree, in some cases it would be templates or logic that require the most updates.

Since it has been confirmed that Genesis won't become a plugin, there are only 2 possible ways (that I can think of) to provide automatic updates going forward:

We should discuss on the pros and cons of each and try to reach an agreement for the best possible solution. So far, the solution from StudioPress/WP Engine is to reduce the amount of code in child themes which is a good long-term goal but it doesn't really solve the problem.