Skip to content

Commit 3d43f70

Browse files
author
Dieter Wyns
committed
Moving dev guide
1 parent 328be5a commit 3d43f70

33 files changed

+2132
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

module guide/ajax.md

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# Ajax
2+
3+
## URL
4+
Before you continue, be sure to have taken a good look at the previous javascript code. Mind the parameters we're calling:
5+
6+
```
7+
data:
8+
{
9+
fork: { module: 'mini_blog', action: 'this_is_awesome' },
10+
post_id: arg
11+
},
12+
```
13+
14+
Because we're on the frontend, we call the frontend ajax.php supply it with a couple of arguments. The first two are always mandatory:
15+
16+
* module → the module in which our action file is located
17+
* action → the name of the action file, without the php-extension
18+
19+
Because we're working in a multilingual site, the language argument is mandatory as well, although you might not need to use it in the action itself. We fetched the language through splitting the url that's currently opened in our browser.
20+
21+
* language → the language code (nl, en, fr, ...)
22+
23+
Other arguments are action depended. In case of the this_is_awesome action, we need to supply the id of the blog post (post_id) of which we want to increment the awesomeness.
24+
25+
## Action
26+
27+
The action file itself is a .php file located in the ajax-folder. The structure of an Ajax action is the same as an other action file, meaning, there has to be a public “execute” function.
28+
29+
```
30+
class FrontendMiniBlogAjaxThisIsAwesome extends FrontendBaseAJAXAction
31+
{
32+
public function execute()
33+
{
34+
$post_id = (int) SpoonFilter::getPostValue('post_id', null, '', 'int');
35+
36+
if($post_id == 0)
37+
{
38+
$this->output(self::BAD_REQUEST, null, 'invalid post_id-parameter.');
39+
}
40+
41+
FrontendMiniBlogModel::addAwesomeness($post_id);
42+
43+
$this->output(self::OK);
44+
}
45+
}
46+
```
47+
48+
49+
The difference with other types of actions can be found when given special attention to the naming of the class.
50+
51+
*ApplicationModule**Ajax**Action*
52+
53+
Also note that the class extends FrontendBaseAJAXAction. This is necessary do define constants such as "self::OK" and the output-method.
54+
55+
Depending on the post_id being valid or not, the addAwesomeness method defined in the model is called, and the output-method is called. This function outputs JSON data which is read by the Javascript success-function we saw earlier.

module guide/api.md

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
# API
2+
3+
When you want to link your website to the outside world, it might be a good idea to provide an API to this outside world. By using the API, other programmers connect there applications, iPhone Apps, websites, ... with your website, or perhaps you could write your own iPhone App (and sell it for just € 9,99 in the AppStore) which allows to post blog posts to your website.
4+
We'll use an other, less complicated example to illustrate the principles of an API.
5+
6+
## Engine
7+
8+
First you create a file named "api.php" in the /backend/modules/module_name/engine folder. In this file you define a class called `BackendModuleNameAPI`.
9+
10+
Then, for every action external applications should be able to perform you define a public static method.
11+
12+
In our case we'll just have one method, `show_top_awesome`. This method will return the most (number) awesome posts of the last (days) days.
13+
14+
```
15+
class BackendMiniBlogAPI
16+
{
17+
public static function showTopAwesome()
18+
{
19+
$number = (int) SpoonFilter::getGetValue('number', null, 10);
20+
$days = (int) SpoonFilter::getGetValue('days', null, 7);
21+
22+
API::output('200', BackendMiniBlogModel::getTopAwesome($number, $days));
23+
}
24+
}
25+
```
26+
27+
As you can see we expect the data to be GET-variables but if you feel like working with POST-variables,... your choice.
28+
29+
## Return
30+
31+
When you want to use the method above, you need to call the following url:
32+
/api/1.0/?method=mini_blog.showTopAwesome&format=json&number=10&days=7
33+
34+
The first parameter is the name of the module and the name of the action separated with a dot. This action is the real method name, not the "reversed" camelCased name as it's used with class- and filenames.
35+
36+
When you're using the output function, you need to supply the format parameter, which has to be equal to "json" or "xml". The data we fetched and passed on the output method will be converted to one of these two formats.
37+
38+
The last two parameters are "number" and "days". They are used only in this action. Should they be omitted, then the default value, given as the third parameter of the getGetValue-method, is used.
39+
40+
> **Don't return**
41+
> In our example the API is supposed to return some data, but of course you can create method's that will not be returning any data (f.e. posting a new blog post). In that case, just don't call the output method.
42+
> Although you could provide some feedback wether to post was successful.

