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