Mojolicious route creation












0















I want to route a request to a controller that's dynamically constructed, base on a place holder in the url. To illustrate, I want do something like the following:



use Mojo::Base 'Mojolicious';

sub startup {

my $r = $self->routes;
my $route = $r->get('/:customer/boxs/:id');

[ somehow, extract the :customer holder into a variable $customer, then ]

$route->(
controller => "$customer::boxs',
action => 'get_list',
);
}


I tried but can't seem to find way to this, and I'm not sure if this is possible?
Some pointer is appreciated. Thanks.



UPDATE

I am able to parse the url of a request with a 'before_depatch' hook, and figure out what Customer Class should be used, before routing happens.



Assuming the request url is /kwikemart/liquor/22, I figure out the customer name (kwikemart) like this:



sub startup {
my $self = shift;
$self->hook( before_dispatch => sub {
my $c= shift;
$c->req->url->path =~ m#^/(w+)/.+#;
$customer = $1;
}

$r = $self->routes;
$r->get('....')->to(....);
...
...
}


The question is, where to store this $customer, so I can use it to specify the correct route later? I still don't quite get how Mojo::Base Class work. Not sure how to correctly create custom attribute, that's local to each request, so it can be used within a $r->to() call.










share|improve this question

























  • I don't know if Mojolicious offers an elegant/convenient way to do this. However, you can always use a dispatch table: my %dispatch = (customer1 => &customer1); $r->get('/:customer' => sub { my $self = shift; $dispatch{$self->stash('customer')}->($self) }) (adapt to your needs...). I'll let someone with a better knowledge of Mojolicious post an answer though.

    – Dada
    Jan 2 at 10:54








  • 1





    I assume that you have a limited amount of values for $customer. Then you should just do: my @customers = get_customers(); for my $customer (@customers) { $r->get("/$customer/boxs/:id")->to(controller => "$customer::boxs", ... ) }. Otherwise, have one route to dispatch them: $r->get('/:customer/boxs/:id')->to(cb => sub { my($c) = @_; ... handle $c->param('customer')}). If $customer is not a class name but a customer id, don't create a class for each customer.

    – Corion
    Jan 2 at 11:39













  • Thanks. You're right, there's not many customer, but I intend to design it with flexibility in mind, and Customer does need to be a class. The idea is, each customer has its own variant of box content handler, so by calling on an different url, the relevant Customer class will be correctly invoked. Anyways, I figured out to parse the url of a request with a 'before_depatch' hook, but the question is, where to store this? I still don't quite get how Mojo::Base Class work, so not sure how to correctly create custom attribute (without race condition)

    – Terry Yang
    Jan 2 at 20:55













  • Anything that you want to store specific to that request tends to go in the stash: $c->stash(customer => $customer); ... my $customer = $c->stash('customer'); Just keep in mind the namespace is shared by both your route placeholders and reserved keys.

    – Grinnz
    Jan 10 at 23:37













  • Note your hook will run at request time, whereas your routes are set up at app startup, so you can't use anything from the hook in your route setup (but you can use the stash in the resulting actions).

    – Grinnz
    Jan 10 at 23:39


















0















I want to route a request to a controller that's dynamically constructed, base on a place holder in the url. To illustrate, I want do something like the following:



use Mojo::Base 'Mojolicious';

sub startup {

my $r = $self->routes;
my $route = $r->get('/:customer/boxs/:id');

[ somehow, extract the :customer holder into a variable $customer, then ]

$route->(
controller => "$customer::boxs',
action => 'get_list',
);
}


I tried but can't seem to find way to this, and I'm not sure if this is possible?
Some pointer is appreciated. Thanks.



UPDATE

I am able to parse the url of a request with a 'before_depatch' hook, and figure out what Customer Class should be used, before routing happens.



Assuming the request url is /kwikemart/liquor/22, I figure out the customer name (kwikemart) like this:



sub startup {
my $self = shift;
$self->hook( before_dispatch => sub {
my $c= shift;
$c->req->url->path =~ m#^/(w+)/.+#;
$customer = $1;
}

$r = $self->routes;
$r->get('....')->to(....);
...
...
}


The question is, where to store this $customer, so I can use it to specify the correct route later? I still don't quite get how Mojo::Base Class work. Not sure how to correctly create custom attribute, that's local to each request, so it can be used within a $r->to() call.










share|improve this question

























  • I don't know if Mojolicious offers an elegant/convenient way to do this. However, you can always use a dispatch table: my %dispatch = (customer1 => &customer1); $r->get('/:customer' => sub { my $self = shift; $dispatch{$self->stash('customer')}->($self) }) (adapt to your needs...). I'll let someone with a better knowledge of Mojolicious post an answer though.

    – Dada
    Jan 2 at 10:54








  • 1





    I assume that you have a limited amount of values for $customer. Then you should just do: my @customers = get_customers(); for my $customer (@customers) { $r->get("/$customer/boxs/:id")->to(controller => "$customer::boxs", ... ) }. Otherwise, have one route to dispatch them: $r->get('/:customer/boxs/:id')->to(cb => sub { my($c) = @_; ... handle $c->param('customer')}). If $customer is not a class name but a customer id, don't create a class for each customer.

    – Corion
    Jan 2 at 11:39













  • Thanks. You're right, there's not many customer, but I intend to design it with flexibility in mind, and Customer does need to be a class. The idea is, each customer has its own variant of box content handler, so by calling on an different url, the relevant Customer class will be correctly invoked. Anyways, I figured out to parse the url of a request with a 'before_depatch' hook, but the question is, where to store this? I still don't quite get how Mojo::Base Class work, so not sure how to correctly create custom attribute (without race condition)

    – Terry Yang
    Jan 2 at 20:55













  • Anything that you want to store specific to that request tends to go in the stash: $c->stash(customer => $customer); ... my $customer = $c->stash('customer'); Just keep in mind the namespace is shared by both your route placeholders and reserved keys.

    – Grinnz
    Jan 10 at 23:37













  • Note your hook will run at request time, whereas your routes are set up at app startup, so you can't use anything from the hook in your route setup (but you can use the stash in the resulting actions).

    – Grinnz
    Jan 10 at 23:39
















0












0








0








I want to route a request to a controller that's dynamically constructed, base on a place holder in the url. To illustrate, I want do something like the following:



use Mojo::Base 'Mojolicious';

sub startup {

my $r = $self->routes;
my $route = $r->get('/:customer/boxs/:id');

[ somehow, extract the :customer holder into a variable $customer, then ]

$route->(
controller => "$customer::boxs',
action => 'get_list',
);
}


I tried but can't seem to find way to this, and I'm not sure if this is possible?
Some pointer is appreciated. Thanks.



UPDATE

I am able to parse the url of a request with a 'before_depatch' hook, and figure out what Customer Class should be used, before routing happens.



Assuming the request url is /kwikemart/liquor/22, I figure out the customer name (kwikemart) like this:



sub startup {
my $self = shift;
$self->hook( before_dispatch => sub {
my $c= shift;
$c->req->url->path =~ m#^/(w+)/.+#;
$customer = $1;
}

$r = $self->routes;
$r->get('....')->to(....);
...
...
}


The question is, where to store this $customer, so I can use it to specify the correct route later? I still don't quite get how Mojo::Base Class work. Not sure how to correctly create custom attribute, that's local to each request, so it can be used within a $r->to() call.










share|improve this question
















I want to route a request to a controller that's dynamically constructed, base on a place holder in the url. To illustrate, I want do something like the following:



use Mojo::Base 'Mojolicious';

sub startup {

my $r = $self->routes;
my $route = $r->get('/:customer/boxs/:id');

[ somehow, extract the :customer holder into a variable $customer, then ]

$route->(
controller => "$customer::boxs',
action => 'get_list',
);
}


I tried but can't seem to find way to this, and I'm not sure if this is possible?
Some pointer is appreciated. Thanks.



UPDATE

I am able to parse the url of a request with a 'before_depatch' hook, and figure out what Customer Class should be used, before routing happens.



Assuming the request url is /kwikemart/liquor/22, I figure out the customer name (kwikemart) like this:



sub startup {
my $self = shift;
$self->hook( before_dispatch => sub {
my $c= shift;
$c->req->url->path =~ m#^/(w+)/.+#;
$customer = $1;
}

$r = $self->routes;
$r->get('....')->to(....);
...
...
}


The question is, where to store this $customer, so I can use it to specify the correct route later? I still don't quite get how Mojo::Base Class work. Not sure how to correctly create custom attribute, that's local to each request, so it can be used within a $r->to() call.







perl mojolicious






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 2 at 21:25







Terry Yang

















asked Jan 2 at 10:43









Terry YangTerry Yang

11




11













  • I don't know if Mojolicious offers an elegant/convenient way to do this. However, you can always use a dispatch table: my %dispatch = (customer1 => &customer1); $r->get('/:customer' => sub { my $self = shift; $dispatch{$self->stash('customer')}->($self) }) (adapt to your needs...). I'll let someone with a better knowledge of Mojolicious post an answer though.

    – Dada
    Jan 2 at 10:54








  • 1





    I assume that you have a limited amount of values for $customer. Then you should just do: my @customers = get_customers(); for my $customer (@customers) { $r->get("/$customer/boxs/:id")->to(controller => "$customer::boxs", ... ) }. Otherwise, have one route to dispatch them: $r->get('/:customer/boxs/:id')->to(cb => sub { my($c) = @_; ... handle $c->param('customer')}). If $customer is not a class name but a customer id, don't create a class for each customer.

    – Corion
    Jan 2 at 11:39













  • Thanks. You're right, there's not many customer, but I intend to design it with flexibility in mind, and Customer does need to be a class. The idea is, each customer has its own variant of box content handler, so by calling on an different url, the relevant Customer class will be correctly invoked. Anyways, I figured out to parse the url of a request with a 'before_depatch' hook, but the question is, where to store this? I still don't quite get how Mojo::Base Class work, so not sure how to correctly create custom attribute (without race condition)

    – Terry Yang
    Jan 2 at 20:55













  • Anything that you want to store specific to that request tends to go in the stash: $c->stash(customer => $customer); ... my $customer = $c->stash('customer'); Just keep in mind the namespace is shared by both your route placeholders and reserved keys.

    – Grinnz
    Jan 10 at 23:37













  • Note your hook will run at request time, whereas your routes are set up at app startup, so you can't use anything from the hook in your route setup (but you can use the stash in the resulting actions).

    – Grinnz
    Jan 10 at 23:39





















  • I don't know if Mojolicious offers an elegant/convenient way to do this. However, you can always use a dispatch table: my %dispatch = (customer1 => &customer1); $r->get('/:customer' => sub { my $self = shift; $dispatch{$self->stash('customer')}->($self) }) (adapt to your needs...). I'll let someone with a better knowledge of Mojolicious post an answer though.

    – Dada
    Jan 2 at 10:54








  • 1





    I assume that you have a limited amount of values for $customer. Then you should just do: my @customers = get_customers(); for my $customer (@customers) { $r->get("/$customer/boxs/:id")->to(controller => "$customer::boxs", ... ) }. Otherwise, have one route to dispatch them: $r->get('/:customer/boxs/:id')->to(cb => sub { my($c) = @_; ... handle $c->param('customer')}). If $customer is not a class name but a customer id, don't create a class for each customer.

    – Corion
    Jan 2 at 11:39













  • Thanks. You're right, there's not many customer, but I intend to design it with flexibility in mind, and Customer does need to be a class. The idea is, each customer has its own variant of box content handler, so by calling on an different url, the relevant Customer class will be correctly invoked. Anyways, I figured out to parse the url of a request with a 'before_depatch' hook, but the question is, where to store this? I still don't quite get how Mojo::Base Class work, so not sure how to correctly create custom attribute (without race condition)

    – Terry Yang
    Jan 2 at 20:55













  • Anything that you want to store specific to that request tends to go in the stash: $c->stash(customer => $customer); ... my $customer = $c->stash('customer'); Just keep in mind the namespace is shared by both your route placeholders and reserved keys.

    – Grinnz
    Jan 10 at 23:37













  • Note your hook will run at request time, whereas your routes are set up at app startup, so you can't use anything from the hook in your route setup (but you can use the stash in the resulting actions).

    – Grinnz
    Jan 10 at 23:39



















I don't know if Mojolicious offers an elegant/convenient way to do this. However, you can always use a dispatch table: my %dispatch = (customer1 => &customer1); $r->get('/:customer' => sub { my $self = shift; $dispatch{$self->stash('customer')}->($self) }) (adapt to your needs...). I'll let someone with a better knowledge of Mojolicious post an answer though.

– Dada
Jan 2 at 10:54







I don't know if Mojolicious offers an elegant/convenient way to do this. However, you can always use a dispatch table: my %dispatch = (customer1 => &customer1); $r->get('/:customer' => sub { my $self = shift; $dispatch{$self->stash('customer')}->($self) }) (adapt to your needs...). I'll let someone with a better knowledge of Mojolicious post an answer though.

– Dada
Jan 2 at 10:54






1




1





I assume that you have a limited amount of values for $customer. Then you should just do: my @customers = get_customers(); for my $customer (@customers) { $r->get("/$customer/boxs/:id")->to(controller => "$customer::boxs", ... ) }. Otherwise, have one route to dispatch them: $r->get('/:customer/boxs/:id')->to(cb => sub { my($c) = @_; ... handle $c->param('customer')}). If $customer is not a class name but a customer id, don't create a class for each customer.

– Corion
Jan 2 at 11:39







I assume that you have a limited amount of values for $customer. Then you should just do: my @customers = get_customers(); for my $customer (@customers) { $r->get("/$customer/boxs/:id")->to(controller => "$customer::boxs", ... ) }. Otherwise, have one route to dispatch them: $r->get('/:customer/boxs/:id')->to(cb => sub { my($c) = @_; ... handle $c->param('customer')}). If $customer is not a class name but a customer id, don't create a class for each customer.

– Corion
Jan 2 at 11:39















Thanks. You're right, there's not many customer, but I intend to design it with flexibility in mind, and Customer does need to be a class. The idea is, each customer has its own variant of box content handler, so by calling on an different url, the relevant Customer class will be correctly invoked. Anyways, I figured out to parse the url of a request with a 'before_depatch' hook, but the question is, where to store this? I still don't quite get how Mojo::Base Class work, so not sure how to correctly create custom attribute (without race condition)

– Terry Yang
Jan 2 at 20:55







Thanks. You're right, there's not many customer, but I intend to design it with flexibility in mind, and Customer does need to be a class. The idea is, each customer has its own variant of box content handler, so by calling on an different url, the relevant Customer class will be correctly invoked. Anyways, I figured out to parse the url of a request with a 'before_depatch' hook, but the question is, where to store this? I still don't quite get how Mojo::Base Class work, so not sure how to correctly create custom attribute (without race condition)

– Terry Yang
Jan 2 at 20:55















Anything that you want to store specific to that request tends to go in the stash: $c->stash(customer => $customer); ... my $customer = $c->stash('customer'); Just keep in mind the namespace is shared by both your route placeholders and reserved keys.

– Grinnz
Jan 10 at 23:37







Anything that you want to store specific to that request tends to go in the stash: $c->stash(customer => $customer); ... my $customer = $c->stash('customer'); Just keep in mind the namespace is shared by both your route placeholders and reserved keys.

– Grinnz
Jan 10 at 23:37















Note your hook will run at request time, whereas your routes are set up at app startup, so you can't use anything from the hook in your route setup (but you can use the stash in the resulting actions).

– Grinnz
Jan 10 at 23:39







Note your hook will run at request time, whereas your routes are set up at app startup, so you can't use anything from the hook in your route setup (but you can use the stash in the resulting actions).

– Grinnz
Jan 10 at 23:39














0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54004894%2fmojolicious-route-creation%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54004894%2fmojolicious-route-creation%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Monofisismo

Angular Downloading a file using contenturl with Basic Authentication

Olmecas