module guide/assets/detail.png

41.8 KB
Loading
333 KB
Loading

module guide/assets/info_xml.png

85.6 KB
Loading

module guide/assets/locale.png

90.4 KB
Loading

module guide/assets/meta.png

54.7 KB
Loading

module guide/assets/translations.png

105 KB
Loading

module guide/assets/zip_structure.png

25.5 KB
Loading

module guide/breadcrumbs.md

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Breadcrumbs
2+
3+
Each blog article will have a proper page title. Adding this title to the breadcrumb allows users to easily keep track of their location.
4+
5+
To add data to the breadcrumb, you'll add the following lines to the parse method in detail.php.
6+
7+
```
8+
// add into breadcrumb
9+
$this->breadcrumb->addElement($this->record['title'], $this->record['full_url']);
10+
```
11+
12+
This way, we'll add the title to the breadcrumb and if this is not the last item (e.g. if we're using categories), the second parameter will be activated and it will become a link so the user can navigate back to that.
13+
14+
The first parameter is manditory, the second is optional.
+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Creating a module.zip file
2+
3+
When you've finished your module, you will probably want to be able to easily install this in other websites. Since Fork CMS 3.0.0, it is possible to install packaged modules. Therefor, you'll need to create a .zip file.
4+
5+
## The .zip file
6+
7+
The zip file contains the absolute paths to the module, as you can see in the image below. This means that you should always have a structure that starts in the base directory of you project.
8+
9+
![Zip structure](assets/zip_structure.png)
10+
11+
## Required files
12+
13+
To install the module, some files are required. Each module should have a config.php file in both the backend and frontend.
14+
15+
In the backend, you also need an installer folder that contains an installer.php file. Next to this, you also need an info.xml file. This file is used to display information on the Extensions page in the backend.
16+
17+
To create these files, we recommend you to take a look in the 'Module development' section.

