Get at name of current template?

115 views
Skip to first unread message

Juergen Nickelsen

unread,
May 13, 2015, 1:18:42 PM5/13/15
to mojol...@googlegroups.com
Hello all,

for a while I have been trying to get at the name of the template that
is just being rendered, to use it in the layout. I have dug through
documentation and source code, and while I found the place where the
debug message qq{Rendering template "$name"} is emitted, I haven't yet
found a good way to get at that name.

Now I did this (as a helper function):

sub current_template_name {
my ($c) = @_;
my $loghist = $c->app()->log()->{history};
my $try = -1;
my $msg;
do {
$msg = $loghist->[$try--]->[2];;
} while ($msg =~ m{\"layouts/} && -$try < @{$loghist});
$msg =~ s/^[^"]*"(.*)".*/$1/;
return $msg;
}

I am pretty certain everybody agrees that this is as ugly as it can get.
Now, what is the preferred way to get at the template name?


(BTW, I *really* like Mojolicious. While I am an experienced programmer,
this is my first real endeavor into web applications, so I was a bit
overwhelmed at first. An excellent training by Renée Bäcker put me on
the right track, and now I am happily hacking away.)

Regards, Juergen.

--
<Juergen....@fu-berlin.de> Tel +49.30.838-50740 Fax -450740
Zentraleinrichtung fuer Datenverarbeitung, Central Systems (Unix)
Freie Universitaet Berlin, Fabeckstrasse 32, 14195 Berlin, DE

Justin Hawkins

unread,
May 13, 2015, 10:11:23 PM5/13/15
to mojol...@googlegroups.com

On 14 May 2015, at 2:48 am, Juergen Nickelsen <nick...@zedat.fu-berlin.de> wrote:

for a while I have been trying to get at the name of the template that
is just being rendered, to use it in the layout.

I can’t answer your question directly, but this requirement sounds like a bit of a code smell. What are you trying to accomplish?

You should probably be setting something in the stash to drive logic required for presentation in the layout, not depending on what template is being rendered.

For example (untested):

sub some_controller_method {
  my $self = shift;
  $self->stash( has_login_box => 1 );
  $self->render(template => ‘foo’);
}

then in the layout:

% if (stash(‘has_login_box’)) {
<div id=“login-box”>
...
</div>
% }

or better:

% if (stash(‘has_login_box’)) {
%   include ‘page_bits/login’;
% }

If you literally just want the name of the template, well, I don’t know how to do that, and I don’t know why you’d want to do that :-)

- Justin

Juergen Nickelsen

unread,
May 18, 2015, 5:45:42 AM5/18/15
to mojol...@googlegroups.com
On 14.05.2015 04:11, Justin Hawkins wrote:

>> for a while I have been trying to get at the name of the template that
>> is just being rendered, to use it in the layout.
>
> I can’t answer your question directly, but this requirement sounds like
> a bit of a code smell. What are you trying to accomplish?

Oh, I understand your suspicion. What I want to have is just an
informational comment in the rendered page that says which template has
rendered that page, like this:

<!-- template v_m_s/domains.html.ep -->

As I said, I am a novice with Mojolicious and "serious" web
applications, plus my application is (at this stage of development)
akind of twisty little maze of pages, of which some are, while not
actually redundant, relatively similar. At some point I was actually
wondering which template had rendered the page I was looking at, hence
that idea.

I could easily put that line by hand into each template to achieve the
same effent (or even devise a scheme to have that done automatically),
but as Mojolicious is great at avoiding boilerplate, I thought it should
be able to come up with a generic solution.

It is certainly not something that will be needed for production code.

Jan Henning Thorsen

unread,
Jun 3, 2015, 4:43:21 AM6/3/15
to mojol...@googlegroups.com, nick...@zedat.fu-berlin.de
While developing, you can see which templates are rendered on screen, with either:

$ morbo script/yourapp.pl
$ MOJO_LOG_LEVEL=debug perl script/yourapp.pl daemon

You will then see something like this in the log:

[Wed Jun  3 10:39:22 2015] [debug] Rendering template "index.html.ep"
[Wed Jun  3 10:39:22 2015] [debug] Rendering template "partials/nav.html.ep"
[Wed Jun  3 10:39:22 2015] [debug] Rendering template "partials/footer.html.ep"
[Wed Jun  3 10:39:22 2015] [debug] GET "/"

Note that if nothing appears to STDERR, then it's probably because you have "./log" directory.

On Monday, May 18, 2015 at 11:45:42 AM UTC+2, Juergen Nickelsen wrote:
On 14.05.2015 04:11, Justin Hawkins wrote:

>> for a while I have been trying to get at the name of the template that
>> is just being rendered, to use it in the layout.
>
> I can’t answer your question directly, but this requirement sounds like
> a bit of a code smell. What are you trying to accomplish?

Oh, I understand your suspicion. What I want to have is just an
informational comment in the rendered page that says which template has
rendered that page, like this:

<!-- template v_m_s/domains.html.ep -->

As I said, I am a novice with Mojolicious and "serious" web
applications, plus my application is (at this stage of development)
akind of twisty little maze of pages, of which some are, while not
actually redundant, relatively similar. At some point I was actually
wondering which template had rendered the page I was looking at, hence
that idea.

I could easily put that line by hand into each template to achieve the
same effent (or even devise a scheme to have that done automatically),
but as Mojolicious is great at avoiding boilerplate, I thought it should
be able to come up with a generic solution.

It is certainly not something that will be needed for production code.

Regards, Juergen.

--

Juergen Nickelsen

unread,
Jun 8, 2015, 11:08:20 AM6/8/15
to mojol...@googlegroups.com
Re my question on how to get the name of the template currently being
rendered in the layout code, On 03.06.2015 10:43, Jan Henning Thorsen wrote:
> While developing, you can see which templates are rendered on screen,
> with either:
>
> $ morbo script/yourapp.pl
> $ MOJO_LOG_LEVEL=debug perl script/yourapp.pl daemon
>
> You will then see something like this in the log:
>
> [Wed Jun 3 10:39:22 2015] [debug] Rendering template "index.html.ep"
[...]

I know that. If you read my question, you will notice that this does not
help me -- I want to access the name of the template from the layout code.

Regards, Juergen.

--
<Juergen....@fu-berlin.de> Tel +49.30.838-50740 Fax -450740

Juergen Nickelsen

unread,
Jun 10, 2015, 1:05:30 PM6/10/15
to mojol...@googlegroups.com
On 13.05.2015 19:18, Juergen Nickelsen wrote:
> Now I did this (as a helper function):
>
> sub current_template_name {
> my ($c) = @_;
> my $loghist = $c->app()->log()->{history};
> my $try = -1;
> my $msg;
> do {
> $msg = $loghist->[$try--]->[2];;
> } while ($msg =~ m{\"layouts/} && -$try < @{$loghist});
> $msg =~ s/^[^"]*"(.*)".*/$1/;
> return $msg;
> }

While that hideosity worked, to some degree, I noticed it broke my test
cases, once I ran them again. But only if I ran them *not* with "prove
-v" -- well, turned out the debug messages don't even show up in the log
history when debugging is not turned on. (Now that makes some sense.)

In this case this code tries to access non-existent entries, and Perl
doesn't like that -> the request returned a 500 instead of a 200.

After giving the idea some thought, I finally refrained from "improving"
this function so it would handle that case, and removed it and all the
code that used it. I am happy I did that. :-/

Allan Cochrane

unread,
Jun 10, 2015, 2:29:31 PM6/10/15
to mojol...@googlegroups.com
Hi,

might not be relevant now but have you tried

$controller->app->renderer->template_for($controller);

For me it returns the directory and file name but not the format and handler (i.e. .html.ep is missing)

Allan

Juergen Nickelsen

unread,
Jun 11, 2015, 6:06:21 AM6/11/15
to mojol...@googlegroups.com
On 10.06.2015 20:29, Allan Cochrane wrote:
> might not be relevant now but have you tried
>
> $controller->app->renderer->template_for($controller);
>
> For me it returns the directory and file name but not the format and
> handler (i.e. .html.ep is missing)

Yep, it does. Great! I'd never have divined that from the documentation.
Format and handler are not as important anyway, so I'll use that and see
how it works out over the time. Thanks a lot!

And the best thing is, it doesn't break my test cases. :-}

kberov

unread,
Jun 11, 2015, 6:15:00 AM6/11/15
to mojol...@googlegroups.com

Juergen Nickelsen

unread,
Jun 11, 2015, 6:17:02 AM6/11/15
to mojol...@googlegroups.com
On 11.06.2015 12:15, kberov wrote:
> May be this example could help you
>
> https://metacpan.org/source/BEROV/Ado-0.921/templates/layouts/default.html.ep

Yes, that is interesting, too. Thanks!

sri

unread,
Jun 11, 2015, 6:21:33 AM6/11/15
to mojol...@googlegroups.com, k.b...@gmail.com
Don't depend on private stash keys like "mojo.captures", they will change without warning.

--
sebastian 

kberov

unread,
Jun 11, 2015, 8:21:35 AM6/11/15
to mojol...@googlegroups.com, k.b...@gmail.com
Yes, sri. I know, but, as this being used only in development I allowed my self to do it.

sri

unread,
Jun 11, 2015, 8:23:36 AM6/11/15
to mojol...@googlegroups.com, k.b...@gmail.com
Yes, sri. I know, but, as this being used only in development I allowed my self to do it.

Yet, here you are recommending others do the same, without mentioning the risks.

--
sebastian 

kberov

unread,
Jun 11, 2015, 8:28:45 AM6/11/15
to mojol...@googlegroups.com, k.b...@gmail.com
ok, guilty.

To elaborate a bit:
What is the alternative of $controller->app->renderer->template_for($controller);
when there is no controller involved in the current request?
Thanks in advance!

sri

unread,
Jun 11, 2015, 8:37:34 AM6/11/15
to mojol...@googlegroups.com, k.b...@gmail.com
Personally, i find the whole idea silly, but i suppose <%= __FILE__ %> should work reasonably well.

--
sebastian

kberov

unread,
Jun 11, 2015, 9:04:22 AM6/11/15
to mojol...@googlegroups.com, k.b...@gmail.com
Thanks, for the advice on the silly idea. I will change my code to use <%= __FILE__ %> because I can not think of anything smarter.

Juergen Nickelsen

unread,
Jun 11, 2015, 10:28:40 AM6/11/15
to mojol...@googlegroups.com
On 11.06.2015 14:37, sri wrote:
> Personally, i find the whole idea silly, but i suppose <%= __FILE__ %>
> should work reasonably well.

That does not work as intended if I put it in the layout, as it gives me
the name of the layout file (unsuprisingly). I wanted to specifically
avoid having to put something into each of the templates, but factor it
out into the layout -- in the spirit of Mojolicious, which allows me to
avoid boilerplate code quite easily in general. :-)

But then it isn't that important anyway. Thanks for the hints!

kberov

unread,
Jun 11, 2015, 11:08:34 AM6/11/15
to mojol...@googlegroups.com
Sure :) it does not work in the leayout.
Reply all
Reply to author
Forward
0 new messages