Embedding Perl in HTML with Mason Chapter 8: Building a Mason Site-P3

Chia sẻ: Thanh Cong | Ngày: | Loại File: PDF | Số trang:26

0
53
lượt xem
8
download

Embedding Perl in HTML with Mason Chapter 8: Building a Mason Site-P3

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Tham khảo tài liệu 'embedding perl in html with mason chapter 8: building a mason site-p3', công nghệ thông tin, kỹ thuật lập trình phục vụ nhu cầu học tập, nghiên cứu và làm việc hiệu quả

Chủ đề:
Lưu

Nội dung Text: Embedding Perl in HTML with Mason Chapter 8: Building a Mason Site-P3

  1. Chapter 8: Building a Mason Site-P3 • all_projects.html This component actually delegates most of its work to the /search_results.mas component. All this component does is create a cursor representing the rows of interest for this query. In this case, the query is simply 'all projects' . We take advantage of the limit and offset features of MySQL in order to select only those rows we are interested in. As we shall see in a moment, the /search_results.mas component displays paged results, 20 per page. In addition, this component needs to get a count of how many rows this query would get without the limit. It also creates a textual description of the search it is doing so that this can be displayed to the user. The $start and $limit arguments are part of the r esults paging system, and any component that implements a search query must accept them in order for the paging system to work. $count, projects => $projects, summary => $summary, start => $start, limit => $limit, %ARGS
  2. &> $start => 0 $limit => 20 my $summary = 'all projects'; my $count = $Schema->Project_t->row_count; my $projects = $Schema->Project_t->all_rows ( order_by => [ $Schema->Project_t->creation_date_c, 'desc', $Schema->Project_t->name_c, 'asc' ], limit => [ $limit, $start ], ); - All projects
  3. • /search_results.mas This is where the actual work of displaying results is done. This component is currently used by just two other components, but it is designed so that if we add more search options, such as a keyword search, it can handle those as well. This component takes the $summary and $count arguments and uses them to tell the user what kind of search he just did (in case he forgot) and how many results there were in total. If there are more results than can be shown on one page, it calls the /lib/paging_controls.mas component to do the work of generating links to all the other pages of results. Finally, if there were results, it loops through the cursor and displays information about each project in turn. Search Results
  4. You searched for . There result. % if ($count > $limit) { % } % if ($count) { Name Created on Difficulty Project status % while (my $project = $projects->next) {
  5. name | h %> $project- >creation_date &> difficulty %> status %> % } % } $count $projects $summary $start $limit • /lib/paging_controls.mas
  6. Generating paged search results is a common need in web applications. If you have a database of hundreds, thousands, or more searchable items, you need a way to handle large result sets. The usual way to do this is to break the results into multiple pages, showing a certain number per page with links to other pages. This component generates the links to the others pages, which look something like this: > The "" link moves one page forward. The page the user is currently viewing is marked with bold text instead of being a link. If the user is on the first or last page, the previous or next page links are not shown. This is all fine until you have something like 100 pages. At that point you need another level of navigation, so we will end up with something like this: ... > ... The first "..." link will move back to the last page of the previous group of 10, in this case page 20. The end "..." link will move to the beginning of the next group of 10, in this case, page 31. This design is capable of handling a large number of pages gracefully, although if you anticipated that you would often be generating result sets consisting of thousands of items, you might want to add additional navigation links that allowed the user to jump forward and backward in larger chunks.
  7. One interesting aspect of this component is how it generates its links. Instead of requiring that a URL be passed in to the component, we use the Apache request object's uri() method to determine the current URL. To find out what arguments were passed to the page, we use the $m- >request_args() method. We do this because we just want to reproduce the arguments passed in by the client, not any generated by component calls earlier in the call stack. We delete the limit and start arguments since we will be overriding them for each link. Displaying results - . % if ( $previous_tenth >= 10 ) {
  8. %query } &>">... % } else {   % } % if ( $current_page > 1 ) { << % } % foreach my $page ( ($previous_tenth + 1)..($next_tenth - 1) ) { % if ( $page
  9. % } else { % } % } else { &nbsp; % } % } % if ( $current_page < $total_pages ) {
  10. %query } &>">&gt;&gt; % } else { &nbsp; % } % if ( $next_tenth ... % } else { &nbsp; % }
  11. $start $limit $count my %query = $m->request_args; delete @query{ 'start', 'limit' }; my $total_pages = int( $count / $limit ); $total_pages++ if $count % $limit; my $current_page = ( $start / $limit ) + 1; my $previous_tenth = $current_page - ( $current_page % $limit ? $current_page % $limit : $limit ); my $next_tenth = $previous_tenth + 11; my $last_shown = $start + $limit > $count ? $count : $start + $limit;
  12. • /browse.html This page simply iterates through all the different project categories. If a category has projects, then we generate a link to browse that category. Browse by Category % while (my $category = $categories->next) { % if (my $count = $category->project_count) { name | h %> ( project 1 ? 's' : '' %>) % } else { name | h %> (No projects)
  13. % } % } my $categories = $Schema->Category_t->all_rows( order_by => $Schema->Category_t->name_c ); - Browse by category • /show_category.html This is what /browse.html links to for each category. This code is quite similar to what we saw in /all_projects.html and uses the same component, /search_results.mas, to do all the real work. One feature new to this component is that the title method dynamically adds the category name to the page title. We used a section here in order to avoid creating the same category object twice. If the category ID we are given is invalid, then we simply redirect the user back to the home page. It's lazy but it's better than simply showing an error message.
  14. count => $count, projects => $projects, summary => $summary, start => $start, limit => $limit, %ARGS &> my $category = eval { $Schema->Category_t->row_by_pk ( pk => $m->request_args- >{category_id} ) } || $m->comp( '/lib/redirect.mas', path => '/' ); $start => 0 $limit => 20 $category_id
  15. my $summary = 'projects in the "' . $category- >name . '" category'; my $count = $category->project_count; my $projects = $Schema->join( select => $Schema->Project_t, join => [ $Schema->tables( 'Project', 'ProjectCategory' ) ], where => [ $Schema->ProjectCategory_t- >category_id_c, '=', $category_id ], order_by => [ $Schema->Project_t- >creation_date_c, 'desc', $Schema->Project_t->name_c, 'asc' ], limit => [ $limit, $start ], );
  16. - name | h %> projects • /user.html This is our user info display component. There's not much here that we haven't seen before. Make some objects, display some information from the objects. Been there, done that. Note that this isn't actually duplicating code from other components, though. It's just similar to them. • /project/dhandler This component is quite similar to the /user.html component but instead of being called with a query string, is called with a URL like /project/77.html, where 77 is the project ID. Using a dhandler here was an arbitrary choice, but it lets us have nice, search-engine-friendly URLs. name | h %>
  17. Created: $project->creation_date &> description, paras => 1 ) %> Categor 1 ? 'ies' : 'y' %>: Project status: status | h %>
  18. Support level: support_level | h %> Members % while (my $user = $members->next) { username | h %> % if ($project->user_is_admin($user)) { Admin % } else { &nbsp; % }
  19. % } % if ( $Schema->ProjectLink_t->row_count % ( where => [ $Schema->ProjectLink_t- >project_id_c, '=', $project_id ] ) ) { &nbsp; Links % while (my $link = $links->next) { description | h %> % } % } % if ($User->is_admin || $User- >is_project_admin($project)) {
  20. &nbsp; Edit this project % } my ($project_id) = $m->dhandler_arg =~ /(\d+).html/; my $project = eval { $Schema->Project_t- >row_by_pk( pk => $project_id ) } || $m->comp( '/lib/redirect.mas', path => '/' );
Đồng bộ tài khoản