Skip to content
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

Proposal for Modular WP Scaffold using Composer #104

Open
1 task done
dsawardekar opened this issue Apr 8, 2022 · 4 comments
Open
1 task done

Proposal for Modular WP Scaffold using Composer #104

dsawardekar opened this issue Apr 8, 2022 · 4 comments

Comments

@dsawardekar
Copy link

Is your enhancement related to a problem? Please describe.

Currently, WP Scaffold is used to bootstrap new projects at 10up. After the project is underway it can be useful to re-integrate updates to the scaffold. At the moment, such an update has to be done manually. Similarly it is difficult to pull bug fixes back into the project. Lastly, any new features that are added to the wp-scaffold are not readily available to projects started with an older version of wp-scaffold.

Designs

To address these issues I'm proposing a modular composer based approach outlined below.

1) wp-library composer package

The code inside the wp-scaffold would move to this wp-library repo. For MVP, This can be a GitHub repo with a composer.json. The wp-library would be imported into the wp-scaffold using configuration like this in the composer.json.

{
    "repositories": [
        {
            "url": "https://github.com/10up/wp-library",
            "type": "git"
        }
    ],
    "require": {
        "10up/wp-library": "~1.0.0"
    }
}

In the future we can publish a package to packagist to reduce this to a simpler require,

{
    "require": {
        "10up/wp-library": "~1.0.0"
    }
}

With this in place, projects using the wp-scaffold can upgrade to a newer 1.1.0 release by doing a composer update to that version of the wp-library.

{
    "require": {
        "10up/wp-library": "~1.1.0"
    }
}

2) Scaffold extends Theme

The wp-library would implement a Theme object that provides common functionality refactored from includes/core.php. In the wp-scaffold theme, we can extend the Theme in the wp-library.

class Theme extends \TenUp\Theme {

}

In a project with such a setup, The Theme class methods can be customized per the project requirements while retaining the parent wp-library functionality while still supporting upgrade paths.

class Theme extends \TenUp\Theme {

  public function js_detection() {
    parent::js_detection();

    // adds a has-notification class if the browser supports Web Notification API
    echo '<script type="javascript"> if (window.Notification ) { document.documentElement.className += 'has-notification'; } </script>'; 
  }

}

3) Theme Supports

Once we have a separate wp-library package we can let the wp-scaffolded projects determine what features should be enabled on the Theme using the add_theme_support api.

For instance, in the wp-library we could implement the above javascript detection behind a theme support condition like,

if ( get_theme_support( 'js_detection' ) ) {
  // do js detection here
}

And in the wp-scaffold theme, this can be managed with,

add_theme_support( 'js_detection' );

This approach combined with the composer.json versioning, allows us a lot of flexibility to add & improve features while maintaining backwards compatibility. For instance, if a new version of js_detection needs to be implemented in the same release it can be given a new theme support name.

After upgrading, projects can opt-in to the new release with something like,

add_theme_support( 'experimental_js_detection' );

4) Shared Features

By allowing projects to opt-in to the wp-library features we can introduce other shared features that are used across projects based on type, hosting provider etc.

Examples:

  • Fieldmanager based Site Settings
  • Newrelic profiling
  • Yoast SEO Tuning
  • Jetpack Tuning
  • ElasticPress Tuning

5) Scaffold extends Plugin

Similarly the wp-library can provide shared functionality to custom plugins while maintaining an upgrade path for bug fixes and improvements.

class Plugin extends \TenUp\Plugin {

}

Describe alternatives you've considered

This approach requires a composer install step to pull in the wp-library dependency. This is something that is typically incorporated into a build step in Gitlab CI, Circle CI, etc. This approach may not be suitable for projects that don't use Continuous Integration.

Code of Conduct

  • I agree to follow this project's Code of Conduct
@dsawardekar
Copy link
Author

Following up with examples from the previous meeting.

1) Fieldmanager Based Site Settings

We can standardize on Site Settings using the Fieldmanager plugin. The settings can have default fields like Social URLs which are used on most sites. And this feature would only be enabled if the theme declares support for site-settings. Another common pattern is to have Site Settings available as a Dropdown in the Admin Menu.

This can be extended to Headless projects by providing a site-settings endpoint that sends the saved Site Settings over REST.

2) New Relic Profiling

The New Relic theme support feature can be used to help identify common bottlenecks on projects. For example we could wrap New Relic around WP HTTP request calls using hooks like pre_http_request. By monitoring performance of such external APIs we can identify any resulting slow requests.

3) Yoast SEO Tuning

A theme support like yoast_seo_defaults can customize Yoast to match typical 10up defaults. This can include,

  • Remove from Admin Bar
  • Remove HTML comments
  • Remove Admin Notifications
  • Remove Dashboard Widget

4) ElasticPress Tuning

Different tiers of ElasticPress.io could have different profiles.

  • Site Search Personas based on type of site. The personas listed here could become presets behind a theme support like, elasticpress_news_persona_default.
  • Preset synonym dictionaries for different types of content.

The overall goal here is to provide good defaults that don't need to be re-implemented on every project. And at the same time keeping an upgrade path open for revisions and/or bug fixes.

@claytoncollie-dmv
Copy link

@dsawardekar I really like this idea and was thinking about it for my projects where I created invididual classes to 1) Disable XML RPC, 2) Clean up the wp_head, 3) Remove emojis 4) Clean up the dashboard widgets. Things that could be standardized, even written as small stand-alone plugins. I always go back and forth on whether to include this sort of stuff in the 10up-Experience plugin or within the theme or its own plugin.

As for your specific issue, I would also want to see these 4 use cases broken into their own repositories so that the theme can use composer to require them if necessary. That might save the extra step of using add_theme_support to toggle them off or on when bundled into a larger repo.

@dsawardekar
Copy link
Author

@claytoncollie-dmv Separating bigger features into separate packages/plugins is definitely something we can do once we have switched to a modular scaffold. The examples you have noted are perfectly in the Goldilocks zone as wp-library features!

RE: add_theme_support

The add_theme_support has an advantage over separate packages because it works at runtime. For example, a different part of the theme code or plugin can choose to turn off a feature on some requests. With separate packages, it is a build time decision whether to include a package in the composer.json.

@dainemawer
Copy link
Contributor

@dsawardekar this is a great proposal and makes a ton of sense to me. Would a setup like this be able to amend build tool configurations? Say eslint or babel ? Or even potentially output specific CSS partials depending on the configuration? With regards to Tailwind for instance we'd need to:

a) output a tailwind.config.js
b) install some extra npm packages
c) update CSS partials

I'd be interested to see just how flexibility composer could provide us here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants