Richard A Quadling
Richard A Quadling

Reputation: 4008

How do I get make to automatically react to additional templates for the same source data?

I have a data file data.json, a script that will process the data file render, and 3 template files accounts.template, locals.template, and header.template.

The targets are called accounts and locals and relate to the expansion of the appropriate template with the data held in data.json. Nothing particularly complicated.

The targets and the data.json are in the root directory for the project. The render script is in ./scripts. The templates are in ./scripts/templates.

Currently my Makefile looks like this ...

render: data.json scripts/render locals accounts
    @echo Completed

locals: data.json scripts/render scripts/templates/locals.template scripts/templates/header.template
    @echo "Building locals"
    @echo "------------------"
    @php scripts/render locals
    @echo ""

accounts: data.json scripts/render scripts/templates/accounts.template scripts/templates/header.template
    @echo "Building accounts"
    @echo "--------------------"
    @php scripts/render accounts
    @echo ""

This is not really expandable. I've got another 20 or so different templates to generate from the data.json file (the data COULD be split into 1 json file per template, if required).

Is there a more intelligent and ideally auto-expanding way for this to be achieved?

Basically, if I have a template that is NOT called header (header is just an "DO NOT EDIT" banner for the generated content - moving it to scripts/templates/common would be sensible here I think), then run the render script with the template name as an argument (without the '.template' part).

Is this doable?

Also, is there any way to invalidate the targets if they have been edited (they shouldn't have been as there IS a great big banner) so to force a rebuild if make is ran again?

EDIT: Updated Makefile based upon the comments below.

TEMPLATES := $(patsubst scripts/templates/%.template.php,%.tf,$(wildcard scripts/templates/*.template.php))

render: $(TEMPLATES)
    @echo Completed

%.tf: scripts/templates/%.template.php scripts/templates/common/header.template.php locals.json scripts/render.php
    @php scripts/render.php $(subst .tf,,$@)

Upvotes: 0

Views: 32

Answers (1)

MadScientist
MadScientist

Reputation: 100956

This is a straightforward application of pattern rules:

TEMPLATES := $(filter-out header,$(patsubst scripts/templates/%.template,%,$(wildcard scripts/templates/*.template)))

render: $(TEMPLATES)
          @echo Completed

%: scripts/templates/%.template scripts/templates/header.template data.json scripts/render  
        @echo "Building $@"
        @echo "------------------"
        @php scripts/render $@
        @echo ""

As for someone editing the targets, there's no good way to do that because make works solely on modification times. There's no way to know that a target is modified because there's nothing to compare it to that will tell you that, and even if you did add a temporary file to detect that, make wouldn't do anything because the target would be newer than the temporary file so make would consider it up to date.

Upvotes: 1

Related Questions