Cakephp: RFC: Use .php extension by default for templates.

Created on 26 Feb 2018  ยท  51Comments  ยท  Source: cakephp/cakephp

Using .ctp extension for templates doesn't provide much value, just extra hassle to configure editors to recognize them as PHP files. Since all templates are nested under Template folder (and generally use underscored file names) they are easily recognizable as templates and don't need a special extension for distinguishing them from class files.

So I propose switching to .php extension for templates in 4.0.

RFC

Most helpful comment

If we move it outside of src, wouldn't the same logic apply to Locale folder and its po files etc?
I think that was a similar discussion and why or why not it should be part inside of src.

All 51 comments

I'd say we should keep .ctp but the load order would be .twig (in case we support that) > .php > .ctp and .ctp being dropped in 5.x.

Personally I would avoid implicit load order for .php and .ctp files. It would be unnecessary hassle figuring out the right file to load considering things like fallback to default templates when using themes and ability to override plugin templates in app. Even when upgrading from 3.x to 4.0, renaming .ctp files to .php would be simple enough or one can just set AppView::$_ext to .ctp until they are ready to rename.

Twig templates are a separate case altogether as they need a separate view class for rendering. Even if twig support is provided in core itself, it's use should be explicit opt-in or opt-in without any fallback / load order.

Hm... I am good with opting in things but I would not make things harder out of the box to omit flexible extension loading?

It can be very feasible to have .twig > .php loading - for instance in plugin-world you supply a .php file but end users can overwrite via say app/src/Template/Plugin/Foobar/batz/quux.twig, wouldn't it? It would also be great if there was an easy way to even chain file extensions and by that order pipe them through different processors (say .md.php or .md.twig - which would pipe through cakephp-view parser or through twig view parser and THEN through parsedown)?

Obviously the path priority would be stronger than the extension/parser priority.

And again, dropping support out of the box for .ctp will be a hassle for seamless upgrading. Why?
If you want to make a clean cut, maybe a ~bake~ bake (corrected) task that renames all .ctp files to .php would be useful?

As I said in the dev channel, this change could be a security hole accidentally. If you call class_exists('App\Template\Users\index'), composer will include index.php. If we want to do that, we would also have to move the Template directory to the root directory like config or bin.

Moving template files out of autoload path src does make sense.

config/
src/ (autoload)
templates/
tests/ (autoload-dev and autoload for fixture)
webroot/

sounds reasonable to me, too.

maybe a bake task that renames all .ctp files to .php would be useful?

No, @ionas , that has nothing to do with bake plugin. This is an upgrade tool task. But I agree that such a task is vital for this to be adopted and is a hard requirement for me in such a case.

Moving template files out of autoload path src does make sense.

some of templates is under plugins

