mojolicious referencing a stash variable not always defined - perl

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').

Related

TYPO3 extbase: Simple readable GET parameters

GET and POST parameters in custom extbase controllers need to be prefixed with the plugin signature to be injected automatically:
<?php
namespace Vendor\Example\Controller;
class SearchController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController
{
public function resultsAction($q = null)
{
//...
}
}
Search term $q is only filled automatically if it is passed as ?tx_example_search[q]=foo.
Is there a way declare that the readable version ?q=foo is also fine, and that this should be injected by extbase as well?
(I know that this breaks when multiple plugins on the same page use that parameter, but that's no problem here.)
(The parameter mapping seems already done when ActionController::processRequest() is called, so it must be done earlier.)
You could use the Extbase Plugin enhancer within the routing configuration.
See here: TYPO3 Advanced routing configuration Docs
TYPO3 would then transform the EXTbase URLs into an readable version.
Example:
without the routeEnhancer: yourdomain.com/?tx_example_search[q]=foo
with the routeEnhancer: yourdomain.com/foo
Tipp: You have to define all GET Params otherwise TYPO3 will show the cHash Param.
You can use the method \TYPO3\CMS\Core\Utility\GeneralUtility::_GP($var) in order to retrieve parameters from global variables GET/POST.
Or also \TYPO3\CMS\Core\Utility\GeneralUtility::_GET($var) or \TYPO3\CMS\Core\Utility\GeneralUtility::_POST($var).
Take care of security, those parameters are not sanitized !
If you really want to add the parameter to the action, you have to create an initializeAction() and set the parameter, something like this I guess :
public function initializeResultsAction() {
$myVar = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('q');
$this->request->setArgument('q', $myVar);
}

Mojolicious sharing of form element name between Perl and the template

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.

Rails 4 with CanCan: unknown attribute error after including load_and_authorize_resource

I'm working in Rails 4 and have gotten CanCan to work well with instructions from this issue, except for one use case that I think might be relatively common.
I have a Comment model, which has_many :comments, through: :replies for nested comments. All of this is working well, until I add load_and_authorize_resource to my comments controller. The problem seems to stem from a hidden field sending an optional :parent_comment_id attribute to my create action.
I've permitted this attribute via strong parameters:
def comment_params
params.require(:comment).permit(:content, :parent_comment_id, :post_id, :comment_id, :user_id)
end
So that I can create the association if a :parent_comment_id is included:
if comment_params[:parent_comment_id] != nil
Reply.create({:parent_comment_id => comment_params[:parent_comment_id], :comment_id => #comment.id})
end
But once I add load_and_authorize_resource, I get an unknown attribute error for :parent_comment_id. What am I missing?
Solution came to me in my sleep. Here's what I did to solve the problem:
The only reason comment_params wasn't normally having a problem on create, was because I was excluding the extra :parent_comment_id parameter, like this:
#comment = post.comment.create(comment_params.except(:parent_comment_id))
When CanCan used the comment_params method however, it did no such sanitation. Hence, the problem. It would have been messy to add that sanitation to CanCan on a per-controller basis, so I did what I should have done all along and instead of passing the :parent_comment_id inside :comment, I used hidden_field_tag to pass it outside of :comment and accessed it through plain, old params.
I hope this helps someone else who makes a similar mistake!

Accessing value by javascript Play Framework/Scala

First of all I am using Play framework with scala.
I am creating a graph and with the node id I would like to show some information at the same page.
In order to do that, first I need to get node.name but for some reasons #node.name function is not working. When searching for it I learnt that it's because play is server-side and js is client-side. However I need to get the data somehow.
I also cannot access:
var html = "<h4>" + node.name + "</h4><b> connections:</b><ul><li>"
How can I access this through the view?
My second question is after reaching the js node.name, I need to access to controller and do the same action one more time but this time with the new node.name .
View Part:
onClick: function(node) {
#node.name
}
1) Is this code in your controller? And are the node variable in scope? If so this should be perfectly legal code, since it will be evaluated as pure scala.
2) The templates are a different story however. You probably know they parse everything as normal html, unless escaped. To use a variable you have to bring it into scope by either:
defining a 'constructor' for the template at the absolute beginning of the file:
#(node : Node)
...
#node.name // later in the file
See http://www.playframework.com/documentation/2.0/ScalaTemplates
or define a variable inside the template:
#defining( Get.node.from.somewhere ) { node =>
#node.name
}
See Play! framework: define a variable in template?
If you did either of the two, you should have no problem accessing the node variable. Even in scripts. But note that external scripts does not have access to the same variables. It is thus very common to use inline scripts or import it as another template if you need to access a variable from JavaScript.
Edit: I've made a gist of a template, controller and routes file: https://gist.github.com/Jegp/5732033

Cannot access devise current_admin_user in AcitveAdmin form definition

I need to display some form fields in ActiveAdmin form only to specific users.
But when I try to check user status with this code:
ActiveAdmin.register Store do
# ...
form do |f|
f.inputs "Basic" do
if current_admin_user.super_admin?
f.input :admin_user
end
# ...
end
end
end
I get
undefined local variable or method `current_admin_user' for #<ActiveAdmin::DSL:0xdb8e798>
CanCan methods also don't work in the ActiveAdmin form definition.
Generally my question is: how can I manage admin interface display, based on current user type?
Particularly, how can I get current devise user object from within ActiveAdmin definitions?
It is a matter of scope. You could try accessing the helper method using the f.template object like so:
ActiveAdmin.register Store do
# ...
form do |f|
f.inputs "Basic" do
if f.template.current_admin_user.super_admin?
f.input :admin_user
end
# ...
end
end
end
Good luck.
I've found a workaround for this issue. In /app/admin/stores.rb:
ActiveAdmin.register Store do
# ...
form :partial => 'form'
# ...
end
and then in /app/views/admin/stores/_form.html.haml:
= semantic_form_for [:admin, #store] do |f|
= f.inputs "Basic" do
- if current_admin_user.super_admin?
=f.input :admin_user
It's not convenient at all, but works.
I know this thread is a little old but I just found a nice little fix for this. I'm not using devise, I'm using the Twitter API for logging in my users
In active_admin.rb, look for config.current_user_method and change the default value to current_user from current_admin_user
config.current_user_method = :current_user
Also change the logout_link_path to in your routes to include as: :destroy_user_session