PHPackages                             lexide/pro-forma - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. lexide/pro-forma

ActiveComposer-plugin[Templating &amp; Views](/categories/templating)

lexide/pro-forma
================

A library for managing and installing templated files for auto-generated code

1.1.0(1y ago)02.9k↓37.5%1MITPHPPHP &gt;=8.0

Since Sep 19Pushed 1y ago1 watchersCompare

[ Source](https://github.com/lexide/pro-forma)[ Packagist](https://packagist.org/packages/lexide/pro-forma)[ RSS](/packages/lexide-pro-forma/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (2)Dependencies (6)Versions (4)Used By (1)

Pro Forma
=========

[](#pro-forma)

This library allows other libraries to configure templates for auto-generated code, allowing for quick bootstrapping of projects, using a composer plugin.

Once the Pro Forma plugin is enabled, the templating process is seamless from an end-user perspective, so installing a library that is configured with Pro Forma templates will automatically generate those files if they don't already exist.

Project installation
--------------------

[](#project-installation)

To use Pro Forma in a project, enable the plugin in the `composer.json` file and allow PuzzleDI to use the library containing the code templates:

```
{
  "config": {
    "allow-plugins": {
      "lexide/pro-forma": true,
      "lexide/puzzle-di": true
    }
  },
  "extra": {
    "lexide/puzzle-di": {
      "whitelist": {
        "lexide/pro-forma": [
          "target/library"
        ]
      }
    }
  }
}
```

Running `install` or `update` Composer commands will invoke Pro Forma code generation. Composer may also ask if the Pro Forma plugin should be enabled, if it is not already.

It is recommended that the auto-generated files be added to version control, however this is not required.

> IMPORTANT! Only whitelisted libraries will have their templates generated. This includes any other libraries that whitelisted libraries have added to the whitelist trust chain. This is intended to prevent unintentional code generation when adding a new library to a project. If Pro Forma does not generate the expected files, it is advised to check that the library is correctly whitelisted.

Template Providers
------------------

[](#template-providers)

Pro Forma works by having libraries register template providers with it, using `lexide/puzzle-di`, then processing the template config provided by those classes to convert template files into generated code.

Pro Forma uses `lexide/puzzle-di` to collect a list of `TemplateProviderInterface` class names.

### Composer configuration

[](#composer-configuration)

Each library can register a single template provider, that implements the `Lexide\ProForm\Template\TemplateProviderInterface` interface, by adding the following configuration to the library's `composer.json` file:

```
{
  "extra": {
    "lexide/puzzle-di": {
      "files": {
        "lexide/pro-forma": {
          "class": "Fully\\Qualified\\Template\\Provider\\Class\\Name"
        }
      }
    }
  }
}
```

If this library uses dependencies that should also use Pro Forma to auto-generate code, those dependent libraries can be added to the whitelist chain for PuzzleDI in this library's `composer.json` file, much the same as when configuring a project:

```
{
  "extra": {
    "lexide/puzzle-di": {
      "whitelist": {
        "lexide/pro-forma": [
          "dependent/library"
        ]
      }
    }
  }
}
```

### Templates

[](#templates)

The purpose of a template provider is to return an array of instances of the `Lexide\ProForm\Template\Template` class. These instances need to contain all the information required to template the generated code.

In order to customise which templated files are returned, the providers are passed two config objects; a `Lexide\ProForm\Template\ProviderConfig\ProjectConfig` instance, which contains the project name, namespace and a list of installed packages, and a `Lexide\ProForm\Template\ProviderConfig\LibraryConfig` instance, which contains configuration for the current provider, taken from the project's `composer.json`. This allows the providers to make decisions such as adding a particular template if a package is installed or setting the value of a replacement based on project config options, for example.

The values contained in the `LibraryConfig` instance for a provider is defined only for its library and is configured as follows:

```
{
  "extra": {
    "lexide/pro-forma": {
      "config": {
        "target/library": {
          "foo": "bar"
        }
      }
    }
  }
}
```

In this example, the `LibraryConfig` instance would contain the value `bar` under the key `foo`.

```
$value = $libraryConfig->getValue("foo");    // value is set to 'bar'
```

### TemplateProvider Messages

[](#templateprovider-messages)

TemplateProviders have the ability to pass messages back to Pro Forma, in order to relay information to the user. This is useful when a provider has made a decision based on installed packages or config that ths user need to be informed about, such as skipping templates if a package is not installed or notifying about invalid configuration.

The TemplateProvider is responsible for implementing the `getMessages()` method, which should return an array of strings representing the messages that need to be displayed. If a provider doesn't supply any messages, an empty array should be returned.

### Template class

[](#template-class)

The template class, `Lexide\ProForma\Template\Template`, has four properties:

- name - the name of the template.
- templatePath - the path, relative to the *library root*, of the template file to process.
- outputPath - the path, relative to the *project root*, of the file to be generated.
- replacements - an array of key/value pairs to substitute into the template.

These properties can be set via setters on a manually created template instance, or via the factory method: `Lexide\ProForma\Template\TemplateFactory::create()`.

### Replacements

[](#replacements)

Template files can contain placeholder values that will be substituted when the output file is generated. The substitutions array is determined by the template providers and is custom per template. Pro Forma doesn't know beforehand which placeholder values exist for a template, it will blindly attempt to replace them based on the key that the provider supplies, therefore if placeholders are used, there must always be a replacement added to the template instance for each one.

Placeholder keys are wrapped in double curly braces, `{{ key }}`; spaces inside the braces are optional. When defining the replacements, only use the key name, no braces are required:

```
$template->setReplacements(["key" => "value"]);
```

> IMPORTANT! For consistency, replacement values must always be strings; any value that is not a string will be ignored, and a message will be outputted describing the value as invalid. This includes values that are "stringable" or that PHP would naturally convert to a string.

Regenerating files
------------------

[](#regenerating-files)

On occasion, it may be necessary to regenerate files if a library has had an update that changes a template's behaviour.

In order to do this, temporarily add the following value to the `lexide/pro-forma` section in `extra`:

```
{
  "extra": {
    "lexide/pro-forma": {
      "overwrite": true
    }
  }
}
```

Please note that Pro Forma will continue to overwrite files while this value is set to true; it is not intended to be used permanently, to avoid unexpected changes in behaviour after a composer update or install.

Also, this setting tells Pro Forma to overwrite *all* files, so any customisations that aren't in version control will be removed.

Finally, Pro Forma will *never* delete files; if a library is uninstalled, it's auto-generated code will need deleting manually.

###  Health Score

31

—

LowBetter than 68% of packages

Maintenance36

Infrequent updates — may be unmaintained

Popularity21

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 88.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~11 days

Total

2

Last Release

594d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/a01f73f5eea8a755e31d879b50f5862ee8a20e8d73daba1c15cb7e75e68796db?d=identicon)[downsider](/maintainers/downsider)

---

Top Contributors

[![Danny-Smart](https://avatars.githubusercontent.com/u/113538899?v=4)](https://github.com/Danny-Smart "Danny-Smart (24 commits)")[![downsider](https://avatars.githubusercontent.com/u/4508388?v=4)](https://github.com/downsider "downsider (3 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/lexide-pro-forma/health.svg)

```
[![Health](https://phpackages.com/badges/lexide-pro-forma/health.svg)](https://phpackages.com/packages/lexide-pro-forma)
```

###  Alternatives

[roots/acorn

Framework for Roots WordPress projects built with Laravel components.

9682.1M97](/packages/roots-acorn)[bkwld/laravel-pug

Pug view adapter for Laravel

15967.4k2](/packages/bkwld-laravel-pug)[nystudio107/craft-twigpack

Twigpack is a bridge between Twig and webpack, with manifest.json &amp; webpack-dev-server HMR support

97341.4k17](/packages/nystudio107-craft-twigpack)[mallardduck/blade-boxicons

A package to easily make use of Boxicons in your Laravel Blade views.

12776.5k9](/packages/mallardduck-blade-boxicons)[localgovdrupal/localgov_base

The base theme for LocalGov Drupal websites.

13121.5k4](/packages/localgovdrupal-localgov-base)[studiometa/ui

A set of opiniated, unstyled and accessible components.

1113.8k2](/packages/studiometa-ui)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
