the URL '/user/1' should dynamically point and rewrite to '/user/John-H' in the browser address bar

By this I'm assuming you mean redirect?

and in link mouseover on the page

This is a little bit unclear: if you're generating the pages yourself, then it would be easiest to just insert the correct link in the first place, like I did in the code below. Otherwise, if your HTML really contains a link like <a href="/user/1"> and you want it to appear differently on mouseover, you'll have to solve that with JavaScript.

I have mapped id to value in the 'users' cache.

This seems a bit strange: a Mojo::Cache, being a cache, is transient, so I assume you're not actually using that as your data store in your actual application (and if you are, you shouldn't). You may have oversimplified your question a bit, since it's unclear what data source you're getting user IDs and names from, like a database? Anyway, I've just used a dummy.

restrict the value of id to be an even number and less than 10.

That's done simply enough with a regex of [02468], but since I suspect in your actual application you probably don't want to limit it to numbers below 10, in the following code I just limited it to any even integer.

Also note that your description is not self-consistent. You want /user/1 to rewrite to /user/John-H, but you also want to restrict IDs to even numbers. It's also unclear if/how you want to map 'John H' to 'John-H' and back, and how you want to handle '/user/NonexistentUser'.

Anyway, here's my best guess:

#!/usr/bin/perl use Mojolicious::Lite -signatures; helper users => sub ($c) { # probably a database in reality? state $users => { 2 => 'John H', 4 => 'Sam A', } }; get '/' => sub ($c) { $c->render(template => 'index') } => 'index'; get '/user/:id' => [id => qr/\d*[02468]/] => sub ($c) { my $id = $c->param('id'); if ( exists app->users->{$id} ) { $c->redirect_to('user_by_name', name=>app->users->{$id} ) } else { $c->reply->not_found } } => 'user_by_id'; get '/user/:name' => sub ($c) { # a very inefficient grep here, don't use this in production!! if ( grep { $_ eq $c->param('name') } values app->users->%* ) { $c->render( template=>'user' ) } else { $c->reply->not_found } } => 'user_by_name'; app->start; __DATA__ @@ layouts/main.html.ep <!DOCTYPE html> <html> <head><title><%= title %></title></head> <body> %= content </body> </html> @@ index.html.ep % layout 'main', title => 'Hello, World!'; <p>User List</p> <ul> % for my $id (sort {$a<=>$b} keys users->%*) { <li> %= link_to "User ID $id" => user_by_id => { id => $id } %= link_to users->{$id} => user_by_name=>{name=>users->{$id}} </li> % } </ul> @@ user.html.ep % layout 'main', title => 'User page'; <p>This is <%= $name %>'s Page</p> %= link_to Home => 'index';

Tests:

use Mojo::Base -strict, -signatures; use Test::Mojo; use Test::More; use Mojo::File; use Mojo::Util qw/url_escape/; my $t = Test::Mojo->new( Mojo::File->new('/path/to/app.pl') ); $t->get_ok('/')->status_is(200)->content_like(qr/\bUser List\b/); $t->get_ok('/user/1')->status_is(404); $t->get_ok('/user/2') ->header_is(location => '/user/' . url_escape 'John H'); $t->get_ok('/user/3')->status_is(404); $t->get_ok('/user/4') ->header_is(location => '/user/' . url_escape 'Sam A'); $t->get_ok('/user/5')->status_is(404); $t->get_ok('/user/6')->status_is(404); $t->get_ok('/user/2/') # trailing slash ->header_is(location => '/user/' . url_escape 'John H'); $t->get_ok('/user/John H')->status_is(200) ->content_like(qr/\bThis is John H's Page\b/); $t->get_ok('/user/Sam A')->status_is(200) ->content_like(qr/\bThis is Sam A's Page\b/); $t->get_ok('/user/John Doe')->status_is(404); done_testing;

Minor typo fixes in text.


In reply to Re: Mojolicious url rewriting by haukex
in thread Mojolicious url rewriting by rajaman

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.