1CGI::Application::StrucUtsuerredC(o3n)tributed Perl DocuCmGeIn:t:aAtpipolnication::Structured(3)
2
3
4
6 CGI::Application::Structured - A medium-weight, MVC, DB web
7 micro-framework.
8
9 SYNOPSIS
10 A simple, medium-weight, MVC, DB web micro-framework built on
11 CGI::Application. The framework combines tested, well known plugins and
12 helper scripts to provide a rapid development environment.
13
14 The bundled plugins mix the following methods into your controller
15 runmodes:
16
17 $c->forward(runmode)
18
19 $c->redirect(url)
20
21 $c->tt_param(name=>value)
22
23 $c->tt_process()
24
25 $c->schema()->resultset("Things")->find($id)
26
27 $c->resultset("Things)->search({color=>"red"})
28
29 $c->log->info('This also works')
30
31 my $value = $c->session->param('key')
32
33 my $conf_val = $c->cfg('field');
34
35 my $select = $c->superform->select(
36 name => 'select',
37 default => 2,
38 values => [ 0, 1, 2, 3 ],
39 labels => {
40 0 => 'Zero',
41 1 => 'One',
42 2 => 'Two',
43 3 => 'Three'
44 }
45 );
46
47
48 sub method: Runmode {my $c = shift; do_something();}
49
50 $c->fill_form( \$template )
51
52 my $results = $ ->check_rm(
53 'form_display','_form_profile')
54 || return $c->check_rm_error_page;
55
57 I have taken to heart a recent comment by Mark Stosberg on the CGIApp
58 mailing list:
59
60 "Titanium is just one vision of what can be built on top of
61 CGI::Application. Someone else could easily combine their own
62 combination of CGI::Application and different favorite plugins,
63 and publish that with a different name."
64
65 CGI::Application::Structured, like Titanium, is an opinionated
66 framework, based on CGI::Application. Both frameworks includes a
67 number of vetted CGI-App plugins each of which are well documented and
68 tested. C::A::Structured, however takes the view that developer time
69 and consistent projects structures can often be more cost-effective
70 than focusing on the highest performance on low cost hosting solutions.
71 That being said, C::A::Structured can be deployed on CGI, FastCGI or
72 mod_perl based on your needs.
73
74 C::A::Structured focuses on:
75
76 · adequate performance under CGI, but with more focus speed of
77 development.
78
79 · a well-defined project structure with directories for model
80 classes, controllers and view templates.
81
82 · a powerful templating DSL via Template Toolkit integration.
83
84 · a integrated Object Relational Mapper, DBIx::Class
85
86 · no runmode configuration required.
87
88 · integrated form building to simplify creation of complex HTML form
89 elements.
90
91 · clean url-to-controller mapping by default.
92
93 C::A::Structured comes in two packages:
94
95 · CGI::Application::Strutured - encapsulates the runtime environment.
96
97 · CGI::Application::Structured::Tools - includes project creation and
98 developemt scripts for developers.
99
100 CGI::Application::Structured::Tools are used to generate a micro-
101 architecture and helper scripts that work within that structure to
102 speed development and maintain project structure across development
103 teams and projects. The helper scripts eliminate the tedium of error-
104 prone manual creation of controllers, templates and database mappings
105 and provide a recognizeable structural conventions that reduced stress
106 on the developer when working across multiple apps, or working with
107 other developers code on the same project.
108
109 The first script that is used is 'cas-starter.pl'. This script is used
110 to generate the initial project skeleton. The skeleton app contains a
111 base controller class rather than runnable module as would be found in
112 Titanium. Also generated is a default 'Home' controller subclass and a
113 URL dispatcher that is customized to default to the Home controllers
114 generated 'index' runmode.
115
116 cas-starter.pl also generates additional helper scripts in your
117 projects 'scripts' subdirectory:
118
119 · create_controller.pl
120
121 · create_dbic_schema.pl
122
123 'create_controller.pl' is used by the developer to generate additional
124 controller subclasses of your base module with a default 'index'
125 runmode and a default TT template for that runmode.
126
127 'create_dbic_schema.pl' generates a DBIx::Class::Schema subclass and a
128 set of resultset subclasses for your database. These Object Relational
129 Maps (ORM) will greatly simplify and speed database assess and
130 manipulation in the development process.
131
132 Finally CGI::Application::Structured aims to be as compatible as
133 possible with Catalyst. Many plugins used in
134 CGI::Application::Structured are also available for Catalyst, or are
135 even defaults in Catalyst. If your projects needs grow in scope or
136 scale to require Catalyst, porting much of your code will be very easy.
137
139 In this tutorial we will build a simplistic database driven web
140 application using CGI::Application::Structured to demonstrate using the
141 starter and helper scripts as well as the minimal required
142 configuration.
143
144 CGI::Application::Structured assumes that you have a database that you
145 want to use with the web. If you have a database you can use for this
146 tutorial. Otherwise, jump to the "Create The Example Database" section
147 at the bottom of this page before starting the tutorial.
148
149 Installation
150 You will need to install CGI::Application::Structured which provides
151 the runtime requirements. You will also need to install
152 CGI::Application::Structured::Tools which supplies the development
153 environment.
154
155 ~/dev$ sudo cpan
156 cpan> install CGI::Application::Structured
157 ... ok
158 cpan> install CGI::Application::Structured::Tools
159 ... ok
160 cpan> exit
161
162 Creating A Project
163 ~/dev$ cas-starter.pl --module=MyApp1 \
164 --author=gordon \
165 --email="vanamburg@cpan.org" \
166 --verbose
167 Created MyApp1
168 Created MyApp1/lib
169 Created MyApp1/lib/MyApp1.pm # YOUR *CONTROLLER BASE CLASS* !
170 Created MyApp1/t
171 Created MyApp1/t/pod-coverage.t
172 Created MyApp1/t/pod.t
173 Created MyApp1/t/01-load.t
174 Created MyApp1/t/test-app.t
175 Created MyApp1/t/perl-critic.t
176 Created MyApp1/t/boilerplate.t
177 Created MyApp1/t/00-signature.t
178 Created MyApp1/t/www
179 Created MyApp1/t/www/PUT.STATIC.CONTENT.HERE
180 Created MyApp1/templates/MyApp1/C/Home
181 Created MyApp1/templates/MyApp1/C/Home/index.tmpl # DEFAULT HOME PAGE TEMPLATE
182 Created MyApp1/Makefile.PL
183 Created MyApp1/Changes
184 Created MyApp1/README
185 Created MyApp1/MANIFEST.SKIP
186 Created MyApp1/t/perlcriticrc
187 Created MyApp1/lib/MyApp1/C # YOUR CONTROLLERS GO HERE
188 Created MyApp1/lib/MyApp1/C/Home.pm # YOUR *DEFAULT CONTROLLER SUBCLASS*
189 Created MyApp1/lib/MyApp1/Dispatch.pm # YOUR CUSTOM DISPATCHER
190 Created MyApp1/config
191 Created MyApp1/config/config-dev.pl # YOU CONFIG -- MUST BE EDITED BY YOU!
192 Created MyApp1/script
193 Created MyApp1/script/create_dbic_schema.pl # IMPORTANT HELPER SCRIPT
194 Created MyApp1/script/create_controller.pl # ANOTHER IMPORTANT HELPER SCRIPT.
195 Created MyApp1/server.pl # SERVER USES YOUR CUSTOM DISPATCH.PM
196 Created MyApp1/MANIFEST
197 Created starter directories and files
198
199 Configure Your Database
200 CGI::Application::Structured is database centric in some sense and
201 expects that you have a database. Before running your app via
202 server.pl you need to configure your database access.
203
204 The example config is generated at MyApp1/config/config.pl. The
205 contents are shown here.
206
207 use strict;
208 my %CFG;
209
210 $CFG{db_dsn} = "dbi:mysql:myapp_dev";
211 $CFG{db_user} = "root";
212 $CFG{db_pw} = "root";
213 $CFG{tt2_dir} = "templates";
214 return \%CFG;
215
216 Using the root account is shown here as a worst-practice. You should
217 customize the file supplying the correct database dsn, user and
218 passwords for your database.
219
220 If you do not have a database and want to use an example see "Create
221 Example Database" below before continuing.
222
223 The configuration file will be found automatically when running with
224 the built in server, but when you deploy your application you may want,
225 or need, to update the config file location in lib/MyApp1/Dispatch.pm
226 to point to your production config file.
227
228 For information on advanced configuration see:
229 CGI::Application::Plugin::ConfigAuto
230
231 Generate A DBIx::Class Schema For Your Database
232 From your project root directory run the helper script to generate
233 DBIx::Class::Schema and Resultset packages. This will use the
234 configuration you supplied in config_dev.pl to produce a DB.pm in your
235 apps lib/MAINMODULE directory
236
237 ~/dev/My-App1$ perl script/create_dbic_schema.pl
238 Dumping manual schema for DB to directory /home/gordon/dev/MyApp1/lib/MyApp1/DB ...
239 Schema dump completed.
240
241 Given the example database shown below your resulting DBIx::Class
242 related files and folders would look like this:
243
244 ~/dev/MyApp1$ find lib/MyApp1/ | grep DB
245 lib/MyApp1/DB
246 lib/MyApp1/DB/Result
247 lib/MyApp1/DB/Result/Orders.pm
248 lib/MyApp1/DB/Result/Customer.pm
249 lib/MyApp1/DB.pm
250
251 For more information see: CGI::Application::Plugin::DBIC::Schema,
252 DBIx::Class
253
254 Run Your App
255 Now that your database is configured and the schema generated you can
256 run your app.
257
258 Run the server:
259
260 ~/dev/MyApp1$ perl server.pl
261 access your default runmode at /cgi-bin/index.cgi
262 CGI::Application::Server: You can connect to your server at http://localhost:8060/
263
264 Open your browser and test at
265
266 http://localhost:8060/cgi-bin/index.cgi
267
268 For more information on the nature of the development server see:
269 CGI::Application::Server
270
271 Try Plugin::DebugScreen;
272 CAS comes with CGI::Application::Plugin::DebugScreen.
273 Plugin::DebugScreen provides a very useful stack trace with multi-line
274 source quotations for each level of the stack. cas-starter.pl has put
275 debug.sh in your project root directory. It sets up the environment
276 for Plugin::DebugPage and runs the built in server.
277
278 Edit lib/MyApp1/C/Home.pm to generate an error to demonstrate the
279 DebugScreen:
280
281 sub index: StartRunmode {
282 my ($c) = @_;
283
284 # add this line for demo of debug screen
285 die "testing";
286
287 $c->tt_params({
288 message => 'Hello world!',
289 title => 'C::Home'
290 });
291 return $c->tt_process();
292
293 }
294
295 Run the server in debug mode:
296
297 ~/dev/MyApp1$ bash debug.sh
298 access your default runmode at /cgi-bin/index.cgi
299 CGI::Application::Server: You can connect to your server at http://localhost:8060/
300
301 Open your browser and test/demo the Plugin::DebugScreen:
302
303 http://localhost:8060/cgi-bin/index.cgi
304
305 Remove the line you added to Home.pm
306
307 For more information on Plugin::DebugScreen see:
308 CGI::Application::Plugin::DebugScreen
309
310 Create A New Controller
311 This is where the create_controller.pl helper script comes in very
312 handy. create_controller.pl will create a new controller with a default
313 runmode called 'index', and an index template to go with it.
314
315 As an example we can generate a new module to interact with the Orders
316 table of the example database.
317
318 ~/dev/MyApp1$ perl script/create_controller.pl --name=Orders
319 will try to create lib/MyApp1/C
320 Created lib/MyApp1/C/Orders.pm
321 will try to create template directory templates/MyApp1/C/Orders
322 Created templates/MyApp1/C/Orders
323 Created templates/MyApp1/C/Orders/index.tmpl
324
325 You can restart server.pl and view default output at:
326
327 http://localhost:8060/cgi-bin/orders
328
329 Add a new runmode to lib/MyApp1/C/Orders.pm to show the orders that we
330 have from the example database.
331
332 sub list: Runmode{
333 my $c = shift;
334
335
336 my @orders = $c->resultset("MyApp1::DB::Result::Orders")->all;
337
338 $c->tt_params(orders =>\@orders);
339 return $c->tt_process();
340
341 }
342
343 Then add a template for this runmode at
344 templates/MyApp1/C/Orders/list.tmpl with the following content:
345
346 <h1>Order List</h1>
347 <table>
348 <tr><th>Cust No</th><th>Order No</th></tr>
349 [% FOREACH order = orders %]
350 <tr>
351 <td>[% order.customer_id %]</td>
352 <td>[% order.id %]</td>
353 </tr>
354 [% END %]
355 </table>
356
357 Restart server.pl and visit page to see list of orders at:
358
359 http://localhost:8060/cgi-bin/orders/list
360
361 For advanced information on creating controllers, runmodes and
362 templates see: CGI::Application::Plugin::AutoRunmode,
363 CGI::Application::Plugin::TT, CGI::Application and Template::Toolkit.
364
365 Creating The Example Database (if you don't already have one)
366 The CGI::Application::Structured distrubution contains an example sql
367 file that you can use for this example app. Use the download link at
368 CGI::Application::Structured on CPAN, grab the archive and extract the
369 file from the 'examples' directory of the distribution.
370
371 The script will create the 'myapp1_dev' database, create 2 tables and
372 load a few Notice that the create table statements end with
373 'engine=InnoDB'. This is important since our DBIC generator script
374 will create perl modules to represent database table relationships,
375 based on the metadata in the database. While the InnoDB engine will
376 work, the default engine for mysql will not store the relationship
377 metadata and you would then need to hand-craft the relationships at the
378 botton of the generated DB::Result classes.
379
380 Example:
381
382 ~/dev/MyApp1$ mysql -u root -p < example_tables.mysql.ddl
383
384 The contents of the example sql file are as follows:
385
386 CREATE DATABASE myapp1_dev;
387 USE myapp1_dev;
388
389 CREATE TABLE customer(
390 id integer not null auto_increment PRIMARY KEY,
391 last_name varchar(25) null,
392 first_name varchar(25) not null
393 )engine=InnoDB;
394
395 CREATE TABLE orders(
396 id integer not null auto_increment PRIMARY KEY,
397 customer_id integer not null,
398 order_status varchar(10) default "OPEN" not null,
399 order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP not null,
400 CONSTRAINT orders_customer_id_fk FOREIGN KEY (customer_id) REFERENCES customer(id)
401 )engine=InnoDB;
402
403 INSERT INTO customer (last_name, first_name) VALUES("Doe","John");
404 INSERT INTO orders (customer_id) VALUES( 1 );
405 INSERT INTO orders (customer_id) VALUES( 1 );
406 INSERT INTO orders (customer_id) VALUES( 1 );
407
408 If you did not use 'engine=InnoDB' or your database does not support
409 relationships, you can paste the following in the bottom of your
410 "MyApp/DB/Result/Orders.pm" to tell DBIx::Class how the example tables
411 relate:
412
413 # Created by DBIx::Class::Schema::Loader v0.04006 @ 2009-09-15 16:05:33
414 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:znOKfDkdRzpL0KHWpfpJ+Q
415
416 __PACKAGE__->belongs_to(
417 "customer",
418 "MyApp1::DB::Result::Customer",
419 { id => "customer" },
420 );
421
422 See documentation for DBIx::Class::Manual for more information on
423 configuring and using relationships in your model.
424
426 See CGI::Application::Structured::Tools for more information on
427 developer tools package.
428
429 See CGI::Application::Plugin::DBIC::Schema for more information on
430 accessing DBIx::Class from your CGI::Application::Structured modules.
431
432 See CGI::Application::Plugin::SuperForm for form building support that
433 is build into CGI::Application::Structured.
434
435 See DBIx::Class::Manual::Intro for more information on using the
436 powerful ORM included with CGI::Application::Structured.
437
438 See Template::Toolkit and CGI::Application::Plugin::TT for more
439 information on advanced templating.
440
441 See CGI::Application for lots of good ideas and examples that will work
442 with your CGI::Application::Structured app.
443
445 There are no known bugs for this distribution.
446
447 Please report any bugs or feature requests through the web interface at
448 <https://rt.cpan.org>.
449
450 I will be notified, and then you'll automatically be notified of
451 progress on your bug as I make changes.
452
454 I recommend joining the cgi-application mailing list.
455
457 Gordon Van Amburg
458 CPAN ID: VANAMBURG
459 vanamburg at cpan.org
460
462 This program is free software; you can redistribute it and/or modify it
463 under the same terms as Perl itself.
464
465 The full text of the license can be found in the LICENSE file included
466 with this module.
467
468
469
470perl v5.32.0 2020-07-28 CGI::Application::Structured(3)