well /plugins/PluginName/templates/*.php would also need to be read as well as /templates/PluginName/*.php, right?

Edit: Another way to circumvent this is dropping .ctp support in favour of .twig support alltogether in 5.0 and keeping .ctp in 4.0?

Lets not put theoretical 5.0 or 6.0 discussion in a small scoped issue. for 4.0.

I was off with the numbers (now corrected). What I mean is we can just keep .ctp and deprecated it in 4.x in favour of .twig?

some of templates is under plugins

Yes, so plugin templates would be under plugins/PluginName/templates instead of plugins/PluginName/src/Template.

I would prefer twig to be optional and plain php (*.php or *.ctp) to stay the default. I really don't get the obsession with people of template engines. The only reason for them is IMO if you have external template authors you can't trust. Or online editing of templates, just like Typo3 does with Typoscrip for scripting without exposing php. In any other case plain php is always faster and less overhead than a template engine, even with caching.

I would prefer twig to be optional and plain php (*.php or *.ctp) to stay the default.

Precisely why I would have liked some here to not widen the scope of the original issue. Everything beyond the extension type for the PHP templates itself is not something that needs discussing here - and only leads us away from the actual relevant discussion.

Removing .ctp means moving the template to root and people will need to upgrade by either setting _ext property or changing file names. Upgrade path either easy seems trivial to me.

The .ctp extension reminds of the zf .phtml which also have been there since its version one. I like the extension. It tells me here is a file that is not something you execute on its own like other .php files.

Iโ€™m indifferent to having ctp or php files for templates but I like the idea of moving them out of src.

I'd not move around templates for the sake of moving them around. Just upgrade hassle in 4.x.
For 5.x that's a different matter.

I still maintain 2.x apps where templates were in View folder. And I still sometimes scratch my head looking for templates in View folder after getting back to 3.x apps. I know it's in my head and just the matter of getting used to, but I think that maybe cleaner seperation of code and templates is a good thing.

@robertpustulka I had moved the templates under src/Template in 3.x to avoid the mix of templates and class files we have under View in 2.x :slightly_smiling_face:. IIIRC the justification for keeping them under src back then was templates are still PHP code. I agree that moving them out of src would be even better aesthetically and would avoid the potential security concern that @chinpei215 pointed out if .php extension was used.

My suggestion to rename .ctp to .php is based on feedback I have read from new / non cakephp users over the years, wondering why the special extension when the templates are just PHP code.

@ADmad that was a good decision back then. But for me having php classes and twig (or any other) template files in a same file structure feels a bit awkward now. So yes, this is aesthetics mostly.

Solving the template directory location can be done in a backwards compatible way. The paths used by an application are defined by App.paths.templates in Configure, so we can use the new convention for new applications and recommend people update their existing apps. Plugin paths could be shimmed for compatibility inside App::path() enabling both the old and new locations to be scanned.

@markstory Yup, as you described the path change can be done in a BC way. What do you think about the extension rename?

Extension rename could be backwards compatible if we had an opt-in way to switch the extension used and make that the default for new apps. I think only supporting .php is something we could do in 4.0.0 though. I think renaming files is a simple enough operation for folks to do as they upgrade.

If we move it outside of src, wouldn't the same logic apply to Locale folder and its po files etc?
I think that was a similar discussion and why or why not it should be part inside of src.

I think it would make sense to separate the templates and resources from the core application. The src/ directory should be reserved for PHP classes (the App namespace). Example:

.
โ”œโ”€โ”€ config                  # Configuration files
โ”œโ”€โ”€ docs                    # Documentation files
โ”œโ”€โ”€ public                  # Web server files (webroot)
โ”œโ”€โ”€ resources               # Other resource files
โ”‚   โ”œโ”€โ”€ assets              # Raw, un-compiled assets such as LESS, SASS
โ”‚   โ”œโ”€โ”€ locales             # Language files (translations)
โ”‚   โ”œโ”€โ”€ migrations          # Database migration files (Phinx)
โ”‚   โ””โ”€โ”€ seeds               # Data seeds
โ”œโ”€โ”€ src                     # PHP source code (The App namespace)
โ”œโ”€โ”€ templates               # Twig and PHP templates + JS and CSS
โ”œโ”€โ”€ tests                   # Automated tests
โ”œโ”€โ”€ tmp                     # Temporary files
โ”œโ”€โ”€ vendor                  # Reserved for composer
โ”œโ”€โ”€ composer.json           # Project dependencies
โ””โ”€โ”€ README.md               # The readme

Edit: Changed locale (singular) to locales (plural).

I like @odan proposal, this would also solve the issue where to place JS that is build using something like webpack by simply adding /resources/scss and /resources/js.

I wonder if templates shouldnt then just be inside resources, and locale might better be plural for consistency:

โ”œโ”€โ”€ resources               # Other resource files
โ”‚   โ”œโ”€โ”€ assets              # Raw, un-compiled assets such as LESS, SASS
โ”‚   โ”œโ”€โ”€ locales             # Language files (translations)
โ”‚   โ”œโ”€โ”€ migrations          # Database migration files (Phinx)
โ”‚   โ”œโ”€โ”€ seeds               # Data seeds
โ”‚   โ””โ”€โ”€ templates           # Twig and PHP templates + INLINE JS and CSS

Why the templates should live in /templates instead of /resources/templates (IMHO):

  • Centralizing your templates in /templates simplifies the work of your designers. That makes it easier to find the templates.
  • Referencing to a template is way shorter: /templates/Articles/index.ctp instead of /resources/templates/Articles/index.ctp
  • It's becoming more and more "standard" (in the PHP community) to put templates into the /templates directory.

@odan I disagree. If you have designers with daily amnesia then this might be a valid argument. Otherwise they'll remember where they are after the first time. Especially if everything else frontend related is in the resources folder as well. And almost every editor and IDE has autocomplete. So having to type and remember one word more is really a non-issue.

@dereuromark I would expect css and js to be inside assets not inside templates.

EDIT: are templates really resources? Resources feel like "additional stuff" or "just data" whereas without templates many applications (those that are not just webservice based) won't run and php/twig templates do include some kind of logic at least?

I would expect css and js to be inside assets not inside templates.

I am fairly certain that is the case when you carefully read the above context again surrounding it.
I just copied what was there, and this folder sure is just for templates (as the assets folder makes also clear). So no reason to worry here.

EDIT
What was meant is probably inline js/css, as such I edited the comment above for clarification.

I also think this should be done, unfortunately this will add significant overhead as we also need to test for older ctp files to keep BC

Keeping support for ctp files isn't necessary IMO. Renaming the files and moving them to /templates is not a big deal.

All it takes is 3 commands as I have shown in related PR.

https://github.com/cakephp/cakephp/pull/11931#discussion_r182517074

@Admad could we have https://github.com/cakephp/cakephp/pull/11931#discussion_r182517074 in the migration guide then? Does it work on osx and *nix? Is windows support (powershell) relevant?

could we have #11931 (comment) in the migration guide then?

When the PR is merged sure.

Does it work on osx and *nix?

Yes.

Is windows support (powershell) relevant?

Dunno. Surely someone will be able to come up with equivalent powershell commands if needed.

Probably a php executable would be better

Yeah, could easily be part of some migration/update script then :)

I'd like to offer my 2c here. The OP is correct in that .ctp by itself provides little immediate benefit over .php. The issues raised about autoloading etc. are valid, however, I disagree with the decision to move templates out of the src dir, since they are certainly part of an app's source code.

I propose a middle ground: index.___.php, similar to how Laravel does it index.blade.php.

It solves the above problems:

  • Can easily configure composer to ignore those
  • IDEs can be taught those are cake templates and treat them as such
  • They still are bonafide .php files
  • An app's files (all of them) reside in src dir, which is their logical home

The question is: what that middle section should be named, and I suggest cake, but am open to other ideas:
index.cake.php
view.cake.php

Another possibility reusing ctp:
index.ctp.php
view.ctp.php

@josephzidell Many files are part of an app. But src is for psr4 autoloader.

@josephzidell well but looking at it for 2 secs it looks like Laravel's blade is a stand alone templating language (probably allowing PHP, similar to markdown still allowing html code).

So the only thing that is in any way close is the bake template syntax so there the files could look like view.bake.php.

There could be other benefits though... to keep view.ctp.php - that would be VisualCode or Atom marking those files as cake templates and/or for editors to inject macros etc...?!

@dereuromark I think it's for both purposes.
@ionas Precisely. IDEs can allow following the path of an element, etc...

Personally, I really like the "ctp" file extension. File extensions are to some extend self explaining or at least self expressive. Even though template files are PHP files, they are a special kind of, with a very specific purpose. Also in the context of a CakePHP application they have special formatting rules.
For me, CTP files aren't just plain PHP files, thus they may have a dedicated file extension and should not be renamed to .php.
Certainly, I understand the argument this file extension can be a small learning hurdle for newbies (What is a .ctp file? Why does my editor not work with them correctly?) but this exact file extension can be a small learning help (CTP files are always template files in a CakePHP application).

Independently whether we change the file extension or not, I'm in favor of moving the templates.
For me, templates should be placed under /templates. /resources is not the correct place, as it is for "other stuff``, like a XSD file or may be a file to import which one wants to find easily when using a CLI command.
Refs: https://github.com/php-pds/skeleton/issues/12

And static web assets (compiled, generated & minified ones, not their base) should be placed under /webroot as usual (or /public for that matter).
Where "raw, un-compiled assets such as LESS, SASS" should go, is currently indifferent to me. /templates, /resources or even /assets have advantages and disadvantages.

I agree, locales could be moved to /locales.

If we really can introduce new template (and locale) folder locations in a BC way, we should do it in CakePHP 3.7 as a preparing bridge for CakePHP 4.0, where we onlly accept the new location.

I like @odan proposal too, but with a bit change

โ”œโ”€โ”€ webroot                 # Web server files (public)
โ”œโ”€โ”€ resources               # Other resource files
โ”‚   โ”œโ”€โ”€ assets              # Raw, un-compiled assets such as LESS, SASS
โ”‚   โ”œโ”€โ”€ locale              # Language files (translations)
โ”‚   โ”œโ”€โ”€ migrations          # Database migration files (Phinx)
โ”‚   โ””โ”€โ”€ seeds               # Data seeds
โ”œโ”€โ”€ src                     # PHP source code (The App namespace)
โ”œโ”€โ”€ templates 

@saeideng would you also keep bin and config as top level directories?

@markstory yes, I just wrote the changes

5 changes :

1) moving src/templates/ to /templates (root)
2) moving src/locale to /resources/locale
3) moving config/seeds to /resources/seeds
4) moving config/migrations to /resources/migrations
5) having /resources/assets (new/optional)

@markstory we should follow this and keep these two folders there.

https://github.com/php-pds/skeleton

I put all database-related things in a database/ folder

โ”œโ”€โ”€ database                # Database-related things
โ”‚   โ”œโ”€โ”€ factories           # Database factory files
โ”‚   โ”œโ”€โ”€ fixtures            # Database fixture files
โ”‚   โ”œโ”€โ”€ migrations          # Database migration files (Phinx)
โ”‚   โ””โ”€โ”€ seeds               # Data seeds
โ”œโ”€โ”€ resources               # Other resource files
โ”‚   โ”œโ”€โ”€ assets              # Raw, un-compiled assets such as LESS, SASS
โ”‚   โ”œโ”€โ”€ locale              # Language files (translations)
โ”œโ”€โ”€ src                     # PHP source code (The App namespace)
โ”œโ”€โ”€ templates
โ”œโ”€โ”€ webroot                 # Web server files (public)

Funny how my issue to change template extension got hijacked into conversation about changing the app's folder structure.

PR #11931 has already been opened to handle the file extension change (and folder move).

In general the following folder structure is a good balance between moving templates and resources out of autoload path and going overboard with changes.

|-- bin
|-- config
|-- resources
|   |-- assets
|   |-- locale
|   |-- migrations
|-- src
|-- templates
|-- webroot

I am closing this issue to stop the bike shedding :slightly_smiling_face:.

Funny how my issue to change template extension got hijacked into conversation about changing the app's folder structure.

Well, pulling it out of src is a requirement then with php file ext - to avoid autoloading/cs-sniff or other side effects to templates. And then there is not too much distance to a general discussion here.

@josephzidell Why is locale singular and not plural locales, if all others are plural?
Otherwise this seems to also be OK, to avoid config being overloaded with migration stuff.

@dereuromark That was a typo. I copied the example above and moved things around ๐Ÿ˜„

  • locales should be plural
  • I would like to see a clear folder split between test relevant directories (that may not require shipping in dist, but migrations and seeds do) and non-test.
Was this page helpful?
0 / 5 - 0 ratings

Related issues

GBeushausen picture GBeushausen  ยท  3Comments

dereuromark picture dereuromark  ยท  3Comments

josbeir picture josbeir  ยท  3Comments

saeideng picture saeideng  ยท  3Comments

burzum picture burzum  ยท  3Comments