I've been working on a side project for a while now (newup.io) - either by actually coding stuff or just thinking about things in the back of my mind. The point of the project is a generator for just about anything you could think of. One of the more interesting features of the generator is that it allows template authors to have file and directory names to be dynamically renamed.

For example, a template can have the following file in the template directory:

{ packageName[studly }ServiceProvider.php

Assuming the packageName was 'new-up', the final file name would be NewUpServiceProvider.php (because the studly filter would convert the new-up value). Filters can also be chained:

{ packageName[studly[upper }ServiceProvider.php

and the final result would be:

NEWUPServiceProvider.php

How this works

This works through a series of steps that all work together. The first step is discovery: gather all the files from the template. The second step is to parse all the file names and process them with any template variables. The third step is to copy the directory and file structure to the target directory with the new file names, while preserving the structure. The processing step is the most interesting, as the discovery and copying steps are fairly easy and straightforward.

The processing step looks at a file name ({ packageName[camel }.js, for example) and does some preliminary processing on the file or directory name. For example, it would look for all occurrences of the [[ sequence and replace it with some arbitrary string (I will just refer to this as ESCAPE_DOUBLE_OPEN_BRACKET). It will then replace each occurrence of [ with the pipe symbol |.

After all instances of the [ sequence has been replaced with the | character, all instances of ESCAPE_DOUBLE_OPEN_BRACKET will then be replaced with a single instance of the opening square bracket character [.

After this step, the file name is then ran through a compiler/render (which internally makes use of the fantastic Twig library). After the compiler has completed it's job, all that is left is the final file/directory name.

More file and directory name magic

I've already shown that filters can be chained, just like when using filters in any other Twig template. The syntax for directory and file names even allows filter parameters. We can name a file like so:

{ "this is a new blog post"|slug('-') }.md

and the final output would be:

this-is-a-new-blog-post.md

Additionally, multiple template variable tags can appear in file names:

{ "this is a test" } non template text { "{" }

which would output

this is a test non template text {

Limitations of File Systems

The arbitrary choice of syntax (the [ character for separating filters, for example) is because of the various limitations of different file systems. The | character is allowed in some fashion on UNIX and Linux systems, but Windows systems will complain since the code will be running in User Mode. Because the utility should run the majority of systems developers use, some decisions about syntax have been made considering the "lowest common denominator", which for now is Windows User Mode NTFS.

Additionally, because of the limitations in file name length, and full path length, another system for naming template files is currently in the planning stages. This will most likely be giving the files and directories normal names, and then looking up a template syntax in some YAML configuration file based on the file name.

Conclusion

Have any thoughts or comments on this? I'd love to hear them. Just leave a comment below. If you would like to browse the source code relevant to this article it's on GitHub.