module guide/creating_an_installer.md

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
# Creating an installer
2+
3+
To create an installer, you need some basic files. First of all, you need the installer file. This is located in the backend installer folder. For our module this would be /backend/modules/mini_blog/installer/installer.php.
4+
5+
Next to this file, depending on the module, you can have some other files, mostly used are the install.sql file and the locale.xml file. We'll put these in the subdirectory /data.
6+
7+
## Installer
8+
9+
In the installer file we load the database tables (if required) and the locale (if required). Besides this, we also make sure our users have rights to access our module.
10+
11+
```
12+
class MiniBlogInstaller extends ModuleInstaller
13+
{
14+
/**
15+
* Install the module
16+
*/
17+
public function install()
18+
{
19+
$this->importSQL(dirname(__FILE__) . '/data/install.sql');
20+
21+
$this->addModule('mini_blog');
22+
23+
$this->importLocale(dirname(__FILE__) . '/data/locale.xml');
24+
```
25+
26+
Now we want to make sure that our module can be accessed for the search module and for other users that aren't god users. We do this by adding some rules:
27+
28+
```
29+
$this->makeSearchable('mini_blog');
30+
$this->setModuleRights(1, 'mini_blog');
31+
32+
$this->setActionRights(1, 'mini_blog', 'index');
33+
$this->setActionRights(1, 'mini_blog', 'add');
34+
$this->setActionRights(1, 'mini_blog', 'edit');
35+
$this->setActionRights(1, 'mini_blog', 'delete');
36+
```
37+
38+
After we've added our rights, we want to create an option so we can add our blog to the frontend. To do this, we need to create some extras. Since we also have a widget with the recent posts, we also need to create an extra for that. We do this by adding the following code:
39+
40+
```
41+
$miniBlogId = $this->insertExtra('mini_blog', 'block', 'MiniBlog');
42+
$this->insertExtra('mini_blog', 'widget', 'RecentPosts', 'recent_posts');
43+
```
44+
45+
The first extra will allow us to show the overview and other actions. The second extra will allow us to add the widget on pages. For this method, the first three parameters are mandatory. Here is a list of parameters:
46+
47+
* module: the module we want to install the extra for
48+
* type: the type of extra we want, this can be a block or a widget
49+
* label: this is the label we should use in the dropdown navigation if we select our extra
50+
* action: the action we should call if this extra is called, if none is given, the base action is index
51+
52+
Last but not least, we want to be able to manage our blog. To do this, we need to add some navigation rules for the backend.
53+
54+
```
55+
// set navigation
56+
$navigationModulesId = $this->setNavigation(null, 'Modules');
57+
$navigationBlogId = $this->setNavigation($navigationModulesId, 'MiniBlog', 'mini_blog/index', array('mini_blog/add', 'mini_blog/edit'));
58+
```
59+
60+
At first, we fetch the id for the Modules navigation that you can see at the top of your backend. We do this because we want our module to come in that navigation tree.
61+
After that, we add a new navigation item. The parameters for this are explained below:
62+
63+
* parentId: the id of the parent (in this case, the modules navigation tree, but this could also be our module itself if we have subnavigation, e.g. categories, comments, ...)
64+
* label: the label we should use for this navigation item
65+
* url: the action we should call if we select this item
66+
* selectedFor: in this case, we want our add and edit action to have the same navigation item as our index action, to do this, we add an array that contains these navigation actions.
67+
68+
## Locale
69+
70+
Fork already has a wide range of labels, messages, errors and actions pre installed. Though, it is possible you'll need some extras. To do this, we provide a locale.xml file that we use in our installer. To parse the data, we use a specific structure. In the screenshot below, you'll see that basic structure, followed by the xml for the mini blog module.
71+
72+
![Locale xml](assets/locale.png)
73+
74+
As you can see, we specify 2 children in the main node. These are backend and frontend (you can use one aswell). Within the application, for each module you have locale parameters, you create a new node with that module name. All the items within this node will be installed for the given module.
75+
76+
## Database
77+
78+
To add the requried database files, we need to create a file called install.sql in the /backend/modules/mini_blog/install/data folder. For the rest, this is pretty basic. It's just a dump of your table.
79+
80+
```
81+
CREATE TABLE `mini_blog` (
82+
`id` int(11) NOT NULL AUTO_INCREMENT,
83+
`title` varchar(255) CHARACTER SET utf8 DEFAULT NULL,
84+
`introduction` text CHARACTER SET utf8,
85+
`text` text CHARACTER SET utf8,
86+
`created` datetime DEFAULT NULL,
87+
`edited` datetime DEFAULT NULL,
88+
`publish` enum('Y','N') CHARACTER SET utf8 DEFAULT 'Y',
89+
`user_id` int(11) DEFAULT NULL,
90+
`language` varchar(3) CHARACTER SET utf8 DEFAULT NULL,
91+
`meta_id` int(11) DEFAULT NULL,
92+
`awesomeness` int(11) DEFAULT '0',
93+
PRIMARY KEY (`id`)
94+
) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
95+
```
96+
97+
## Info
98+
99+
We also provide a info.xml with each module. This allows us to see some information about it. The main node is the <module> node. Below is a screenshot of the info.xml file for the mini blog.
100+
101+
![Info xml](assets/info_xml.png)
102+
103+
As you can see, we have several sections in the module node. The upper part(name - authors) is to give some information about the module itself. The lower part(events-cronjobs) is information that we can use for other modules. The events system is already explained in another article.

0 commit comments

Comments
 (0)