Commit | Line | Data |
d325256f |
1 | |
2 | =head1 Page rendering |
3 | |
4 | =head2 Or, how to track why your page failed to render |
5 | |
0fd7c39d |
6 | Catalyst's C<begin> and C<end> actions are supplied by |
7 | L<Reaction::UI::Controller::Root>, which your C<Root> controller should inherit |
8 | from, or at least the root controller of the part of your application that is |
9 | using Reaction. |
10 | |
11 | The C<begin> action creates a new L<Reaction::UI::Window> and stores it in $c->stash->{window}. |
12 | The C<end> action calls the flush() method on the stashed window object. |
13 | L<Reaction::UI::Window/flush> then calls L<Reaction::UI::View/render_window> |
14 | on the window's view. |
d325256f |
15 | |
16 | The View first fetches the root ViewPort from the Window's stack and |
b6c6aad4 |
17 | creates a RenderingContext. The layout is chosen based on the ViewPort name or |
18 | though the ViewPort's C<layout> attribute. The Widget is then used to render the |
19 | content via the RenderingContext. |
d325256f |
20 | |
0fd7c39d |
21 | Is your head spinning yet? |
22 | |
d325256f |
23 | Ingredients used: |
0fd7c39d |
24 | |
d325256f |
25 | * A Reaction::UI::Skin object built from: |
0fd7c39d |
26 | |
27 | - The skin_name set on your View |
28 | - The View object |
29 | - The skin_base_dir (MyApp/share/skin) |
30 | - The share/skin/defaults.conf + share/skin/<my_skin>/skin.conf |
31 | |
d325256f |
32 | * A Reaction::UI::LayoutSet object built from: |
0fd7c39d |
33 | |
34 | - The layoutset file itself, found in the share/skin/<my_skin>/layout directory |
35 | or the share/skin/default/layout directory. |
36 | - The Skin object |
37 | |
d325256f |
38 | * A Reaction::UI::Widget object built from: |
0fd7c39d |
39 | |
40 | - It's class, determined from the name of the ViewPort or read from the |
41 | layoutset file, and found in the widget_search_path. |
42 | - The View object |
43 | - The LayoutSet object |
44 | |
d325256f |
45 | * A Reaction::UI::RenderingContext::TT object built from: |
0fd7c39d |
46 | |
47 | - Nothing |
d325256f |
48 | |
49 | To render the window the correct Reaction::UI::Widget object is |
50 | retrieved via the LayoutSet for the root ViewPort of the page. |
51 | |
52 | The LayoutSet used defaults to the "layout" attribute on the |
53 | ViewPort. If there is no layout attribute value set, it takes the |
54 | class name of the ViewPort, extracts the parts following |
55 | "::ViewPort::" and constructs the layoutset name from converting camel |
56 | cased parts of the namespace to lower-case underscored, and namespace |
57 | parts into directories. |
58 | |
59 | ## eg: |
60 | My::ViewPort::Action::UserForm |
61 | ## becomes |
62 | action/user_form |
63 | |
64 | The layoutset file should exist in the skin_base_dir, in the "layout" |
65 | directory under the "skin_name" dir set in your View config, or in the |
66 | "default/layout" directory. [[ A LayoutSet object is created based on |
67 | the layoutset name, skin object, source_file (path to file), top_skin |
68 | (skin object), next_skin if exists ]]. |
69 | |
70 | The layoutset file is parsed as the LayoutSet object is created, if a |
71 | "=widget" line is found, the "widget_type" attribute is set. |
72 | |
73 | The class of the Widget object can be set in the layoutset object |
74 | args, or it defaults to being fetched via the Skin. The type of widget |
75 | is either specified in the layoutset file via the "=widget" directive |
76 | or retrieved by recreating the camelcased name from the layoutset |
77 | name. The Widget is assumed to be in the widget search path provided |
78 | by defaults.conf or your skin.conf. |
79 | |
80 | The Widget itself is passed the ViewPort to render, and the |
81 | RenderingContext. The initial fragment name to render is also passed, |
82 | "widget". |
83 | |
84 | The render stack is created using the widget order. The widget order |
85 | is fetched for the fragment from the layoutset, this is either the |
86 | widget class/layoutset, or retrieved from the extended layouts. As the |
87 | render_stack is built, the fragment methods in the Widget are called |
88 | to assign values from the ViewPort to arguments for the layout. (Or |
89 | other interesting things). |
90 | |
91 | The stack is passed to the RenderingContext to complete. |