$app->secret() by $app->secrets() ) has touched me. But the fact remains - backward compatibility is broken, often broken, and without really good reasons: for example, in the case of secret() nothing prevented adding to the code sub secret { shift->secrets([shift]) } or simply add support for additional parameters to the secret() instead of adding the new function secrets() implementing the necessary feature without breaking the compatibility at all.$self often used, which does not add readability — there are too many classes in the framework, and not always looking at $self it is easy to figure out which class this object is in this example. Therefore, I will use instead of $self in the examples: $app # YourApp → Mojolicious $r # Mojolicious::Routes ($app->routes) $c # YourApp::SomeController → Mojolicious::Controller $ua # Mojo::UserAgent $r->get("/a/b/c/d") ->to(text=>"1"); $ab = $r->route("/a")->route("/b"); $ab->get("/c") ->to(text=>"2-1"); $ab->get("/c/d") ->to(text=>"2-2"); $r->get("/a/b/c/d/e") ->to(text=>"3"); $ r {}
├─ / a / b / c / d {text => "1"}
├─ / a─── / b─┬─ / c {text => "2-1"}
│ └─ / c / d {text => "2-2"}
└─ / a / b / c / d / e {text => "3"}
GET / a / b => 404 Not Found GET / a / b / c => "2-1" GET / a / b / c / d => "1" GET / a / b / c / d / e => "3" GET / a / b / c / d / e / f => 404 Not Found
route() , normal get() , etc.) and whether the request handler is set for them ( "controller#action" or {cb=>\&handler} , etc.).get() : $r->get("a", {text=>"A"})->get("b", {text=>"B"}); GET / a => 404 Not Found GET / a / b => "B"
$app->routes->to(text=>"wow"); GET / => "wow"
under() , or an existing node can be made under by calling inline(1) . After determining the terminal node that should process the current request, handlers of all the under-nodes will be sequentially called from the root of the tree to the terminal. These handlers must return true or false (you can even asynchronously) - if they return false, subsequent handlers, including the terminal node handler, will not be called. "/something/:name/:id" name => ["alex","nick"], id => qr/^\d+$/ format => 0 format => ["json","xml"] agent => qr/Firefox/ $c->stash() when processing the requesturl_for # defaults . $r->to("users#"); # /resource . $b = $r->route("/resource", format => 0); # $b $b # /resource. # get() , # , , .. /resource. $b->get()->over(agent=>qr/Firefox/)->to("#ff_only"); $b->get()->to("#not_ff"); $app->defaults and through the root node $app->routes->to (maybe some hooks work completely before routing, and then the values ​​from $app->defaults will be available and may not be available from the root node).$r->any("/path")->to(app=>$otherapp) , maybe there are additional nuances.over() , to() and via() - they return the current value when called without parameters).$r->route() creates a new node, parameters:$r->via() sets the HTTP method (s)$r->over() sets the conditions$r->to() sets default parameters$r->under() creates an under-nodeget()$r->any() creates a node for any HTTP methodsget()$r->get() creates a node for the HTTP GET method$r->post() creates a node for the HTTP POST methodget()$r->put() creates a node for the HTTP PUT methodget()$r->delete() creates a node for the HTTP DELETE methodget()$r->patch() creates a node for the HTTP PATCH methodget()$r->options() creates a node for the HTTP OPTIONS methodget() # Mojolicious $r->get("/users/:id", [ format => 0 ], agent => qr/Firefox/, { id => -1, controller => "users" }, [ id => qr/^\d+$/ ], headers => { "X-Secret" => "letmeit" }, \&cb, { action => "list" }, "my_cool_route", ); # get() $r->route("/users/:id", id => qr/^\d+$/, format => 0) ->via("GET") ->over(agent => qr/Firefox/, headers => { "X-Secret" => "letmeit" }) ->to(id => -1, controller => "users", action => "list", cb => \&cb) ->name("my_cool_route"); application/x-www-form-urlencoded or type multipart/form-data — but in this case only ordinary parameters are taken, except for filesmultipart/form-data$c->param is mentioned - let's see where the values ​​returned by this function come from (in Mojolicious up to 5.47) :scalar $c->param() - returns undef@names = $c->param() - returns the names of all GET, POST, UPLOAD and ROUTE parameters$value = $c->param("name") - returns:@values = $c->param("name") - returns:$c->param does is already beyond good and evil (for example, if you were expecting a GET / POST parameter , and get UPLOAD, then instead of the string value , get the object Mojo :: Upload). Everything is good in moderation, even the magic sloth functions that create the wow factor that Mojolicious so much like to implement. $value = $c->stash( "name" ) # ROUTE # HASHREF: : # - ( ) # - ( ) $params = $c->req->params->to_hash # POST, GET $params = $c->req->query_params->to_hash # GET $params = $c->req->body_params->to_hash # POST # ARRAYREF: , Mojo::Upload $uploads = $c->req->uploads # UPLOAD @names = @{ $c->req->params->names } # POST GET @names = @{ $c->req->query_params->names } # GET @names = @{ $c->req->body_params->names } # POST @names = keys %{{ map { $_->name => 1 } @{ $c->req->uploads } }} # UPLOAD $c->req->params->param( "name" ) # POST, GET $c->req->query_params->param( "name" ) # GET $c->req->body_params->param( "name" ) # POST $c->req->upload( "name" ) # UPLOAD $c->req->params->every_param( "name" ) # POST, GET $c->req->query_params->every_param( "name" ) # GET $c->req->body_params->every_param( "name" ) # POST $c->req->every_upload( "name" ) # UPLOAD $c->req->param is the same as $c->req->params->param$c->req->url->query is the same as $c->req->query_paramsto_hash you can use pairs - it returns a link to the array where the names and values ​​of all parameters go successively, and one name may occur several times, but all values ​​are scalars.$tx->res will be available (with a 404 stub).$dom has a root node, and the node with the html tag (if it was in the downloaded page) is a descendant of the root node. Because of this, to_string and content on the root node return the same thing.$dom->child_tag_name ), the pearl throws an exception “there is no such method” - in other words, it is almost always necessary to include the parser in eval .flatten and compact collections will help here."*" means a string with CSS selector. $tx = $ua->get($url); # Mojo::Transaction::HTTP → Mojo::Transaction $tx->error # undef {message=>'…',…} $tx->success # undef $tx->res $tx->req # Mojo::Message::Request → Mojo::Message $tx->res # Mojo::Message::Response → Mojo::Message $tx->redirects # [ Mojo::Transaction::HTTP, … ] $res = $tx->res; # Mojo::Message::Response → Mojo::Message $res->error # undef {message=>'Parse error',…} $res->to_string # "…" (headers+content) $res->is_status_class(200); # bool $res->code # 404 $res->message # "Not Found" $res->headers # Mojo::Headers $res->cookies # [ Mojo::Cookie::Response, … ] $res->cookie('name') # Mojo::Cookie::Response → Mojo::Cookie $res->body # "…" $res->text # "…" (decoded body using charset) $res->dom # Mojo::DOM $res->json # Mojo::JSON $headers = $res->headers; # Mojo::Headers $headers->names # [ "Content-Type", "Server", … ] $headers->to_hash # { "Content-Type" => "…", … } $headers->header('Server') # "…" $headers->$standard_header_name # "…" (shortcuts for useful headers) $dom = $res->dom; # Mojo::DOM $dom->to_string # "…" ( , ) $dom->content # "…" ( ) $dom->type # "…" ( : root,tag,text,comment,…) $dom->tag # "…" "" ( ) $dom->attr # {name=>"val",…} $dom->attr('name') # "val" $dom->{name} # $dom->attr("name") $dom->all_text # "…" ( ) $dom->all_text(0) # "…" ( , ) $dom->text # "…" ( ) $dom->text(0) # "…" ( , ) $dom->root # Mojo::DOM ( ) $dom->parent # Mojo::DOM undef (-) $dom->next # Mojo::DOM undef ( -) $dom->next_node # Mojo::DOM undef ( -) $dom->previous # Mojo::DOM undef ( -) $dom->previous_node # Mojo::DOM undef ( -) $dom->matches('*') # true/false ( ) $dom->at('*') # Mojo::DOM undef ( ) $dom->find('*') # Mojo::Collection ( ) $dom->ancestors # Mojo::Collection (-) $dom->ancestors('*') # Mojo::Collection ( -) $dom->following # Mojo::Collection ( -) $dom->following("*") # Mojo::Collection ( -) $dom->following_nodes # Mojo::Collection ( -) $dom->preceding # Mojo::Collection ( -) $dom->preceding("*") # Mojo::Collection ( -) $dom->preceding_nodes # Mojo::Collection ( -) $dom->children # Mojo::Collection (-) $dom->children('*') # Mojo::Collection ( -) $dom->descendant_nodes # Mojo::Collection ( ) $dom->child_nodes # Mojo::Collection ( -) $dom->[0] # $dom->child_nodes->[0] $res->dom('*') # $dom->find('*') $ua , TCP- - — : $app , Mojo::UserAgent, , , url, , $app . Mojo::UserAgent::Server->app($app); $ perl -Mojo -E 'get "/", {text=>"wow\n"}; app->start' get / wow MOJO_ — , .. Mojolicious, :MOJO_MODE — - , , , :$app->modeexception not_found ( MOJO_MODE , . «exception.$mode.html.ep»)$app->log->level «debug» «info» MOJO_MODE «development»${mode}_mode() startup() ( , ) .MOJO_LOG_LEVEL — «warn» Mojolicious::Lite, .Source: https://habr.com/ru/post/227493/
All Articles