2017 © Pedro Pelรกez
 

library wordpress-suv

A scaffold for implementing the SUV architecture

image

grottopress/wordpress-suv

A scaffold for implementing the SUV architecture

  • Monday, June 18, 2018
  • by akadusei
  • Repository
  • 1 Watchers
  • 1 Stars
  • 110 Installations
  • PHP
  • 1 Dependents
  • 0 Suggesters
  • 0 Forks
  • 0 Open issues
  • 13 Versions
  • 17 % Grown

The README.md

WordPress SUV

SUV is our own architecture for building WordPress themes and plugins at GrottoPress. This package is a scaffold for implementing SUV., (*1)

SUV is short for Setups-Utilities-Views. It emphasises an object oriented approach to writing WordPress plugins and themes, and provides for a cleaner, more organised code base., (*2)

SUV employs object composition extensively, and makes full use of the express power of core WordPress' event-driven architecture., (*3)

Setups: Includes all objects with methods that interact directly with WordPress, usually by means of action and filter hooks., (*4)

Utilities: Utilities are objects with methods that are needed by setups and views to accomplish their goals., (*5)

Views: Views are templates and partials to be loaded by the theme/plugin or WordPress., (*6)

Requirements

Code style

Code should comply with PSR-1, PSR-2 and PSR-4, at least., (*7)

You are strongly encouraged to use strict typing in PHP 7, and specify types for function/method arguments and return values., (*8)

As much as possible:, (*9)

  • Aim for immutable objects
  • Prefer declarative syntax
  • Don't inherit concrete classes
  • Avoid static methods
  • Do away with fancy design patterns

Usage

Note: From here on, app refers to your theme or plugin., (*10)

Directory Structure

Set up your own app's directory structure as follows:, (*11)

.
โ”œโ”€โ”€ app/
โ”‚   โ”œโ”€โ”€ MyApp/
โ”‚   โ”‚   โ”œโ”€โ”€ Setups/
โ”‚   โ”‚   โ”œโ”€โ”€ Utilities/
โ”‚   โ”‚   โ””โ”€โ”€ Utilities.php
โ”‚   โ”œโ”€โ”€ helpers.php
โ”‚   โ””โ”€โ”€ MyApp.php
โ”œโ”€โ”€ assets/
โ”‚   โ”œโ”€โ”€ css/
โ”‚   โ””โ”€โ”€ js/
โ”œโ”€โ”€ dist/
โ”‚   โ”œโ”€โ”€ css/
โ”‚   โ””โ”€โ”€ js/
โ”œโ”€โ”€ lang/
โ”œโ”€โ”€ node_modules/
โ”œโ”€โ”€ partials/
โ”œโ”€โ”€ templates/
โ”œโ”€โ”€ tests/
โ”œโ”€โ”€ vendor/
โ”œโ”€โ”€ .editorconfig
โ”œโ”€โ”€ .gitignore
โ”œโ”€โ”€ CHANGELOG.md
โ”œโ”€โ”€ codeception.yml
โ”œโ”€โ”€ composer.json
โ”œโ”€โ”€ composer.lock
โ”œโ”€โ”€ <app-bootsrap>.php (functions.php or my-plugin.php)
โ”œโ”€โ”€ LICENSE
โ”œโ”€โ”€ package.json
โ”œโ”€โ”€ package-lock.json
โ”œโ”€โ”€ postcss.config.js
โ”œโ”€โ”€ README.md
โ”œโ”€โ”€ tailwind.config.js
โ”œโ”€โ”€ tsconfig.json
โ””โ”€โ”€ webpack.mix.js

Not all directories/files may apply in your case. Remove whichever you do not need, and add whatever you require as necessary. Just keep the general concept in mind., (*12)

Autoloading

Your composer.json autoload config:, (*13)

{


  "autoload": {
    "psr-4": {
      "Vendor\\": "app/"
    },
    "files": [
      "app/helpers.php"
    ]
  }


}

Require SUV

From the root of your app, run:, (*14)

composer require grottopress/wordpress-suv

Sample WordPress plugin

Let's write a sample WordPress plugin using SUV, shall we?, (*15)

// @ wp-content/plugins/my-plugin/app/MyPlugin.php

<?php
declare (strict_types = 1);

namespace Vendor;

use Vendor\MyPlugin\Setups;
use Vendor\MyPlugin\Utilities;
use GrottoPress\WordPress\SUV\AbstractPlugin;

final class MyPlugin extends AbstractPlugin
{
    /**
     * @var Utilities
     */
    private $utilities;

    protected function __construct()
    {
        $this->setups['Footer'] = new Setups\Footer($this);
        // ...
    }

    protected function getUtilities(): Utilities
    {
        return $this->utilities = $this->utilities ?: new Utilities($this);
    }
}
// @ wp-content/plugins/my-plugin/app/MyPlugin/Setups/Footer.php

<?php
declare (strict_types = 1);

namespace Vendor\MyPlugin\Setups;

use GrottoPress\WordPress\SUV\Setups\AbstractSetup;

final class Footer extends AbstractSetup
{
    public function run()
    {
        \add_action('wp_footer', [$this, 'renderText']);
    }

    /**
     * @action wp_footer
     */
    public function renderText()
    {
        echo '<div class="useless-text">'.
            $this->app->utilities->text->render().
        '</div>';
    }
}

You may file utility classes in app/MyPlugin/Utilities/. Utility classes do not interact directly with WordPress, but contain functionality that setup classes and views can use to accomplish their goal., (*16)

// @ wp-content/plugins/my-plugin/app/MyPlugin/Utilities.php

<?php
declare (strict_types = 1);

namespace Vendor\MyPlugin;

use Vendor\MyPlugin;
use GrottoPress\Getter\GetterTrait;

class Utilities
{
    use GetterTrait;

    /**
     * @var MyPlugin
     */
    private $app;

    /**
     * @var Utilities\Text
     */
    private $text;

    public function __construct(MyPlugin $plugin)
    {
        $this->app = $plugin;
    }

    private function getApp(): MyPlugin
    {
        return $this->app;
    }

    private function getText(): Utilities\Text
    {
        return $this->text = $this->text ?: new Utilities\Text($this);
    }
}
// @ wp-content/plugins/my-plugin/app/MyPlugin/Utilities/Text.php

<?php
declare (strict_types = 1);

namespace Vendor\MyPlugin\Utilities;

use Vendor\MyPlugin\Utilities;
use GrottoPress\Getter\GetterTrait;

class Text
{
    use GetterTrait;

    /**
     * @var Utilities
     */
    private $utilities;

    public function __construct(Utilities $utilities)
    {
        $this->utilities = $utilities;
    }

    /**
     * This is obviously a very trivial example. We could
     * have just printed this directly in the footer setup's
     * `renderText()` method.
     *
     * It is done here only for the purpose of demonstration,
     * if you know what I mean.
     */
    public function render(): string
    {
        return \esc_html__('Useless text', 'my-plugin');
    }
}

Since our plugin extends SUV's AbstractPlugin, it is essentially a singleton. The entire plugin (with all objects) can be retrieved with a call to Vendor\MyPlugin\MyPlugin::getInstance(), (*17)

Let's create a helper to do this in app/helpers.php., (*18)

// @ wp-content/plugins/my-plugin/app/helpers.php

<?php
declare (strict_types = 1);

use Vendor\MyPlugin;

function MyPlugin(): MyPlugin
{
    return MyPlugin::getInstance();
}

Other plugins and themes now have access to the singleton plugin instance, and can remove an action in our plugin thus:, (*19)

\add_action('init', function () {
    \remove_action('wp_footer', [\MyPlugin()->setups['Footer'], 'renderText']);
});

Now, to conclude with our plugin's bootstrap:, (*20)

// @ wp-content/plugins/my-plugin/my-plugin.php

<?php
/**
 * @wordpress-plugin
 * Plugin Name: My Plugin
 * Plugin URI: https://www.grottopress.com
 * Description: My awesome plugin
 * Version: 0.1.0
 * Author: GrottoPress
 * Author URI: https://www.grottopress.com
 * License: MIT
 * License URI: https://opensource.org/licenses/MIT
 * Text Domain: my-plugin
 * Domain Path: /languages
 */
declare (strict_types = 1);

require __DIR__.'/vendor/autoload.php';

/**
 * Run plugin
 */
\add_action('plugins_loaded', function () {
    \MyPlugin()->run();
}, 0);

Building a plugin?

We created a WordPress plugin scaffold that uses SUV. It sets up the most common stuff for you to dive straight into code., (*21)

You should check it out ยป, (*22)

Building a theme?

If you're looking to build a theme using SUV, you should check out Jentil., (*23)

Jentil is a framework for rapid WordPress theme development, built using the SUV architecture., (*24)

It comes with numerous features, and includes a loader that loads templates (eg: page.php, index.php, single.php etc) only from the app/templates directory, and partials (eg: header.php, footer.php, sidebar.php) from the app/partials directory., (*25)

Check it out ยป, (*26)

Development

Run tests with composer run test., (*27)

Contributing

  1. Fork it
  2. Switch to the master branch: git checkout master
  3. Create your feature branch: git checkout -b my-new-feature
  4. Make your changes, updating changelog and documentation as appropriate.
  5. Commit your changes: git commit
  6. Push to the branch: git push origin my-new-feature
  7. Submit a new Pull Request against the GrottoPress:master branch.

The Versions

18/06 2018

dev-master

9999999-dev

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

18/06 2018

dev-dev

dev-dev

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

18/06 2018

0.4.3

0.4.3.0

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

13/04 2018

0.4.2

0.4.2.0

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

14/03 2018

0.4.1

0.4.1.0

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

05/03 2018

0.4.0

0.4.0.0

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

01/03 2018

0.3.1

0.3.1.0

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

28/02 2018

0.3.0

0.3.0.0

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

04/02 2018

0.2.3

0.2.3.0

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

25/01 2018

0.2.2

0.2.2.0

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

25/01 2018

0.2.1

0.2.1.0

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

09/01 2018

0.2.0

0.2.0.0

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv

07/01 2018

0.1.0

0.1.0.0

A scaffold for implementing the SUV architecture

  Sources   Download

MIT

The Requires

 

wordpress suv