Development

/plugins/sfPropel15Plugin/trunk/doc/admin_generator.txt

You must first sign up to be able to contribute.

root/plugins/sfPropel15Plugin/trunk/doc/admin_generator.txt

Revision 29247, 10.6 kB (checked in by francois, 4 years ago)

[sfPropel15PLugin] Added the ability to use "plain" type for form fields, just like in symfony 1.2

  • Property svn:executable set to *
Line 
1 Admin Generator Extensions
2 ==========================
3
4 sfPropel15Plugin comes bundled with a new admin generator theme named 'admin15'. This theme provides additional features based on the new Propel 1.5 query objects, and is backwards compatible with sfPropelPlugin's admin generator theme.
5
6 To enable this theme, edit your `generator.yml` and change the `theme` property from `admin` to `admin15`, as follows:
7
8     [yaml]
9     generator:
10       class: sfPropelGenerator
11       param:
12         model_class:           Book
13         theme:                 admin15
14         non_verbose_templates: true
15         with_show:             false
16         singular:              Book
17         plural:                Books
18         route_prefix:          book
19         with_propel_route:     1
20         actions_base_class:    sfActions
21
22 You can now use the additional features listed below.
23
24 Hydrating Related Objects
25 -------------------------
26
27 The `admin15` theme doesn't use the Peer classes anymore, therefore settings referencing the Peer classes are ignored in this theme. This includes `peer_method`, and `peer_count_method`. The new theme provides a simple alternative for these settings, called `with`. Add each of the objects to hydrate together with the main object in the `with` setting list:
28
29     [yaml]
30     list:
31       display: [title, Author]
32       with: [Author]
33
34 The admin generator will then execute the following query to display the list, effectively executing a single query instead of 1+n queries:
35
36     [php]
37     $books = BookQuery::create()
38       ->joinWithAuthor()
39       ->paginate();
40
41 Of course, you can add as many `with` names as you want, to hydrate multiple objects:
42
43     [yaml]
44     list:
45       display: [title, Author, Publisher]
46       with:    [Author, Publisher]
47
48 **Tip**: Before adding relations to the `with` setting, check that you don't already have a filter on the foreign key column that already makes the query to list all the related objects. If it's the case, then Propel's Instance Pooling will make the `with` superfluous, as each call to a related object will not trigger an additional query anyway.
49
50 Additional Query Methods
51 ------------------------
52
53 You can execute additional query methods in the list by setting the `query_methods` parameter. For instance, in a list of `Books`, to limit the list of published books, setup your `list` view as follows:
54
55     [yaml]
56     list:
57       display:       [title]
58       query_methods: [filterByAlreadyPublished]
59
60 The admin generator will then execute the following query to display the list:
61
62     [php]
63     $books = BookQuery::create()
64       ->filterByAlreadyPublished()
65       ->paginate();
66
67 You must implement each `query_method` in the main object's query class. In this exemple, here is how you can implement `Bookquery::filterByAlreadyPublished()`:
68
69     [php]
70     class BookQuery extends BaseBookQuery
71     {
72       public function filterByAlreadyPublished()
73       {
74         return $this->filterByPublishedAt(array('min' => time()));
75       }
76     }
77    
78 You can use this feature to add calculated columns to the list without additional queries:
79
80     [yaml]
81     list:
82       display:       [title]
83       query_methods: [withNbReviews]
84
85 For this to work, add the following method to the query class:
86
87     [php]
88     class BookQuery extends BaseBookQuery
89     {
90       public function withNbReviews()
91       {
92         return $this
93           ->leftJoin('Book.Review')
94           ->withColumn('COUNT(Review.Id)', 'NbReviews');
95       }
96     }
97
98 Now you can add a partial column and use the virtual `NbReviews` column in the list:
99
100     [php]
101     <?php echo $book->getVirtualColumn('NbReviews') ?>
102
103 Sorting On A Virtual Column
104 ---------------------------
105
106 The new theme provides an easy way to make virtual columns and foreign key columns sortable in the list view. Just declare the corresponding fields with `is_sortable` to `true`, and the generated module will look for an `orderByXXX()` method in the generated query. For instance, to allow a book list to be sortable on the author name:
107
108     [yaml]
109     # in generator.yml
110     list:
111       display:       [title, Author]
112       query_methods: [joinWithAuthor]
113       fields:
114         - Author:    { is_sortable: true }
115
116 Then the generator will try to execute `BookQuery::orderByAuthor()` whenever the user clicks on the `Author` header to sort on this column. The method must be implemented as follows:
117
118     [php]
119     class BookQuery extends BaseBookQuery
120     {
121       public function orderByAuthor($order = Criteria::ASC)
122       {
123         return $this
124           ->useAuthorQuery()
125             ->orderByLastName($order)
126           ->endUse();
127       }
128     }
129
130 You can override the default sorting method name for a field by setting the `sort_method` parameter:
131
132     [yaml]
133     # in generator.yml
134     list:
135       display:       [title, Author]
136       query_methods: [joinWithAuthor]
137       fields:
138         - Author:    { is_sortable: true, sort_method: orderByAuthorLastName }
139        
140 The generator will execute `BookQuery::orderByAuthorLastName()` instead of `BookQuery::orderByAuthor()` in that case.
141
142 Filtering The List With GET Parameters
143 --------------------------------------
144
145 The admin generator doesn't allow to filter the list using GET parameters. This neat feature used to be supported in previous versions of the generator, and is supported again in the `admin15` theme.
146
147 All you have to do to filter a list view is to prepend a query string to the URL, describing the filters in a `filters` array. For instance, to link to the book list view filtered by Author, try the following link:
148
149     [php]
150     <?php echo link_to($author->getName(), 'book', array(), array('query_string' => 'filters[author_id]=' . $author->getId())) ?>
151
152 This is very useful for partial lists, to link admin modules together.
153
154 Cross-Linking Admin Modules
155 ---------------------------
156
157 In lists, related object columns often have to link to another admin generator module. For instance, in a list of `Books`, a column showing the `Author` name usually needs to link to the `edit` view in the `author` module for the current book author. You can implement this feature using a partial column:
158
159     [yaml]
160     # in generator.yml
161     list:
162       display: [title, _author]
163
164 The partial column code is a one-liner, but it's quite tedious to repeat it many times:
165
166     [php]
167     // in modules/book/templates/_author.php
168     <?php echo link_to($book->getAuthor(), 'author_edit', $book->getAuthor) ?>
169
170 The `admin15` theme provides a shortcut for this situation. Just define the `link_module` setting in the `Author` field configuration to point the `author` module, and you're good to go:
171
172     [yaml]
173     # in generator.yml
174     list:
175       display:  [title, Author]
176       fields:
177         Author: { link_module: author }
178        
179 You no longer need a partial for such simple cases. This should unclutter the `templates/` directory of your admin generator modules.
180
181 Easy Custom Filter
182 ------------------
183
184 Adding custom filters becomes very easy once you can take advantage of the generated Propel query classes. For example, in a list of `Books`, the default filters offer one text input for the book title, and a second one for the book ISBN. In order to replace them with a single text input, here is what you need to do:
185
186     [php]   
187     // in lib/filter/BookFormFilter.php
188     class BookFormFilter extends BaseBookFormFilter
189     {
190       public function configure()
191       {
192         $this->widgetSchema['full_text'] = new sfWidgetFormFilterInput(array('with_empty' => false));
193         $this->validatorSchema['full_text'] = new sfValidatorPass(array('required' => false));
194       }
195     }
196    
197     // in lib/model/Bookquery.php
198     class BookQuery extends BaseBookQuery
199     {
200       public function filterByFullText($value)
201       {
202         if (isset($value['text'])) {
203           $pattern = '%' . $value['text'] . '%';
204           $this
205             ->condition('condTitle', 'Book.Title LIKE ?', $pattern)
206             ->condition('condISBN', 'Book.ISBN LIKE ?', $pattern)
207             ->combine(array('condTitle', 'condISBN'), Criteria::LOGICAL_OR);
208         }
209         return $this;
210       }
211     }
212
213 Now just modify the `filter.display` setting in the `generator.yml` to remove the `title` and `isbn` filters, and replace them with the new `full_text` filter:
214
215     [yaml]
216     # in modules/book/config/generator.yml
217     config:
218       filter:
219         display: [full_text]
220
221 The amdin generator looks for a `filterByXXX()` method in the query class, where `XXX` is the CamelCase version of the custom filter you add.
222
223 YAML Form Customization
224 -----------------------
225
226 You can now modify, add or remove widgets and validators directly from within the `generator.yml`, for all generator forms. That means you no longer need to edit a form object for basic widget customization.
227
228 This is made possible by five new field attributes that you can customize: `widgetClass`, `widgetOptions`, `validatorClass`, `validatorOptions`, and `validatorMessages`. Of course, you can still modify the HTML attributes of a widget by setting the `attributes` attribute.
229
230 **Tip**: You can also safely omit one of the form fields in the `display` list. The `admin15` generator theme takes care of unsetting the field in the form for you.
231
232 For instance, to replace an input filter on a text column by a choice list, try the following:
233
234     [php]
235     filter:
236       fields:
237         sex:
238           widgetClass:   sfWidgetFormChoice
239           widgetOptions: { choices: { '': '' , male: Male, female: Female } }
240
241 To remove the "is empty" checkbox for a given filter, just set the relevant widget option in YAML:
242
243     [php]
244     filter:
245       fields:
246         title:
247           widgetOptions: { with_empty: false }
248
249 To replace a text input by a textarea in the edit form, change the widget class:
250
251     [php]
252     form:
253       fields:
254         body:
255           widgetClass:   sfWidgetFormTextarea
256
257 The configuration cascade works as usual for these attributes, so a field customization defined under the `form` key affects both the `new` and `edit` forms, and a field customization defined under the main `field` key affects all forms, including the filter form.
258
259 Plain fields
260 ------------
261
262 If you want to display some data in a form without allowing the user to edit it, use the `type: plain` attribute, just like in the old days of symfony 1.2. This is very useful for columns managed by the model, like `created_at` and `updated_at` columns:
263
264     [yaml]
265     # in modules/book/config/generator.yml
266     config:
267       edit:
268         display:      [title, author_id, created_at, updated_at]
269         fields:
270           created_at: { type: plain }
271           updated_at: { type: plain }
272
273 This displays the field in the edit view, but not in a form input. Submitting the form will leave these fields unchanged - or, in the previous example, will let the model take care of their values.
Note: See TracBrowser for help on using the browser.