|
| 1 | +Conventions |
| 2 | +=========== |
| 3 | + |
| 4 | +By default the **Cake Toolkit** follows all of the [conventions](http://book.cakephp.org/2.0/en/getting-started/cakephp-conventions.html) and [standards](http://book.cakephp.org/2.0/en/contributing/cakephp-coding-conventions.html) already defined in *CakePHP*. However, it introduces some additional conventions for the new features it provides. |
| 5 | + |
| 6 | +Naming |
| 7 | +------ |
| 8 | + |
| 9 | +Controllers follow the existing conventions, however, as Views are now *PHP* classes, they adopt the common naming format for class files in *CakePHP*, for example: |
| 10 | + |
| 11 | +``` |
| 12 | +app/View/Products/Ctk/IndexView.php |
| 13 | +``` |
| 14 | + |
| 15 | +The example given would be the View for the "index" action of the "Products" Controller. All View files are named in CamelCase after the "action", plus the word "View", and are located in a sub-directory called "Ctk/". This helps keep the *PHP* class files separate from any legacy ".ctp" files which may also be used by the Controller. |
| 16 | + |
| 17 | +Presentation |
| 18 | +------------ |
| 19 | + |
| 20 | +Due to the fact that CTK reduces your code to just *PHP*, it's important to mantain this code in a clean and coherent format, aiding readability where possible. |
| 21 | + |
| 22 | +With regard to node hierarchy, it's helpful to show indentation of parent and child nodes in the code, to aid visualization of the structure being built. It's also wise to introduce white space, to further imply the separation between different objects, for example: |
| 23 | + |
| 24 | +```php |
| 25 | +$grandParent = $this->Factory->Object(array( |
| 26 | + 'param' => $value |
| 27 | +)); |
| 28 | + |
| 29 | + $parent = $this->Factory->Object(array( |
| 30 | + 'param' => $value |
| 31 | + )); |
| 32 | + |
| 33 | + $firstChild = $this->Factory->Object(array( |
| 34 | + 'param' => $value |
| 35 | + )); |
| 36 | + |
| 37 | + $secondChild = $this->Factory->Object(array( |
| 38 | + 'param' => $value |
| 39 | + )); |
| 40 | + |
| 41 | + $parent->add($firstChild); |
| 42 | + $parent->add($secondChild); |
| 43 | + |
| 44 | +$grandParent->add($parent); |
| 45 | + |
| 46 | +$this->add($grandParent); |
| 47 | +``` |
| 48 | + |
| 49 | +The following are a list of basic rules which, if adhered to, should provide additional consistency to the code: |
| 50 | + |
| 51 | +* Objects should be defined with a handler which clearly describes the object |
| 52 | +* Names of object handlers should not describe their appearance, size or position, as this is controlled via *CSS* and may change |
| 53 | +* Names of object handlers should end with their type, for example, $submitButton |
| 54 | +* All objects should be defined with a line of white space (LF) before and after |
| 55 | +* Objects should be added to their parent or the View after all children have been defined |
| 56 | +* Objects which are added directly to the View should be added at the end of the **build()** method |
| 57 | +* Objects which are a child of another object should be defined with an additional tab of indentation |
| 58 | + |
| 59 | +Modularity |
| 60 | +---------- |
| 61 | + |
| 62 | +As Views in CTK are *PHP* classes it's possible to take full advantage of the object-oriented aspects of the language. Some areas of Views can be encapsulated into methods of a class, or introduced when using traits. It's as equally important to maintain a coherent design with regard to these methods, especially in the interest of keeping your application *future-proof*. |
| 63 | + |
| 64 | +**Builders**: These are methods which prepare an object for use in the View. The principal characteristic of this method is that it returns an object which has been prepared and built. These methods begin with the "build" keyword, followed by a CamelCase name for what they build, for example: |
| 65 | + |
| 66 | +```php |
| 67 | +public function buildExampleObject() { |
| 68 | + // some logic here |
| 69 | + $object = $this->Factory->Object(); |
| 70 | + return $object; |
| 71 | +} |
| 72 | +``` |
| 73 | + |
| 74 | +A simple example of a **builder** in use may be similar to the following: |
| 75 | + |
| 76 | +```php |
| 77 | +$exampleObject = $this->buildExampleObject(); |
| 78 | +``` |
| 79 | + |
| 80 | +Keep in mind that it's perfectly possible for **builders** to return a single object, or possibly a full structure of objects, with a base object as the return value of the method. However, it's very important to *not* add the object to the View inside of the method, as this breaks the option to use that method elsewhere without it be added directly to the View. The added benefit of **builder** methods is that they encapsulate the code required to build that specific interface, but also provide portability by returning the objects. |
| 81 | + |
| 82 | +**Resolvers**: These are methods which resolve a value for use in a View. It's important to not confuse this with application logic which should be resolved in the Controller. These methods begin with the "resolve" keyword, followed by a CameCase name for what they resolve, for example: |
| 83 | + |
| 84 | +```php |
| 85 | +public function resolveSomething() { |
| 86 | + // some logic here |
| 87 | + return $something; |
| 88 | +} |
| 89 | +``` |
| 90 | + |
| 91 | +An example of a **resolver** may be for the value of a configuration parameter, for example: |
| 92 | + |
| 93 | +```php |
| 94 | +$exampleButton = $this->Factory->Object(array( |
| 95 | + 'param' => $this->resolveSomething() |
| 96 | +)); |
| 97 | +``` |
| 98 | + |
| 99 | +Or, possibly a more complete example, where the whole configuration array is resolved: |
| 100 | + |
| 101 | +```php |
| 102 | +$exampleButton = $this->Factory->Object($this->resolveSomething()); |
| 103 | +``` |
| 104 | + |
| 105 | +Configuration |
| 106 | +------------- |
| 107 | + |
| 108 | +A powerful feature of CTK is the possibility to define the configuration of objects from an external file. This can be acheived through the use of **Configure::write()** and **Configure::read()**. |
| 109 | + |
| 110 | +For example, you may have various forms in your application which have configurations that may be modified on a regular basis. In order to avoid having to edit the view file, you can abstract the configuration of those objects to an external file, for example: |
| 111 | + |
| 112 | +```php |
| 113 | +Configure::write('exampleFormConfig', array( |
| 114 | + 'param' => 'value' |
| 115 | +)); |
| 116 | +``` |
| 117 | + |
| 118 | +Then, in your View file, simply read the configuration array from the external file: |
| 119 | + |
| 120 | +```php |
| 121 | +$exampleForm = $this->Html->Form(Configure::read('exampleFormConfig')); |
| 122 | +``` |
| 123 | + |
| 124 | +If you have the same object located in various areas of the application, but it's configuration varies slightly in each location, consider possibly using a **resolver** method which uses **Configuration::read()** to access the relevant configuration for each area. |
| 125 | + |
| 126 | +Extensibility |
| 127 | +------------- |
| 128 | + |
| 129 | +You may find you want to build you own factories, to hold propietary objects used by your application, or you may even be considering sharing your objects with the open source community. In either case, it's ideal to maintain a certain amount of conformaty in the naming of your factories. |
| 130 | + |
| 131 | +By default, the plugin name for factories is the name of the factory itself, followed by the word "Factory". So, if you were to create an "Example" factory, the name of your plugin would become "ExampleFactory", for example: |
| 132 | + |
| 133 | +``` |
| 134 | +app/Plugin/ExampleFactory |
| 135 | +``` |
| 136 | + |
| 137 | +Inside the plugin, the location of your factory class itself would be located in the "Factory" directory, in the base "View" directory, for example: |
| 138 | + |
| 139 | +``` |
| 140 | +app/Plugin/ExampleFactory/View/Factory/ExampleFactory.php |
| 141 | +``` |
| 142 | + |
| 143 | +All of your factory's objects and templates are then located in a directory with the same name as your factory, in this case "Example". |
| 144 | + |
| 145 | +``` |
| 146 | +app/Plugin/ExampleFactory/View/Factory/Example/ |
| 147 | +``` |
| 148 | + |
| 149 | +This naming convention also applies to renderers and processors. So, if you were to create either a renderer or a processor named "Example", they would be named in the same fashion. |
| 150 | + |
| 151 | +``` |
| 152 | +app/Plugin/ExampleFactory/View/Renderer/ExampleRenderer.php |
| 153 | +app/Plugin/ExampleFactory/View/Processor/ExampleProcessor.php |
| 154 | +``` |
| 155 | + |
| 156 | +As layouts remain as ".ctp" files there is no alteration to the naming or location of these. |
| 157 | + |
0 commit comments