Structured helpers

34 views
Skip to first unread message

Leo Cacciari

unread,
Mar 28, 2018, 6:43:51 AM3/28/18
to mojol...@googlegroups.com
Hi,
I was lookint to a way of organizing the helpers needed for an
application (a very silly one, it's just to learn Mojolicious) and I
found a little section in the rendering guide
(http://mojolicious.org/perldoc/Mojolicious/Guides/Rendering#Adding-helpers)
that talks about using prefixes in the helper names, creating 'proxy
helpers' that in turns allow to call the "real" helper in an indirect
way. The bothering part is the
"feature" associated with this, namely "to keep helpers from getting
exposed in templates as functions". I'm sure there is a very rationale
behind this but I can't see it.

I also read the discussion I found on the group archives
(https://groups.google.com/forum/#!topic/mojolicious/Pn0FkpBzO4I) but
it didn't help (maybe also because the references to the git
repository aren't there any more).

A little section in the Cookbock about adding plugins
(http://mojolicious.org/perldoc/Mojolicious/Guides/Cookbook#Adding-a-plugin-to-your-application)
seems to suggest that it would works if the "basename" of the helper
was the name of the plugin creating it (currently the helpers aren't
created by a plugin, but that can be quickly done).

That being said, I would ask to the collective wisdom of the group:

1. would proxy defined as explained in the cookboock work in templates?
2. is this the recommended way to organize helpers in 'namespaces'?

An explication of the rationale behind the decision of allowing
"nested" helpers only in controllers would also be interesting to
read.

Thanks to whomever will help :)

--
Leo Cacciari

Aliae nationes servitutem pati possunt. Populi Romani est propria libertas.

sri

unread,
Mar 28, 2018, 8:39:58 AM3/28/18
to Mojolicious
That being said, I would ask to the collective wisdom of the group:

  1. would proxy defined as explained in the cookboock work in templates?

Technically, you can always do "<%= $c->my_helper_prefix->foo('bar') %>".
 
  2. is this the recommended way to organize helpers in 'namespaces'?

There is none, template helpers are meant to be short.
 

An explication of the rationale behind the decision of allowing
"nested" helpers only in controllers would also be interesting to
read.

Most helpers are used as functions in templates (like "<%= url_for 'foo' %>"),
but helpers with prefix require a method call, which doesn't look as nice in
comparison ("<%= my_prefix->url_for('foo') %>") and is no better than
"<%= $c->my_prefix->url_for('foo') %>". And of course it's consistent with
stash value prefixes.

--
sebastian

Leo Cacciari

unread,
Mar 29, 2018, 9:47:45 AM3/29/18
to mojol...@googlegroups.com
On Wed, Mar 28, 2018 at 2:39 PM, sri <kra...@gmail.com> wrote:
>> That being said, I would ask to the collective wisdom of the group:
>>
>> 1. would proxy defined as explained in the cookboock work in templates?
>
>
> Technically, you can always do "<%= $c->my_helper_prefix->foo('bar') %>".
>
When I read this I started banging my head on the desk: I had
*completely missed* the paragraph in the rendering guide about the
controller being accessible
in the template scripts. Now that the headache has subsided, I can reply :)

Since the main reason I wanted 'structured' helpers was that I had two
helpers that logically should have had the same name but
where actually quite different. So I thought to introduce two helpers:
foo.foobar, to be used in the context of controller Foo to do foobnar,
and bar.foobar meant to do a different foobar in the context of
controller Bar.

What I did, was to define methods Foo::_foobar and Bar::_foobar and
then, in my app setup, define a single foobar helper with

$app->helper(foobar => sub {
my $c = shift;
return $c->_foobar(@_) if $c->$_can('_foobar');
# do something (e.g. croak) to handle the case were the
controller has no _foobar
});


I tried to define directly Foo::foobar and Bar::foobar, but I get something like

Undefined subroutine
&Mojo::Template::Sandbox::6bd05336357ba117d6ac9a329ea3a6ec::foobar

meaning there is something (well, more than some thing) that I do not
understand in how the functions are injected into the template object.
However, the solution above works for me, and I'm content :).
Obviously, I'm open to suggestion for better ways to do this.

cheers

Dan Book

unread,
Mar 29, 2018, 11:42:54 AM3/29/18
to mojol...@googlegroups.com
The template is rendered within its own namespace unique to that compilation, so you cannot inject subs directly. You can however pass coderefs in the stash and then do $foobar->() in the template. But namespacing the helpers seems reasonable to me.

-Dan

--
You received this message because you are subscribed to the Google Groups "Mojolicious" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mojolicious+unsubscribe@googlegroups.com.
To post to this group, send email to mojol...@googlegroups.com.
Visit this group at https://groups.google.com/group/mojolicious.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages