I'm new at using Mojolicious and therefore I apologize if this is a basic question but I looked around and couldn't find a good way to do it.
I would like to know what's the best strategy to share the name of form parameters between the Perl code (to be used in param('element') and a template (to be used in say INPUT name="element" ...>.
Is there a way to define 'element' somewhere so that it can be used in both the Perl side and the template side? A super global variable?
Thanks in advance!
if i understand you correct then stash - is answer for your question.
https://metacpan.org/pod/Mojolicious::Controller#stash
Example. In controller you have such code:
sub action {
my $c = shift;
$c->stash(name_of_param => $c->param('name_of_param'), another_param => $c->param('another_param'));
$c->render;
}
In template:
<h1><%= $name_of_param %></h1>
<h2><%= $another_param %></h2>
I think that more good way not exist.
Related
I am still learning mojolicious and MVC frameworks in general so this just might be a problem where I am thinking about this wrong so if I am please suggest a better way to do the following.
I have a route /route/:param where param is sometimes defined and sometimes not. I am trying to use "param" in the template for that route but I get an error saying "param" requires explicit package name. I know this is due to :param not matching in the route because when I do call /route/value everything works fine.
Is there a way to be able to use the same template for both when "param" is defined and not defined? I am just trying to pre-populate a form off of what is defined in "param" but not making it required to.
In the template I have
<% if(defined($param)){ %><%= $param %><% } %>
Thanks.
It is always safe to refer to stash("param"), where stash is a helper function defined in Mojolicious::Plugin::DefaultHelpers:
<%= stash "param" %>
<%= defined(stash("param")) && stash("param") %>
etc.
It is possible to define a stash (or a flash) variable as a Perl variable within the epl space/template so that it can be reused, if required. e.g.,
% if (my $param = stash 'param') {
$param
% }
In this case the if condition block will be rendered only when the param is defined in the stash, otherwise, it'll be skipped.
It seems like in this situation using an optional placeholder in the route might be the best option. If the placeholder is defined in the route itself that definition will be used if the placeholder is not given in the url (else the value specified in the URL is used).
For example:
$r->any('/page/:paramVar')->to('page#doTheThing', paramVar => 'cake');
If the the address "/page" is loaded then $self->param('paramVar') == 'cake' else if "/page/tree" is loaded then $self->param('paramVar') == 'tree'.
Note: As with other placeholder values an optional placeholder, such as paramVar used in the above example, can be accessed via the stash function as well as the param function: $self->stash('paramVar').
What is the difference between $c->uri_for and $c->uri_for_action methods of Catalyst.
Which one to use? And why?
#Devendra I think your examples could be somehow misleading if someone reads them.
uri_for expects path (and not action). It return an absolute URI object, so for example it's useful for linking to static content or in case you don't expect your paths to change.
So for example, let say you've deployed your application on domain example.com and subdir abc (example.com/abc/): $c->uri_for('/static/images/catalyst.png') would return example.com/abc/static/images/catalyst.pn, or for example: $c->uri_for('/contact-us-today') would return example.com/abc/contact-us-today. If you decide later to deploy your application under another subdirectory or at / you'll still end up with correct links.
Let say that your contact-us action looks like: sub contact :Path('/contact-us-today') :Args(0) {...} and you decide later that /contact-us-today should become just /contact-us. If you've used uri_for('/contact-us-today') you'll need to find and change all lines which points to this url. However you can use $c->uri_for_action('/controller/action_name') which will return the correct url.
dpetrov_ in #catalyst says:
If the paths are likely to change, uri_for_action is better idea.
I found below difference between $c->uri_for and $c->uri_for_action
Consider
Othercontroller.pm
__PACKAGE__->config(namespace => 'Hello');
.
.
.
sub bar: Local{
$c->res->redirect($c->uri_for('yourcontroller/method_name'));
$c->res->redirect($c->uri_for_action('yourcontroller/method_name'));
}
Yourcontroller.pm
sub method_name: Local{
print "In Yourcontroller:: method_name"
}
In case of $c->uri_for the url changes to
http://localhost:3000/Hello/yourcontroller/method_name
However for $c->uri_for_action the url changes to
http://localhost:3000/yourcontroller/method_name
So the namespace gets added in case of uri_for.
i am making some good progress with Perl due to the help on this site but i've run into a problem. One of the pages i was scraping from has changed and i can't figure out how to get to it now. What i want to do is store a link to each page i want to get to. The problem is that these links are inside the a href attribute tags in the source code and i have no idea how to extract them. Could anyone help me?
the links i need are from line 316 to 354 of this page(source code) http://www.soccerbase.com/teams/home.sd
i need to basically extract the links to variables for use in my other scripts. As mentioned i am using WWW::Mechanize and HTML::TokeParser, hopefully there are methods within these that i can use but can't currently figure out. Thanks in advance!
See method find_all_links in WWW::Mechanize. No need to bother manually with the parser. You probably want to relax the regex so that you get all ~1000 possible teams at once.
use WWW::Mechanize qw();
my $w = WWW::Mechanize->new;
$w->get('http://www.soccerbase.com/teams/home.sd');
for my $link ($w->find_all_links(url_regex => qr/comp_id=1\b/)) {
# 20 instances of WWW::Mechanize::Link
printf "URL=%s\tTeam=%s\n", $link->url_abs, $link->text
}
URL=http://www.soccerbase.com/tournaments/tournament.sd?comp_id=1 Team=Premier League
URL=http://www.soccerbase.com/teams/team.sd?team_id=142&comp_id=1 Team=Arsenal
URL=http://www.soccerbase.com/teams/team.sd?team_id=154&comp_id=1 Team=Aston Villa
URL=http://www.soccerbase.com/teams/team.sd?team_id=308&comp_id=1 Team=Blackburn
URL=http://www.soccerbase.com/teams/team.sd?team_id=354&comp_id=1 Team=Bolton
URL=http://www.soccerbase.com/teams/team.sd?team_id=536&comp_id=1 Team=Chelsea
URL=http://www.soccerbase.com/teams/team.sd?team_id=942&comp_id=1 Team=Everton
URL=http://www.soccerbase.com/teams/team.sd?team_id=1055&comp_id=1 Team=Fulham
URL=http://www.soccerbase.com/teams/team.sd?team_id=1563&comp_id=1 Team=Liverpool
URL=http://www.soccerbase.com/teams/team.sd?team_id=1718&comp_id=1 Team=Man City
URL=http://www.soccerbase.com/teams/team.sd?team_id=1724&comp_id=1 Team=Man Utd
URL=http://www.soccerbase.com/teams/team.sd?team_id=1823&comp_id=1 Team=Newcastle
URL=http://www.soccerbase.com/teams/team.sd?team_id=1855&comp_id=1 Team=Norwich
URL=http://www.soccerbase.com/teams/team.sd?team_id=2093&comp_id=1 Team=QPR
URL=http://www.soccerbase.com/teams/team.sd?team_id=2477&comp_id=1 Team=Stoke
URL=http://www.soccerbase.com/teams/team.sd?team_id=2493&comp_id=1 Team=Sunderland
URL=http://www.soccerbase.com/teams/team.sd?team_id=2513&comp_id=1 Team=Swansea
URL=http://www.soccerbase.com/teams/team.sd?team_id=2590&comp_id=1 Team=Tottenham
URL=http://www.soccerbase.com/teams/team.sd?team_id=2744&comp_id=1 Team=West Brom
URL=http://www.soccerbase.com/teams/team.sd?team_id=2783&comp_id=1 Team=Wigan
URL=http://www.soccerbase.com/teams/team.sd?team_id=2848&comp_id=1 Team=Wolves
i have a problem with calling a function which name is a string.
I made few helpers which i want to echo in my phtml file like this:
echo $this->EditProfile();
echo $this->ViewProfile();
The EditProfile() and ViewProfile() are names of the View Helpers which i created and i'm calling them in view. And this method is working fine. But when i want dynamicly call a function by name stored in database im trying to do this in this way:
im getting the names of helpers from database and store them into array and then trying to display them in foreach.
foreach ($this->modules as $key => $module)
{
echo $this->$module['name'];
}
the variable
$module['name']
contains a valid name of Helper which i want to call in phtml file (checked with Zend_debug::dump() and with just an echo $module['name'] in foeach and id display it properly... but this echo its not working and not calling the View Helper, nothing is displayed
when i try eval or call_user_func too nothing is displayed too... How can i do this in foreach or other loop?
ok solved it myself :)
dont know is this solution properly but its actually working ;)
instead call_user_func i mentioned that magical function __call is same as call_user_func_array
so i edited code like this below
foreach ($this->modules as $key => $module)
{
$this->__call($module['name'],array(null));
}
in this case array is null cause none parameters are passed to function. If in my helper ill need parameters ill pass them in this array in future.
And this solution works fine for me :)
If someone have better solution please post it here and share your opinion ;)
regards
Darek
Is there any way to do something like that.
I have next wiki text:
{{template_open_tag}}
{{template_some_data}}
{{template_close_tag}}
And there are templates:
{{template_open_tag}}
<my-tag>
{{template_some_data}}
bla-bla-bla...
{{template_close_tag}}
</my-tag>
But tag '<bold>' processed already when first template transluded and wiki render this page like:
bla-bla-bla...
</my-tag>
But I want to see:
**bla-bla-bla...**
In my extension:
$wgHooks['ParserFirstCallInit'][] = 'myTagInit';
function myTagInit( &$parser ) {
$parser->setHook( 'my-tag', 'myTagRender' );
}
function myTagRender( $input, $args, $parser, $frame) {
return "**".$input."**";
}
Thank you.
P.S.
And don't ask me why I need this strange markup and don't want to use something like this:
{{template_tag|{{template_some_data}}}}
And {{template_open_tag}} like:
<my-tag>{{{1}}}</my-tag>
To warn you -- this sort of structure will likely be phased out entirely in future versions of MediaWiki, due to its inconsistent behavior and the difficulties it causes with structures like tags and sections.
The correct and future-proof way to do it is indeed to contain both your start and end in one template and pass the middle in as a parameter, eg {{template_tag|{{template_some_data}}}}
Set $wgUseTidy to true to make MediaWiki remove unclosed tags only after all the templates have been evaluated. Alternatively, you can use wikimarkup - as Adrian said - which does not suffer from this limitation.
Update: AFAIK XML-style extension tags are evaluated before way template including happens, so piecing them together from multiple templates is not possible. (Event <ext>{{{1}}}</ext> does not work pre-1.16, though you can make it work in 1.16 with recursiveTagParse.)
instead of using <bold> use ''' in both your {{template_open_tag}} and {{template_close_tag}} and it should render as bla-bla-bla...
Also, you can't do:
{{template_open_tag}}
{{template_some_data}}
{{template_close_tag}}
You have to do
{{template_open_tag}}{{template_some_data}}{{template_close_tag}}