Skip to content

UI Development Workflow

Lara Schenck edited this page Apr 23, 2020 · 5 revisions

This workflow will take some getting used to, but once you get the hang of it, you will find you are able to build UI quickly and safely.

Before you begin:

  1. Read through the Larva Glossary to familiarize yourself with the terminology used in this section.
  2. Review the available patterns in the Larva Server (npm run larva from the root of assets in this repo, navigate to localhost:3000) and find a similar looking module to reference, if possible.
  3. Open the Twig and Prototype JS tabs to get an idea of what the module is made of, and use the inspector to compare the module markup with the Prototype JS object.
  4. Make sure your module does not already exist. Look through existing modules to get an idea of how big they should be e.g. not an entire template, and not as small as a single piece of text. Refer back to the Glossary for drawing the distinction between module, object, and component.

Step 1: Build or Update UI in the Larva Server

All UI must be maintained in the Larva server. If you are creating a new module, these steps will help and can be followed. If you are updating an existing module, these steps will also help, and can also be followed, after number 3.

  1. Plan a name for the module. It will likely match the name used by Product, or will be close.
  2. If the command is available, use npm run scaffold -- module-name to scaffold the module files. If not available, create a new module in src/patterns/modules that consists of the following:
    • src/patterns/modules/module.twig - this will contain markup
    • src/patterns/modules/module.prototype.js - this will export the object containing classes and data
  3. In the module.prototype.js, import the existing pattern objects you plan to use e.g. c-heading, o-nav, or c-span. Refer to other modules' prototype JS files and the patterns source in the Larva side of the Larva UI menu.
  4. Write the Twig for the module, including existing patterns as needed with Twig {% include %} syntax
    • include a pattern from Larva with: {% include "@larva/components/c-tagline/c-tagline.twig" with c_tagline %}
    • include a pattern from the project with: {% include "@project/objects/o-profile-card/o-profile-card.twig" with o_profile_card %} where o-profile-card is an object created specifically for the project.
  5. Add any wrapping elements and CSS classes directly to the module Twig
  6. Add CSS classes to any XX_classes properties for existing patterns in the prototype JS file. Refer to other patterns, and use Find in Folder for examples.

Once you are finished developing the UI in the pattern library, it is almost time to integrate it into the WordPress theme. First, you must generate a screenshot test with:

npm run backstop -- test

If the new screenshots look correct, approve the tests with

npm run backstop -- approve

Commit the screenshot files.

Step 2: Integrating UI into PHP

  1. Run the following scripts to build the PHP and JSON defaults necessary to display the module on the theme
    1. npm run parser
    2. npm run write-json
    3. Check your git diff to make sure there are new files, module.php and module.prototype.json have been created. If there aren't, figure out why not.
  2. Create a PHP Controller file, or a template-part that matches the name of the module e.g. template-parts/article/module.php if it will be on the article template.
  3. Stub in the generated PHP file along with the defaults object from JSON:
// In template-parts/article/module.php

$module = PMC\Core\Inc\Larva::get_instance()->get_json( 'modules/module.prototype' );

\PMC::render_template(
	sprintf( '%s/template-parts/patterns/modules/module.php', untrailingslashit( CHILD_THEME_PATH ) ),
	$module,
	true
);
  1. If you are responsible for only front-end, then now it is time to hand off the development to the back-end developer. If you are working on both ends, continue.
  2. Gradually replace relevant parts of the $module object with real data. There should not be business logic in these controllers. Any business logic should be stored in a class, and the data provided by calling a single method. For example, the code above can be updated to:
// In template-parts/article/module.php

$module = PMC\Core\Inc\Larva::get_instance()->get_json( 'modules/module.prototype' );

$module_data = ArtNews\Article::get_module_data();

$module['c_heading']['c_heading_text'] = $module_data['title'];
$module['c_heading']['c_heading_url']  = $module_data['url'];

\PMC::render_template(
	sprintf( '%s/template-parts/patterns/modules/module.php', untrailingslashit( CHILD_THEME_PATH ) ),
	$module,
	true
);
  1. Like with the UI development, refer to existing template parts to find the solution to your problem.

Parsing Patterns from Larva

When there are changes to core Larva patterns in the npm package, you will need to parse them into the theme. Until this is part of the CLI, you must manually do this in larva.config.js. Uncomment relativeSrcOverride to point the parser to the @penskemediacorp/larva-patterns directory instead of the project:

	parser: {
		isCore: false,
		relativeSrcOverride: LARVA_PATTERNS_PATH
	}

Then run npm run parser to update patterns. If nothing updates, make sure you have updated the larva-patterns node_module, or are reading from an npm linked version of the larva-patterns package.

Important After you run the parser on larva-patterns, re-comment the relativeSrcOverride and run the parser again to make sure any project-level pattern overrides are applied.

Larva Server

The Larva server is where you will develop patterns. npm run larva will spin up the server.

To navigate to a pattern, follow this URL schema: http://localhost:3000/{larva|project}/{modules|components|objects}/{patternName}/{variant}

For example, to view the default Larva footer, go to: http://localhost:3000/larva/modules/footer

Assuming there is a project-level breadcrumbs, go to: http://localhost:3000/project/modules/breadcrumbs

And assuming there is a project-level featured article variation of breadcrumbs, go to: http://localhost:3000/project/modules/breadcrumbs/featured-article

To view only the tokens for AiA applied to a pattern, add the query string ?tokens=aia, for example: http://localhost:3000/project/modules/headline-only-featured-stories/?tokens=aia

BackstopJS Visual Regression Testing

  1. Checkout to master, and update the backstop property in larva.config.js with an array of project level modules you want to test. Copy that array to your clipboard - you will need it later.
  2. Make sure the Larva server is running with npm run larva.
  3. Generate the reference screenshots with npm run backstop -- reference.
  4. Checkout to your feature branch, and paste the array of modules copied from before into larva.config.js.
  5. Run the test with npm run backstop -- test, and a UI should open up with the test results.

See the Larva package README for further information.

Building Patterns With JS Prototypes

Each pattern must have a {patternName}.prototype.js file that exports a data object to be written to a JSON file. This provides defaults for when the pattern is rendered in the PHP templates.

You should make use of core Larva patterns wherever possible. For example, if you want to use o_nav from larva-patterns, you can import and then clone the object like so:

const clonedeep = require( 'lodash.clonedeep' );
const o_nav = clonedeep( require( '@penskemediacorp/larva-patterns/objects/o-nav/o-nav.prototype' ) );

o_nav.o_nav_classes += ' lrv-u-font-family-secondary';
o_nav.o_nav_title_text = 'New Title Text';

module.exports = {
	o_nav: o_nav
};

The above script overwrites the title text for o-nav and applies CSS for a new font family. Refer to existing patterns for guidance. While it is okay to change text in the JS files, make sure these any text values are overwritten with escaped and internationalized strings in the PHP controllers.

SVGs: Sprite, Icons, and Logos

Refer to this page for notes on using SVG in Larva themes.