File Coverage

examples/single-file-apps/form-app.psgi
Criterion Covered Total %
statement 19 19 100.0
branch n/a
condition n/a
subroutine 5 5 100.0
pod n/a
total 24 24 100.0


line stmt bran cond sub pod time code
1             #!perl
2 1     1   1815 use v5.36;
  1         6  
3              
4             #######################################################################
5             # Main module
6              
7             package PXF::Example::FormApp {
8 1     1   8 use PlackX::Framework;
  1         3  
  1         9  
9             }
10              
11             #######################################################################
12             # Set up routes using Router DSL
13              
14             package PXF::Example::FormApp::Routes {
15 1     1   8 use PXF::Example::FormApp::Router;
  1         2  
  1         10  
16              
17             our $counter = 0;
18              
19             my $app_name = 'My Example App';
20             my %credentials = (username => 'larry', password => 'perl');
21              
22             my $style = <<~INDENTED_HEREDOC;
23             body {
24             color: #333; font-family: Tahoma, Sans-serif;
25             margin: 1em;
26             }
27             form {
28             border: 1px solid #ddd;
29             padding: 1em;
30             }
31             form label {
32             display: block;
33             }
34             form input {
35             display: block;
36             margin-top: 0.25em;
37             margin-bottom: 0.75em;
38             }
39             INDENTED_HEREDOC
40              
41             # Filters, a bad way to to do templating
42             filter before => sub ($request, $response) {
43             my $title = __PACKAGE__;
44             $response->print(qq{
45            
46            
47            
48             $title
49            
50            
51            
52             });
53             return;
54             };
55              
56             filter after => sub ($request, $response) {
57             $response->print("\n");
58             return;
59             };
60              
61             # Demonstrate a global filter - add signature
62             global_filter after => sub ($request, $response) {
63             return unless $response->content_type =~ m|text/html|;
64             $response->print("\n\n\n");
65             return; # return nothing to continue
66             };
67              
68             # Root request
69             route '/' => sub ($request, $response) {
70             $response->print(qq{
71            

$app_name

72            

Please Log In to continue.

73             });
74             return $response;
75             };
76              
77             # Different route
78             route '/login' => sub ($request, $response) {
79             my $message = $request->stash->{'message'} || 'Enter your credentials below.';
80             my $want_method = $request->param('method') // 'post';
81             $response->print(qq{
82            

$app_name: Log In

83            

$message

84            
85            
86            
87            
88            
89             });
90             return $response;
91             };
92              
93             # Demonstrate HTTP request method
94             route { post => ['/login-submit','/login/submit'] } => sub ($request, $response) {
95             my $username = $request->param('username');
96             my $password = $request->param('password');
97              
98             unless ($username eq $credentials{'username'} and $password eq $credentials{'password'}) {
99             # Here we show the login page again with the "reroute" feature.
100             # We could also use the flash_redirect feature instead.
101             $request->stash->{'message'} = "Incorrect username ($username) or password ($password).";
102             return $request->reroute('/login');
103             }
104              
105             $response->print(qq{
106            

$app_name

107            

Welcome back, $username.

108             });
109              
110             return $response;
111             };
112              
113             route { get => '/login/submit' } => sub ($request, $response) {
114             $response->status(405);
115             $response->print(qq{
116            

Method Not Allowed

117            

You cannot login with a GET request. Please try again.

118             });
119             return $response;
120             };
121              
122             # Demonstrate a callback (cleanup handler)
123             route '/callback' => sub ($request, $response) {
124             my $supports_cleanup = $request->env->{'psgix.cleanup'};
125              
126             $response->add_cleanup_callback(sub ($env) {
127             say "Cleanup callback: sleeping for 1 second...";
128             say "(server does not support cleanup callbacks, so this will cause blocking...)" unless $supports_cleanup;
129             sleep 1;
130             $counter++;
131             });
132             $response->print(qq{
133            

Cleanup Callback Example

134            

Callback added. Request $request, response $response.

135             });
136             $response->print("Server does NOT support cleanup!") unless $supports_cleanup.
137             return $response;
138             };
139              
140             # Demonstrate flash
141             route '/flash/set/:message' => sub ($request, $response) {
142             $response->flash($request->route_param('message'));
143             $response->redirect('/flash/view');
144             return $response;
145             };
146              
147             route '/flash/view' => sub ($request, $response) {
148             $response->print('Flash message shown below!');
149             $response->print('If you refresh the page, it will disappear.');
150             $response->print($request->flash);
151             return $response;
152             };
153             }
154              
155             #######################################################################
156             # Routing without DSL
157              
158             package PXF::Example::FormApp::Routes::NonDSL {
159 1     1   10 use PXF::Example::FormApp::Router ();
  1         3  
  1         159  
160              
161             # Add routes (actions can be coderefs or names of functions as strings)
162             PXF::Example::FormApp::Router->add_route('/page/{pagenum:\d+}/view' => 'page_nondsl');
163              
164             # Route actions
165 1     1   3 sub page_nondsl ($request, $response) {
  1         3  
  1         4  
  1         2  
166 1         6 my $page = $request->route_param('pagenum');
167 1         7 $response->print('

No DSL Example

');
168 1         5 $response->print("You are viewing page $page.
\n");
169 1         4 return $response;
170             }
171             }
172              
173             #######################################################################
174             # Return the application coderef
175              
176             PXF::Example::FormApp->app;