Indefero

Indefero Commit Details


Date:2008-11-22 16:51:23 (16 years 29 days ago)
Author:Loic d'Anterroches
Branch:dev, develop, feature-issue_links, feature.better-home, feature.content-md5, feature.diff-whitespace, feature.download-md5, feature.issue-links, feature.issue-of-others, feature.issue-summary, feature.search-filter, feature.webrepos, feature.wiki-default-page, master, release-1.1, release-1.2, release-1.3
Commit:8eb5715656cfc94c312ee54e65b6c919c840489f
Parents: b13633fed2a86a9015ac2e492a643b652f56a7ff
Message:Partial fix of issue 55, addition of a simple Wiki.

Added a base wiki, it is now possible to create wiki pages and update
them. Revisions are kept also not used/displayed at the moment.
Changes:

File differences

src/IDF/Form/TabsConf.php
3636
3737
3838
39
3940
4041
4142
$this->project = $extra['project'];
$ak = array('downloads_access_rights' => __('Downloads'),
'wiki_access_rights' => __('Documentation'),
'source_access_rights' => __('Source'),
'issues_access_rights' => __('Issues'),);
foreach ($ak as $key=>$label) {
src/IDF/Form/WikiConf.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Configuration of the labels etc. for the wiki pages.
*/
class IDF_Form_WikiConf extends Pluf_Form
{
/**
* Defined as constants to easily access the value in the
* form in the case nothing is in the db yet.
*/
const init_predefined = 'Featured = Listed on project home page
Phase:Requirements = Project vision and requirements
Phase:Design = Project design and key concerns
Phase:Implementation = Developers\' guide
Phase:QA = Testing plans and QA strategies
Phase:Deploy = How to install and configure the program
Phase:Support = Plans for user support and advocacy
Deprecated = Most users should NOT reference this';
const init_one_max = '';
public function initFields($extra=array())
{
$this->fields['labels_wiki_predefined'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Predefined documentation page labels'),
'initial' => self::init_predefined,
'widget_attrs' => array('rows' => 13,
'cols' => 75),
'widget' => 'Pluf_Form_Widget_TextareaInput',
));
$this->fields['labels_wiki_one_max'] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Each documentation page may have at most one label with each of these classes'),
'initial' => self::init_one_max,
'widget_attrs' => array('size' => 60),
));
}
}
src/IDF/Form/WikiCreate.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Create a new documentation page.
*
* This create a new page and the corresponding revision.
*
*/
class IDF_Form_WikiCreate extends Pluf_Form
{
public $user = null;
public $project = null;
public $show_full = false;
public function initFields($extra=array())
{
$initial = __('# Introduction
Add your content here.
# Details
Add your content here. Format your content with:
* Text in **bold** or *italic*.
* Headings, paragraphs, and lists.
* Links to other [[WikiPage]].
');
$this->user = $extra['user'];
$this->project = $extra['project'];
if ($this->user->hasPerm('IDF.project-owner', $this->project)
or $this->user->hasPerm('IDF.project-member', $this->project)) {
$this->show_full = true;
}
$this->fields['title'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Page title'),
'initial' => __('PageName'),
'widget_attrs' => array(
'maxlength' => 200,
'size' => 67,
),
'help_text' => __('The page name must contains only letters, digits and the dash (-) character.'),
));
$this->fields['summary'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Description'),
'help_text' => __('This one line description is displayed in the list of pages.'),
'initial' => '',
'widget_attrs' => array(
'maxlength' => 200,
'size' => 67,
),
));
$this->fields['content'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Content'),
'initial' => $initial,
'widget' => 'Pluf_Form_Widget_TextareaInput',
'widget_attrs' => array(
'cols' => 58,
'rows' => 26,
),
));
if ($this->show_full) {
for ($i=1;$i<4;$i++) {
$this->fields['label'.$i] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Labels'),
'initial' => '',
'widget_attrs' => array(
'maxlength' => 50,
'size' => 20,
),
));
}
}
}
public function clean_title()
{
$title = $this->cleaned_data['title'];
if (preg_match('/[^a-zA-Z0-9\-]/', $title)) {
throw new Pluf_Form_Invalid(__('The title contains invalid characters.'));
}
$sql = new Pluf_SQL('project=%s AND title=%s',
array($this->project->id, $title));
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
if ($pages->count() > 0) {
throw new Pluf_Form_Invalid(__('A page with this title already exists.'));
}
return $title;
}
/**
* Validate the interconnection in the form.
*/
public function clean()
{
if (!$this->show_full) {
return $this->cleaned_data;
}
$conf = new IDF_Conf();
$conf->setProject($this->project);
$onemax = array();
foreach (split(',', $conf->getVal('labels_wiki_one_max', IDF_Form_WikiConf::init_one_max)) as $class) {
if (trim($class) != '') {
$onemax[] = mb_strtolower(trim($class));
}
}
$count = array();
for ($i=1;$i<4;$i++) {
$this->cleaned_data['label'.$i] = trim($this->cleaned_data['label'.$i]);
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(mb_strtolower(trim($class)),
trim($name));
} else {
$class = 'other';
$name = $this->cleaned_data['label'.$i];
}
if (!isset($count[$class])) $count[$class] = 1;
else $count[$class] += 1;
if (in_array($class, $onemax) and $count[$class] > 1) {
if (!isset($this->errors['label'.$i])) $this->errors['label'.$i] = array();
$this->errors['label'.$i][] = sprintf(__('You cannot provide more than label from the %s class to a page.'), $class);
throw new Pluf_Form_Invalid(__('You provided an invalid label.'));
}
}
return $this->cleaned_data;
}
/**
* Save the model in the database.
*
* @param bool Commit in the database or not. If not, the object
* is returned but not saved in the database.
* @return Object Model with data set from the form.
*/
function save($commit=true)
{
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
// Add a tag for each label
$tags = array();
if ($this->show_full) {
for ($i=1;$i<4;$i++) {
if (strlen($this->cleaned_data['label'.$i]) > 0) {
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(trim($class), trim($name));
} else {
$class = 'Other';
$name = trim($this->cleaned_data['label'.$i]);
}
$tags[] = IDF_Tag::add($name, $this->project, $class);
}
}
}
// Create the page
$page = new IDF_WikiPage();
$page->project = $this->project;
$page->submitter = $this->user;
$page->summary = trim($this->cleaned_data['summary']);
$page->title = trim($this->cleaned_data['title']);
$page->create();
foreach ($tags as $tag) {
$page->setAssoc($tag);
}
// add the first revision
$rev = new IDF_WikiRevision();
$rev->wikipage = $page;
$rev->content = $this->cleaned_data['content'];
$rev->submitter = $this->user;
$rev->summary = __('Initial page creation');
$rev->create();
return $page;
}
}
src/IDF/Form/WikiUpdate.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Update a documentation page.
*
* This add a corresponding revision.
*
*/
class IDF_Form_WikiUpdate extends Pluf_Form
{
public $user = null;
public $project = null;
public $page = null;
public $show_full = false;
public function initFields($extra=array())
{
$this->page = $extra['page'];
$this->user = $extra['user'];
$this->project = $extra['project'];
if ($this->user->hasPerm('IDF.project-owner', $this->project)
or $this->user->hasPerm('IDF.project-member', $this->project)) {
$this->show_full = true;
}
if ($this->show_full) {
$this->fields['title'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Page title'),
'initial' => $this->page->title,
'widget_attrs' => array(
'maxlength' => 200,
'size' => 67,
),
'help_text' => __('The page name must contains only letters, digits and the dash (-) character.'),
));
$this->fields['summary'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Description'),
'help_text' => __('This one line description is displayed in the list of pages.'),
'initial' => $this->page->summary,
'widget_attrs' => array(
'maxlength' => 200,
'size' => 67,
),
));
}
$rev = $this->page->get_current_revision();
$this->fields['content'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Content'),
'initial' => $rev->content,
'widget' => 'Pluf_Form_Widget_TextareaInput',
'widget_attrs' => array(
'cols' => 58,
'rows' => 26,
),
));
$this->fields['comment'] = new Pluf_Form_Field_Varchar(
array('required' => true,
'label' => __('Comment'),
'help_text' => __('One line to describe the changes you made.'),
'initial' => '',
'widget_attrs' => array(
'maxlength' => 200,
'size' => 67,
),
));
if ($this->show_full) {
$tags = $this->page->get_tags_list();
for ($i=1;$i<4;$i++) {
$initial = '';
if (isset($tags[$i-1])) {
if ($tags[$i-1]->class != 'Other') {
$initial = (string) $tags[$i-1];
} else {
$initial = $tags[$i-1]->name;
}
}
$this->fields['label'.$i] = new Pluf_Form_Field_Varchar(
array('required' => false,
'label' => __('Labels'),
'initial' => $initial,
'widget_attrs' => array(
'maxlength' => 50,
'size' => 20,
),
));
}
}
}
public function clean_title()
{
$title = $this->cleaned_data['title'];
if (preg_match('/[^a-zA-Z0-9\-]/', $title)) {
throw new Pluf_Form_Invalid(__('The title contains invalid characters.'));
}
$sql = new Pluf_SQL('project=%s AND title=%s',
array($this->project->id, $title));
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
if ($pages->count() > 0 and $pages[0]->id != $this->page->id) {
throw new Pluf_Form_Invalid(__('A page with this title already exists.'));
}
return $title;
}
/**
* Validate the interconnection in the form.
*/
public function clean()
{
if (!$this->show_full) {
return $this->cleaned_data;
}
$conf = new IDF_Conf();
$conf->setProject($this->project);
$onemax = array();
foreach (split(',', $conf->getVal('labels_wiki_one_max', IDF_Form_WikiConf::init_one_max)) as $class) {
if (trim($class) != '') {
$onemax[] = mb_strtolower(trim($class));
}
}
$count = array();
for ($i=1;$i<4;$i++) {
$this->cleaned_data['label'.$i] = trim($this->cleaned_data['label'.$i]);
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(mb_strtolower(trim($class)),
trim($name));
} else {
$class = 'other';
$name = $this->cleaned_data['label'.$i];
}
if (!isset($count[$class])) $count[$class] = 1;
else $count[$class] += 1;
if (in_array($class, $onemax) and $count[$class] > 1) {
if (!isset($this->errors['label'.$i])) $this->errors['label'.$i] = array();
$this->errors['label'.$i][] = sprintf(__('You cannot provide more than label from the %s class to a page.'), $class);
throw new Pluf_Form_Invalid(__('You provided an invalid label.'));
}
}
return $this->cleaned_data;
}
/**
* Save the model in the database.
*
* @param bool Commit in the database or not. If not, the object
* is returned but not saved in the database.
* @return Object Model with data set from the form.
*/
function save($commit=true)
{
if (!$this->isValid()) {
throw new Exception(__('Cannot save the model from an invalid form.'));
}
if ($this->show_full) {
$tagids = array();
$tags = array();
for ($i=1;$i<4;$i++) {
if (strlen($this->cleaned_data['label'.$i]) > 0) {
if (strpos($this->cleaned_data['label'.$i], ':') !== false) {
list($class, $name) = explode(':', $this->cleaned_data['label'.$i], 2);
list($class, $name) = array(trim($class), trim($name));
} else {
$class = 'Other';
$name = trim($this->cleaned_data['label'.$i]);
}
$tag = IDF_Tag::add($name, $this->project, $class);
$tags[] = $tag;
$tagids[] = $tag->id;
}
}
// Compare between the old and the new data
$changes = array();
$oldtags = $this->page->get_tags_list();
foreach ($tags as $tag) {
if (!Pluf_Model_InArray($tag, $oldtags)) {
if (!isset($changes['lb'])) $changes['lb'] = array();
if ($tag->class != 'Other') {
$changes['lb'][] = (string) $tag; //new tag
} else {
$changes['lb'][] = (string) $tag->name;
}
}
}
foreach ($oldtags as $tag) {
if (!Pluf_Model_InArray($tag, $tags)) {
if (!isset($changes['lb'])) $changes['lb'] = array();
if ($tag->class != 'Other') {
$changes['lb'][] = '-'.(string) $tag; //new tag
} else {
$changes['lb'][] = '-'.(string) $tag->name;
}
}
}
if (trim($this->page->summary) != trim($this->cleaned_data['summary'])) {
$changes['su'] = trim($this->cleaned_data['summary']);
}
// Update the page
$this->page->batchAssoc('IDF_Tag', $tagids);
$this->page->summary = trim($this->cleaned_data['summary']);
$this->page->title = trim($this->cleaned_data['title']);
} else {
$changes = array();
}
$this->page->update();
// add the new revision
$rev = new IDF_WikiRevision();
$rev->wikipage = $this->page;
$rev->content = $this->cleaned_data['content'];
$rev->submitter = $this->user;
$rev->summary = $this->cleaned_data['comment'];
$rev->changes = $changes;
$rev->create();
return $this->page;
}
}
src/IDF/Middleware.php
5353
5454
5555
56
5657
5758
5859
$request->conf = new IDF_Conf();
$request->conf->setProject($request->project);
$ak = array('downloads_access_rights' => 'hasDownloadsAccess',
'wiki_access_rights' => 'hasWikiAccess',
'source_access_rights' => 'hasSourceAccess',
'issues_access_rights' => 'hasIssuesAccess');
$request->rights = array();
src/IDF/Migrations/7Wiki.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Add the download of files.
*/
function IDF_Migrations_7Wiki_up($params=null)
{
$models = array(
'IDF_WikiPage',
'IDF_WikiRevision',
);
$db = Pluf::db();
$schema = new Pluf_DB_Schema($db);
foreach ($models as $model) {
$schema->model = new $model();
$schema->createTables();
}
}
function IDF_Migrations_7Wiki_down($params=null)
{
$models = array(
'IDF_WikiRevision',
'IDF_WikiPage',
);
$db = Pluf::db();
$schema = new Pluf_DB_Schema($db);
foreach ($models as $model) {
$schema->model = new $model();
$schema->dropTables();
}
}
src/IDF/Migrations/Install.php
4040
4141
4242
43
44
4345
4446
4547
......
6971
7072
7173
74
75
7276
7377
7478
'IDF_IssueFile',
'IDF_Commit',
'IDF_Timeline',
'IDF_WikiPage',
'IDF_WikiRevision',
);
$db = Pluf::db();
$schema = new Pluf_DB_Schema($db);
$perm = Pluf_Permission::getFromString('IDF.project-owner');
if ($perm) $perm->delete();
$models = array(
'IDF_WikiRevision',
'IDF_WikiPage',
'IDF_Timeline',
'IDF_IssueFile',
'IDF_Search_Occ',
src/IDF/Precondition.php
143143
144144
145145
146
147
148
149
150
151
152
153
154
146155
147156
148157
return self::accessTabGeneric($request, 'downloads_access_rights');
}
static public function accessWiki($request)
{
$res = self::baseAccess($request);
if (true !== $res) {
return $res;
}
return self::accessTabGeneric($request, 'wiki_access_rights');
}
/**
* Based on the request, it is automatically setting the user.
*
src/IDF/Project.php
283283
284284
285285
286
287
288
289
286
287
288
290289
291290
292291
/**
* Generate the tag clouds.
*
* Return an array of tags sorted class, then name. Each tag get
* the extra property 'nb_use' for the number of use in the
* project. For issues, only open issues are used to generate the
* cloud.
* Return an array of tags sorted by class, then name. Each tag
* get the extra property 'nb_use' for the number of use in the
* project.
*
* @param string ('issues') 'closed_issues' or 'downloads'
* @return ArrayObject of IDF_Tag
src/IDF/Template/IssueComment.php
3232
3333
3434
35
35
3636
3737
3838
3939
4040
41
41
4242
4343
4444
private $request = null;
private $scm = null;
function start($text, $request, $echo=true, $wordwrap=true)
function start($text, $request, $echo=true, $wordwrap=true, $esc=true)
{
$this->project = $request->project;
$this->request = $request;
$this->scm = IDF_Scm::get($request);
if ($wordwrap) $text = wordwrap($text, 69, "\n", true);
$text = Pluf_esc($text);
if ($esc) $text = Pluf_esc($text);
$text = ereg_replace('[[:alpha:]]+://[^<>[:space:]]+[[:alnum:]/]',
'<a href="\\0" rel="nofollow">\\0</a>',
$text);
src/IDF/Template/Markdown.php
2323
2424
2525
26
27
28
29
30
31
3226
33
27
3428
35
29
3630
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
10276
77
Pluf::loadFunction('Pluf_Text_MarkDown_parse');
function IDF_Template_Markdown_filter($mdtext)
{
$filter = new IDF_Template_Markdown();
return Pluf_Template::markSafe(Pluf_Text_MarkDown_parse($filter->go($mdtext)));
}
/**
* Strict class to only allow entities.
* Make the links to issues and commits.
*/
class IDF_Template_Markdown extends Pluf_Text_HTML_Filter
class IDF_Template_Markdown extends Pluf_Template_Tag
{
public $allowed = array();
public $always_close = array();
public $remove_blanks = array();
public $allowed_entities = array(
'amp',
'gt',
'lt',
'quot',
'nbsp',
'ndash',
'rdquo',
'ldquo',
'Alpha',
'Beta',
'Gamma',
'Delta',
'Epsilon',
'Zeta',
'Eta',
'Theta',
'Iota',
'Kappa',
'Lambda',
'Mu',
'Nu',
'Xi',
'Omicron',
'Pi',
'Rho',
'Sigma',
'Tau',
'Upsilon',
'Phi',
'Chi',
'Psi',
'Omega',
'alpha',
'beta',
'gamma',
'delta',
'epsilon',
'zeta',
'eta',
'theta',
'iota',
'kappa',
'lambda',
'mu',
'nu',
'xi',
'omicron',
'pi',
'rho',
'sigmaf',
'sigma',
'tau',
'upsilon',
'phi',
'chi',
'psi',
'omega',
'thetasym',
'upsih',
'piv',
);
private $project = null;
private $request = null;
private $scm = null;
function start($text, $request)
{
$this->project = $request->project;
$this->request = $request;
$filter = new IDF_Template_MarkdownPrefilter();
$text = $filter->go($text);
// The filter has replace < and > also in the code blocks so
// we need to revert them
$tmp = array();
foreach (preg_split("/\015\012|\015|\012/", $text, -1) as $s) {
if (0 === strpos($s, ' ')) {
$s = str_replace(array('&lt;', '&gt;'),
array('<', '>'), $s);
}
$tmp[] = $s;
}
$text = implode("\n", $tmp);
// Replace like in the issue text
$tag = new IDF_Template_IssueComment();
$text = $tag->start($text, $request, false, false, false);
// Replace [[PageName]] with corresponding link to the page.
// if not the right to see the
$text = preg_replace_callback('#\[\[([A-Za-z0-9\-]+)\]\]#im',
array($this, 'callbackWikiPage'),
$text);
echo Pluf_Text_MarkDown_parse($text);
}
function callbackWikiPage($m)
{
$sql = new Pluf_SQL('project=%s AND title=%s',
array($this->project->id, $m[1]));
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
if ($pages->count() != 1) {
return $m[0];
}
if (!$this->request->rights['hasWikiAccess']) {
return $m[1];
}
return '<a href="'.Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::view', array($this->project->shortname, $pages[0]->title)).'" title="'.Pluf_esc($pages[0]->summary).'">'.$m[1].'</a>';
}
}
src/IDF/Template/MarkdownPrefilter.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* Strict class to only allow entities.
*/
class IDF_Template_MarkdownPrefilter extends Pluf_Text_HTML_Filter
{
public $allowed = array();
public $always_close = array();
public $remove_blanks = array();
public $allowed_entities = array(
'amp',
'gt',
'lt',
'quot',
'nbsp',
'ndash',
'rdquo',
'ldquo',
'Alpha',
'Beta',
'Gamma',
'Delta',
'Epsilon',
'Zeta',
'Eta',
'Theta',
'Iota',
'Kappa',
'Lambda',
'Mu',
'Nu',
'Xi',
'Omicron',
'Pi',
'Rho',
'Sigma',
'Tau',
'Upsilon',
'Phi',
'Chi',
'Psi',
'Omega',
'alpha',
'beta',
'gamma',
'delta',
'epsilon',
'zeta',
'eta',
'theta',
'iota',
'kappa',
'lambda',
'mu',
'nu',
'xi',
'omicron',
'pi',
'rho',
'sigmaf',
'sigma',
'tau',
'upsilon',
'phi',
'chi',
'psi',
'omega',
'thetasym',
'upsih',
'piv',
);
}
src/IDF/Views/Project.php
8181
8282
8383
84
85
86
87
8488
8589
8690
......
234238
235239
236240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
237284
238285
239286
......
292339
293340
294341
295
342
343
296344
297345
298346
if (true === IDF_Precondition::accessDownloads($request)) {
$rights[] = '\'IDF_Upload\'';
}
if (true === IDF_Precondition::accessWiki($request)) {
$rights[] = '\'IDF_WikiPage\'';
$rights[] = '\'IDF_WikiRevision\'';
}
if (count($rights) == 0) {
$rights[] = '\'IDF_Dummy\'';
}
}
/**
* Administrate the information pages of a project.
*/
public $adminWiki_precond = array('IDF_Precondition::projectOwner');
public function adminWiki($request, $match)
{
$prj = $request->project;
$title = sprintf(__('%s Documentation Configuration'), (string) $prj);
$conf = new IDF_Conf();
$conf->setProject($prj);
if ($request->method == 'POST') {
$form = new IDF_Form_WikiConf($request->POST);
if ($form->isValid()) {
foreach ($form->cleaned_data as $key=>$val) {
$conf->setVal($key, $val);
}
$request->user->setMessage(__('The documentation configuration has been saved.'));
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Project::adminDownloads',
array($prj->shortname));
return new Pluf_HTTP_Response_Redirect($url);
}
} else {
$params = array();
$keys = array('labels_wiki_predefined', 'labels_wiki_one_max');
foreach ($keys as $key) {
$_val = $conf->getVal($key, false);
if ($_val !== false) {
$params[$key] = $_val;
}
}
if (count($params) == 0) {
$params = null; //Nothing in the db, so new form.
}
$form = new IDF_Form_WikiConf($params);
}
return Pluf_Shortcuts_RenderToResponse('idf/admin/wiki.html',
array(
'page_title' => $title,
'form' => $form,
),
$request);
}
/**
* Administrate the members of a project.
*/
public $adminMembers_precond = array('IDF_Precondition::projectOwner');
} else {
$params = array();
$keys = array('downloads_access_rights', 'source_access_rights',
'issues_access_rights', 'private_project');
'issues_access_rights', 'private_project',
'wiki_access_rights');
foreach ($keys as $key) {
$_val = $request->conf->getVal($key, false);
if ($_val !== false) {
src/IDF/Views/Wiki.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
Pluf::loadFunction('Pluf_Shortcuts_RenderToResponse');
Pluf::loadFunction('Pluf_Shortcuts_GetObjectOr404');
Pluf::loadFunction('Pluf_Shortcuts_GetFormForModel');
/**
* Documentation pages views.
*/
class IDF_Views_Wiki
{
/**
* View list of issues for a given project.
*/
public $index_precond = array('IDF_Precondition::accessWiki');
public function index($request, $match, $api=false)
{
$prj = $request->project;
$title = sprintf(__('%s Documentation'), (string) $prj);
// Paginator to paginate the pages
$pag = new Pluf_Paginator(new IDF_WikiPage());
$pag->class = 'recent-issues';
$pag->item_extra_props = array('project_m' => $prj,
'shortname' => $prj->shortname,
'current_user' => $request->user);
$pag->summary = __('This table shows the documentation pages.');
$pag->action = array('IDF_Views_Wiki::index', array($prj->shortname));
$pag->edit_action = array('IDF_Views_Wiki::view', 'shortname', 'title');
$sql = 'project=%s';
$ptags = self::getWikiTags($prj);
$dtag = array_pop($ptags); // The last tag is the deprecated tag.
$ids = self::getDeprecatedPagesIds($prj, $dtag);
if (count($ids)) {
$sql .= ' AND id NOT IN ('.implode(',', $ids).')';
}
$pag->forced_where = new Pluf_SQL($sql, array($prj->id));
$list_display = array(
'title' => __('Page Title'),
array('summary', 'IDF_Views_Wiki_SummaryAndLabels', __('Summary')),
array('modif_dtime', 'Pluf_Paginator_DateYMD', __('Updated')),
);
$pag->configure($list_display, array(), array('title', 'modif_dtime'));
$pag->items_per_page = 25;
$pag->no_results_text = __('No documentation pages were found.');
$pag->sort_order = array('title', 'ASC');
$pag->setFromRequest($request);
//$tags = $prj->getTagCloud('downloads');
return Pluf_Shortcuts_RenderToResponse('idf/wiki/index.html',
array(
'page_title' => $title,
'pages' => $pag,
//'tags' => $tags,
'deprecated' => count($ids),
'dlabel' => $dtag,
),
$request);
}
/**
* Create a new documentation page.
*/
public $create_precond = array('IDF_Precondition::accessWiki',
'Pluf_Precondition::loginRequired');
public function create($request, $match)
{
$prj = $request->project;
$title = __('New Page');
$preview = false;
if ($request->method == 'POST') {
$form = new IDF_Form_WikiCreate($request->POST,
array('project' => $prj,
'user' => $request->user
));
if ($form->isValid() and !isset($request->POST['preview'])) {
$page = $form->save();
$urlpage = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::view',
array($prj->shortname, $page->title));
$request->user->setMessage(sprintf(__('The page <a href="%s">%s</a> has been created.'), $urlpage, Pluf_esc($page->title)));
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::index',
array($prj->shortname));
return new Pluf_HTTP_Response_Redirect($url);
} elseif (isset($request->POST['preview'])) {
$preview = $request->POST['content'];
}
} else {
$form = new IDF_Form_WikiCreate(null,
array('project' => $prj,
'user' => $request->user));
}
return Pluf_Shortcuts_RenderToResponse('idf/wiki/create.html',
array(
'auto_labels' => self::autoCompleteArrays($prj),
'page_title' => $title,
'form' => $form,
'preview' => $preview,
),
$request);
}
/**
* View a documentation page.
*/
public $view_precond = array('IDF_Precondition::accessWiki');
public function view($request, $match)
{
$prj = $request->project;
// Find the page
$sql = new Pluf_SQL('project=%s AND title=%s',
array($prj->id, $match[2]));
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
if ($pages->count() != 1) {
throw new Pluf_HTTP_Error404($request);
}
$page = $pages[0];
$title = $page->title;
$revision = $page->get_current_revision();
return Pluf_Shortcuts_RenderToResponse('idf/wiki/view.html',
array(
'page_title' => $title,
'page' => $page,
'rev' => $revision,
'tags' => $page->get_tags_list(),
),
$request);
}
/**
* View a documentation page.
*/
public $update_precond = array('IDF_Precondition::accessWiki',
'Pluf_Precondition::loginRequired');
public function update($request, $match)
{
$prj = $request->project;
// Find the page
$sql = new Pluf_SQL('project=%s AND title=%s',
array($prj->id, $match[2]));
$pages = Pluf::factory('IDF_WikiPage')->getList(array('filter'=>$sql->gen()));
if ($pages->count() != 1) {
throw new Pluf_HTTP_Error404($request);
}
$page = $pages[0];
$title = sprintf(__('Update %s'), $page->title);
$revision = $page->get_current_revision();
$preview = false;
$params = array('project' => $prj,
'user' => $request->user,
'page' => $page);
if ($request->method == 'POST') {
$form = new IDF_Form_WikiUpdate($request->POST, $params);
if ($form->isValid() and !isset($request->POST['preview'])) {
$page = $form->save();
$urlpage = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::view',
array($prj->shortname, $page->title));
$request->user->setMessage(sprintf(__('The page <a href="%s">%s</a> has been updated.'), $urlpage, Pluf_esc($page->title)));
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::index',
array($prj->shortname));
return new Pluf_HTTP_Response_Redirect($url);
} elseif (isset($request->POST['preview'])) {
$preview = $request->POST['content'];
}
} else {
$form = new IDF_Form_WikiUpdate(null, $params);
}
return Pluf_Shortcuts_RenderToResponse('idf/wiki/update.html',
array(
'auto_labels' => self::autoCompleteArrays($prj),
'page_title' => $title,
'page' => $page,
'rev' => $revision,
'form' => $form,
'preview' => $preview,
),
$request);
}
/**
* Get the wiki tags.
*
* @param IDF_Project
* @return ArrayObject The tags
*/
public static function getWikiTags($project)
{
return $project->getTagsFromConfig('labels_wiki_predefined',
IDF_Form_WikiConf::init_predefined);
}
/**
* Get deprecated page ids.
*
* @param IDF_Project
* @param IDF_Tag Deprecated tag (null)
* @return array Ids of the deprecated pages.
*/
public static function getDeprecatedPagesIds($project, $dtag=null)
{
if (is_null($dtag)) {
$ptags = self::getDownloadTags($project);
$dtag = array_pop($ptags); // The last tag is the deprecated tag
}
$sql = new Pluf_SQL('project=%s AND idf_tag_id=%s', array($project->id,
$dtag->id));
$ids = array();
foreach (Pluf::factory('IDF_WikiPage')->getList(array('filter' => $sql->gen(), 'view' => 'join_tags'))
as $file) {
$ids[] = (int) $file->id;
}
return $ids;
}
/**
* Create the autocomplete arrays for the little AJAX stuff.
*/
public static function autoCompleteArrays($project)
{
$conf = new IDF_Conf();
$conf->setProject($project);
$st = preg_split("/\015\012|\015|\012/",
$conf->getVal('labels_wiki_predefined', IDF_Form_UploadConf::init_predefined), -1, PREG_SPLIT_NO_EMPTY);
$auto = '';
foreach ($st as $s) {
$v = '';
$d = '';
$_s = split('=', $s, 2);
if (count($_s) > 1) {
$v = trim($_s[0]);
$d = trim($_s[1]);
} else {
$v = trim($_s[0]);
}
$auto .= sprintf('{ name: "%s", to: "%s" }, ',
Pluf_esc($d), Pluf_esc($v));
}
return substr($auto, 0, -1);
}
}
/**
* Display the summary of a page, then on a new line, display the
* list of labels.
*/
function IDF_Views_Wiki_SummaryAndLabels($field, $page, $extra='')
{
$tags = array();
foreach ($page->get_tags_list() as $tag) {
$tags[] = Pluf_esc((string) $tag);
}
$out = '';
if (count($tags)) {
$out = '<br /><span class="note label">'.implode(', ', $tags).'</span>';
}
return Pluf_esc($page->summary).$out;
}
src/IDF/WikiPage.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
Pluf::loadFunction('Pluf_HTTP_URL_urlForView');
Pluf::loadFunction('Pluf_Template_dateAgo');
/**
* Base definition of a wiki page.
*
* A wiki page can have tags and be starred by the users. The real
* content of the page is stored in the IDF_WikiRevision
* object. Several revisions are associated to a given page.
*/
class IDF_WikiPage extends Pluf_Model
{
public $_model = __CLASS__;
function init()
{
$this->_a['table'] = 'idf_wikipages';
$this->_a['model'] = __CLASS__;
$this->_a['cols'] = array(
// It is mandatory to have an "id" column.
'id' =>
array(
'type' => 'Pluf_DB_Field_Sequence',
'blank' => true,
),
'project' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'IDF_Project',
'blank' => false,
'verbose' => __('project'),
'relate_name' => 'wikipages',
),
'title' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'blank' => false,
'size' => 250,
'verbose' => __('title'),
'help_text' => __('The title of the page must only contain letters, digits or the dash character. For example: My-new-Wiki-Page.'),
),
'summary' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'blank' => false,
'size' => 250,
'verbose' => __('summary'),
'help_text' => __('A one line description of the page content.'),
),
'submitter' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'Pluf_User',
'blank' => false,
'verbose' => __('submitter'),
'relate_name' => 'submitted_wikipages',
),
'interested' =>
array(
'type' => 'Pluf_DB_Field_Manytomany',
'model' => 'Pluf_User',
'blank' => true,
'verbose' => __('interested users'),
'help_text' => 'Interested users will get an email notification when the wiki page is changed.',
),
'tags' =>
array(
'type' => 'Pluf_DB_Field_Manytomany',
'blank' => true,
'model' => 'IDF_Tag',
'verbose' => __('labels'),
),
'creation_dtime' =>
array(
'type' => 'Pluf_DB_Field_Datetime',
'blank' => true,
'verbose' => __('creation date'),
),
'modif_dtime' =>
array(
'type' => 'Pluf_DB_Field_Datetime',
'blank' => true,
'verbose' => __('modification date'),
),
);
$this->_a['idx'] = array(
'modif_dtime_idx' =>
array(
'col' => 'modif_dtime',
'type' => 'normal',
),
);
$table = $this->_con->pfx.'idf_tag_idf_wikipage_assoc';
$this->_a['views'] = array(
'join_tags' =>
array(
'join' => 'LEFT JOIN '.$table
.' ON idf_wikipage_id=id',
),
);
}
function __toString()
{
return $this->title.' - '.$this->summary;
}
function _toIndex()
{
$rev = $this->get_current_revision()->_toIndex();
$str = str_repeat($this->summary.' ', 4).' '.$rev;
return Pluf_Text::cleanString(html_entity_decode($str, ENT_QUOTES, 'UTF-8'));
}
function get_current_revision()
{
$db = $this->getDbConnection();
$true = Pluf_DB_BooleanToDb(true, $db);
$rev = $this->get_revisions_list(array('filter' => 'is_head='.$true,
'nb' => 1));
return ($rev->count() == 1) ? $rev[0] : null;
}
function preSave($create=false)
{
if ($this->id == '') {
$this->creation_dtime = gmdate('Y-m-d H:i:s');
}
$this->modif_dtime = gmdate('Y-m-d H:i:s');
}
function postSave($create=false)
{
// Note: No indexing is performed here. The indexing is
// triggered in the postSave step of the revision to ensure
// that the page as a given revision in the database when
// doing the indexing.
if ($create) {
IDF_Timeline::insert($this, $this->get_project(),
$this->get_submitter());
}
}
/**
* Returns an HTML fragment used to display this wikipage in the
* timeline.
*
* The request object is given to be able to check the rights and
* as such create links to other items etc. You can consider that
* if displayed, you can create a link to it.
*
* @param Pluf_HTTP_Request
* @return Pluf_Template_SafeString
*/
public function timelineFragment($request)
{
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::view',
array($request->project->shortname,
$this->title));
$out = '<tr class="log"><td><a href="'.$url.'">'.
Pluf_esc(Pluf_Template_dateAgo($this->creation_dtime, 'without')).
'</a></td><td>';
$submitter = $this->get_submitter();
$out .= sprintf(__('<a href="%1$s" title="View page">%2$s</a>, %3$s'), $url, Pluf_esc($this->title), Pluf_esc($this->summary)).'</td>';
$out .= "\n".'<tr class="extra"><td colspan="2">
<div class="helptext right">'.sprintf(__('Creation of <a href="%s">page&nbsp;%s</a>'), $url, Pluf_esc($this->title)).', '.__('by').' '.Pluf_esc($submitter).'</div></td></tr>';
return Pluf_Template::markSafe($out);
}
}
src/IDF/WikiRevision.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
<?php
/* -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
# ***** BEGIN LICENSE BLOCK *****
# This file is part of InDefero, an open source project management application.
# Copyright (C) 2008 Céondo Ltd and contributors.
#
# InDefero is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# InDefero is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# ***** END LICENSE BLOCK ***** */
/**
* A revision of a wiki page.
*
*/
class IDF_WikiRevision extends Pluf_Model
{
public $_model = __CLASS__;
function init()
{
$this->_a['table'] = 'idf_wikirevisions';
$this->_a['model'] = __CLASS__;
$this->_a['cols'] = array(
// It is mandatory to have an "id" column.
'id' =>
array(
'type' => 'Pluf_DB_Field_Sequence',
'blank' => true,
),
'wikipage' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'IDF_WikiPage',
'blank' => false,
'verbose' => __('page'),
'relate_name' => 'revisions',
),
'is_head' =>
array(
'type' => 'Pluf_DB_Field_Boolean',
'blank' => false,
'default' => false,
'help_text' => 'If this revision is the latest, we mark it as being the head revision.',
'index' => true,
),
'summary' =>
array(
'type' => 'Pluf_DB_Field_Varchar',
'blank' => false,
'size' => 250,
'verbose' => __('summary'),
'help_text' => __('A one line description of the changes.'),
),
'content' =>
array(
'type' => 'Pluf_DB_Field_Compressed',
'blank' => false,
'verbose' => __('content'),
),
'submitter' =>
array(
'type' => 'Pluf_DB_Field_Foreignkey',
'model' => 'Pluf_User',
'blank' => false,
'verbose' => __('submitter'),
),
'changes' =>
array(
'type' => 'Pluf_DB_Field_Serialized',
'blank' => true,
'verbose' => __('changes'),
'help_text' => 'Serialized array of the changes in the issue.',
),
'creation_dtime' =>
array(
'type' => 'Pluf_DB_Field_Datetime',
'blank' => true,
'verbose' => __('creation date'),
),
);
$this->_a['idx'] = array(
'creation_dtime_idx' =>
array(
'col' => 'creation_dtime',
'type' => 'normal',
),
);
}
function changedRevision()
{
return (is_array($this->changes) and count($this->changes) > 0);
}
function _toIndex()
{
return $this->content;
}
function preSave($create=false)
{
if ($this->id == '') {
$this->creation_dtime = gmdate('Y-m-d H:i:s');
$this->is_head = true;
}
}
function postSave($create=false)
{
if ($create) {
// Check if more than one revision for this page. We do
// not want to insert the first revision in the timeline
// as the page itself is inserted. We do not insert on
// update as update is performed to change the is_head
// flag.
$sql = new Pluf_SQL('wikipage=%s', array($this->wikipage));
$rev = Pluf::factory('IDF_WikiRevision')->getList(array('filter'=>$sql->gen()));
if ($rev->count() > 1) {
IDF_Timeline::insert($this, $this->get_wikipage()->get_project(),
$this->get_submitter());
foreach ($rev as $r) {
if ($r->id != $this->id and $r->is_head) {
$r->is_head = false;
$r->update();
}
}
}
$page = $this->get_wikipage();
$page->update(); // Will update the modification timestamp.
IDF_Search::index($page);
}
}
public function timelineFragment($request)
{
$page = $this->get_wikipage();
$url = Pluf_HTTP_URL_urlForView('IDF_Views_Wiki::view',
array($request->project->shortname,
$page->title));
$out = "\n".'<tr class="log"><td><a href="'.$url.'">'.
Pluf_esc(Pluf_Template_dateAgo($this->creation_dtime, 'without')).
'</a></td><td>';
$submitter = $this->get_submitter();
$out .= sprintf(__('<a href="%1$s" title="View page">%2$s</a>, %3$s'), $url, Pluf_esc($page->title), Pluf_esc($this->summary));
//$out .= '<strong>'.__('Summary:').'</strong>&nbsp;'.Pluf_esc($this->summary).' ';
if ($this->changedRevision()) {
$out .= '<div class="issue-changes-timeline">';
foreach ($this->changes as $w => $v) {
$out .= '<strong>';
switch ($w) {
case 'lb':
$out .= __('Labels:'); break;
}
$out .= '</strong>&nbsp;';
if ($w == 'lb') {
$out .= Pluf_esc(implode(', ', $v));
} else {
$out .= Pluf_esc($v);
}
$out .= ' ';
}
$out .= '</div>';
}
$out .= '</td></tr>';
$out .= "\n".'<tr class="extra"><td colspan="2">
<div class="helptext right">'.sprintf(__('Change of <a href="%s">%s</a>'), $url, Pluf_esc($page->title)).', '.__('by').' '.Pluf_esc($submitter).'</div></td></tr>';
return Pluf_Template::markSafe($out);
}
}
src/IDF/conf/idf.php-dist
161161
162162
163163
164
164165
165166
166167
167
168168
169169
170170
'hotkey' => 'IDF_Template_HotKey',
'issuetext' => 'IDF_Template_IssueComment',
'timeline' => 'IDF_Template_TimelineFragment',
'markdown' => 'IDF_Template_Markdown',
);
$cfg['template_modifiers'] = array(
'size' => 'IDF_Views_Source_PrettySize',
'markdown' => 'IDF_Template_Markdown_filter',
);
// available languages
src/IDF/conf/urls.php
147147
148148
149149
150
150
151151
152152
153153
154154
155155
156
156
157157
158158
159159
160160
161161
162
162
163163
164164
165165
166166
167167
168
168
169169
170170
171171
172172
173173
174
174
175175
176176
177177
178178
179179
180
180
181181
182182
183183
......
195195
196196
197197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
198224
199225
200226
......
254280
255281
256282
283
284
285
286
287
288
257289
258290
259291
// ---------- SCM ----------------------------------------
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/(\w+)/$#',
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/([\S^/]+)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Source',
'method' => 'treeBase');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/(\w+)/(.*)$#',
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/tree/([\S^/]+)/(.*)$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Source',
'method' => 'tree');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changes/(\w+)/$#',
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/changes/([\S^/]+)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Source',
'method' => 'changeLog');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/commit/(\w+)/$#',
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/commit/([\S^/]+)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Source',
'method' => 'commit');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/download/(\w+)/$#',
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/download/([\S^/]+)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Source',
'method' => 'download');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/file/(\w+)/(.*)$#',
$ctl[] = array('regex' => '#^/p/([\-\w]+)/source/file/([\S^/]+)/(.*)$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Source',
'model' => 'IDF_Views_Source_Svn',
'method' => 'changelogRev');
// ---------- WIKI -----------------------------------------
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Wiki',
'method' => 'index');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/create/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Wiki',
'method' => 'create');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/doc/update/(.*)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Wiki',
'method' => 'update');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/page/(.*)/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Wiki',
'method' => 'view');
// ---------- Downloads ------------------------------------
$ctl[] = array('regex' => '#^/p/([\-\w]+)/downloads/$#',
'model' => 'IDF_Views_Project',
'method' => 'adminDownloads');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/wiki/$#',
'base' => $base,
'priority' => 4,
'model' => 'IDF_Views_Project',
'method' => 'adminWiki');
$ctl[] = array('regex' => '#^/p/([\-\w]+)/admin/source/$#',
'base' => $base,
'priority' => 4,
src/IDF/relations.php
3030
3131
3232
33
34
35
3336
3437
$m['IDF_Upload'] = array('relate_to' => array('IDF_Project', 'Pluf_User'),
'relate_to_many' => array('IDF_Tag'));
$m['IDF_Search_Occ'] = array('relate_to' => array('IDF_Project'),);
$m['IDF_WikiPage'] = array('relate_to' => array('IDF_Project', 'Pluf_User'),
'relate_to_many' => array('IDF_Tag', 'Pluf_User'));
$m['IDF_WikiRevision'] = array('relate_to' => array('IDF_WikiPage', 'Pluf_User'));
return $m;
src/IDF/templates/idf/admin/base.html
33
44
55
6
76
7
8
89
910
1011
{block subtabs}
<div id="sub-tabs">
<a {if $inSummary}class="active" {/if}href="{url 'IDF_Views_Project::admin', array($project.shortname)}">{trans 'Project Summary'}</a> |
<a {if $inIssueTracking}class="active" {/if}href="{url 'IDF_Views_Project::adminIssues', array($project.shortname)}">{trans 'Issue Tracking'}</a> |
<a {if $inDownloads}class="active" {/if}href="{url 'IDF_Views_Project::adminDownloads', array($project.shortname)}">{trans 'Downloads'}</a> |
<a {if $inWiki}class="active" {/if}href="{url 'IDF_Views_Project::adminWiki', array($project.shortname)}">{trans 'Documentation'}</a> |
<a {if $inIssueTracking}class="active" {/if}href="{url 'IDF_Views_Project::adminIssues', array($project.shortname)}">{trans 'Issue Tracking'}</a> |
<a {if $inSource}class="active" {/if}href="{url 'IDF_Views_Project::adminSource', array($project.shortname)}">{trans 'Source'}</a> |
<a {if $inMembers}class="active" {/if}href="{url 'IDF_Views_Project::adminMembers', array($project.shortname)}">{trans 'Project Members'}</a> |
<a {if $inTabs}class="active" {/if}href="{url 'IDF_Views_Project::adminTabs', array($project.shortname)}">{trans 'Tabs Access'}</a>
src/IDF/templates/idf/admin/tabs.html
1818
1919
2020
21
22
23
24
25
26
2127
2228
2329
</td>
</tr>
<tr>
<th><strong>{$form.f.wiki_access_rights.labelTag}:</strong></th>
<td>{if $form.f.wiki_access_rights.errors}{$form.f.wiki_access_rights.fieldErrors}{/if}
{$form.f.wiki_access_rights|unsafe}
</td>
</tr>
<tr>
<th><strong>{$form.f.issues_access_rights.labelTag}:</strong></th>
<td>{if $form.f.issues_access_rights.errors}{$form.f.issues_access_rights.fieldErrors}{/if}
{$form.f.issues_access_rights|unsafe}
src/IDF/templates/idf/admin/wiki.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
{extends "idf/admin/base.html"}
{block docclass}yui-t1{assign $inWiki = true}{/block}
{block body}
<form method="post" action=".">
<table class="form" summary="">
<tr>
<td colspan="2"><strong>{$form.f.labels_wiki_predefined.labelTag}:</strong><br />
{if $form.f.labels_wiki_predefined.errors}{$form.f.labels_wiki_predefined.fieldErrors}{/if}
{$form.f.labels_wiki_predefined|unsafe}
</td>
</tr>
<tr>
<td colspan="2">{$form.f.labels_wiki_one_max.labelTag}:<br />
{if $form.f.labels_wiki_one_max.errors}{$form.f.labels_wiki_one_max.fieldErrors}{/if}
{$form.f.labels_wiki_one_max|unsafe}
</td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="{trans 'Save Changes'}" name="submit" />
</td>
</tr>
</table>
</form>
{/block}
{block context}
<div class="issue-submit-info">
{blocktrans}
<p><strong>Instructions:</strong></p>
<p>List one status value per line in desired sort-order.</p>
<p>Optionally, use an equals-sign to document the meaning of each status value.</p>
{/blocktrans}
</div>
{/block}
src/IDF/templates/idf/base.html
4343
4444
4545
46
4746
47
48
4849
4950
5051
<div id="main-tabs">
{if $project}
<a accesskey="1" href="{url 'IDF_Views_Project::home', array($project.shortname)}"{block tabhome}{/block}>{trans 'Project Home'}</a>
{if $hasIssuesAccess} <a href="{url 'IDF_Views_Issue::index', array($project.shortname)}"{block tabissues}{/block}>{trans 'Issues'}</a>{/if}
{if $hasDownloadsAccess} <a href="{url 'IDF_Views_Download::index', array($project.shortname)}"{block tabdownloads}{/block}>{trans 'Downloads'}</a>{/if}
{if $hasWikiAccess} <a href="{url 'IDF_Views_Wiki::index', array($project.shortname)}"{block tabwiki}{/block}>{trans 'Documentation'}</a>{/if}
{if $hasIssuesAccess} <a href="{url 'IDF_Views_Issue::index', array($project.shortname)}"{block tabissues}{/block}>{trans 'Issues'}</a>{/if}
{if $hasSourceAccess} <a href="{url 'IDF_Views_Source::treeBase', array($project.shortname, $project.getScmRoot())}"{block tabsource}{/block}>{trans 'Source'}</a>{/if}
{if $isOwner}
<a href="{url 'IDF_Views_Project::admin', array($project.shortname)}"{block tabadmin}{/block}>{trans 'Administer'}</a>{/if}{/if}
src/IDF/templates/idf/project/home.html
77
88
99
10
10
1111
1212
1313
</div>
{/block}
{block body}
{$project.description|markdown}
{markdown $project.description, $request}
{/block}
{block context}
{if count($downloads) > 0}
src/IDF/templates/idf/wiki/base.html
1
2
3
4
5
6
7
8
9
10
{extends "idf/base.html"}
{block tabwiki} class="active"{/block}
{block subtabs}
<div id="sub-tabs">
<a {if $inWiki}class="active" {/if}href="{url 'IDF_Views_Wiki::index', array($project.shortname)}">{trans 'List Pages'}</a>
{if !$user.isAnonymous()} | <a {if $inCreate}class="active" {/if}href="{url 'IDF_Views_Wiki::create', array($project.shortname)}">{trans 'New Page'}</a> {/if}
{if !$user.isAnonymous() and $inView} | <a href="{url 'IDF_Views_Wiki::update', array($project.shortname, $page.title)}">{trans 'Update This Page'}</a> {/if}
{superblock}
</div>
{/block}
src/IDF/templates/idf/wiki/create.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
{extends "idf/wiki/base.html"}
{block docclass}yui-t1{assign $inCreate = true}{/block}
{block body}
{if $preview}
<h2 class="top">{trans 'Preview of the Page'}</h2>
{markdown $preview, $request}
{/if}
{if $form.errors}
<div class="px-message-error">
<p>{trans 'The form contains some errors. Please correct them to create the page.'}</p>
{if $form.get_top_errors}
{$form.render_top_errors|unsafe}
{/if}
</div>
{/if}
<form method="post" enctype="multipart/form-data" action="." >
<table class="form" summary="">
<tr>
<th><strong>{$form.f.title.labelTag}:</strong></th>
<td>{if $form.f.title.errors}{$form.f.title.fieldErrors}{/if}
{$form.f.title|unsafe}<br />
<span class="helptext">{$form.f.title.help_text}</span>
</td>
</tr>
<tr>
<th><strong>{$form.f.summary.labelTag}:</strong></th>
<td>{if $form.f.summary.errors}{$form.f.summary.fieldErrors}{/if}
{$form.f.summary|unsafe}<br />
<span class="helptext">{$form.f.summary.help_text}</span>
</td>
</tr>
<tr>
<th><strong>{$form.f.content.labelTag}:</strong></th>
<td>{if $form.f.content.errors}{$form.f.content.fieldErrors}{/if}
{$form.f.content|unsafe}
</td>
</tr>{if $isOwner or $isMember}
<tr>
<th>{$form.f.label1.labelTag}:</th>
<td>
{if $form.f.label1.errors}{$form.f.label1.fieldErrors}{/if}{$form.f.label1|unsafe}
{if $form.f.label2.errors}{$form.f.label2.fieldErrors}{/if}{$form.f.label2|unsafe}
{if $form.f.label3.errors}{$form.f.label3.fieldErrors}{/if}{$form.f.label3|unsafe}
</td>
</tr>{/if}
<tr>
<td>&nbsp;</td>
<td><input type="submit" value="{trans 'Preview'}" name="preview" /> &nbsp; <input type="submit" value="{trans 'Create Page'}" name="submit" /> | <a href="{url 'IDF_Views_Wiki::index', array($project.shortname)}">{trans 'Cancel'}</a>
</td>
</tr>
</table>
</form>
{/block}
{block context}
<div class="issue-submit-info">
{include 'idf/wiki/edit-info.html'}
</div>
{/block}
{block javascript}
<script type="text/javascript">
document.getElementById('id_title').focus()
</script>
{include 'idf/wiki/js-autocomplete.html'}{/block}
src/IDF/templates/idf/wiki/edit-info.html
1
2
3
4
5
6
{assign $url = 'http://daringfireball.net/projects/markdown/syntax'}
{blocktrans}
<p><strong>Instructions:</strong></p>
<p>The content of the page can use the <a href="{$url}">Markdown syntax</a>.</p>
<p>Website addresses are automatically linked and you can link to another page in the documentation using double square brackets like that [[AnotherPage]].</p>
{/blocktrans}
src/IDF/templates/idf/wiki/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
{extends "idf/wiki/base.html"}
{block docclass}yui-t1{assign $inWiki=true}{/block}
{block body}
{$pages.render}
{if !$user.isAnonymous()}
{aurl 'url', 'IDF_Views_Wiki::create', array($project.shortname)}
<p><a href="{$url}"><img style="vertical-align: text-bottom;" src="{media '/idf/img/add.png'}" alt="+" align="bottom" /></a> <a href="{$url}">{trans 'New Page'}</a></p>{/if}
{/block}
{block context}
<p><strong>{trans 'Number of pages:'}</strong> {$pages.nb_items}</p>
{/block}
src/IDF/templates/idf/wiki/js-autocomplete.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
{if $isOwner or $isMember}
<script type="text/javascript" src="{media '/idf/js/jquery.bgiframe.min.js'}"></script>
<script type="text/javascript" src="{media '/idf/js/jquery.autocomplete.min.js'}"></script>
<script type="text/javascript" charset="utf-8">
// <!-- {literal}
$(document).ready(function(){
var auto_labels = [{/literal}{$auto_labels|safe}{literal}];
var j=0;
for (j=1;j<4;j=j+1) {
$("#id_label"+j).autocomplete(auto_labels, {
minChars: 0,
width: 310,
matchContains: true,
max: 50,
highlightItem: false,
formatItem: function(row, i, max, term) {
return row.to.replace(new RegExp("(" + term + ")", "gi"), "<strong>$1</strong>") + " <span style='font-size: 80%;'>" + row.name + "</span>";
},
formatResult: function(row) {
return row.to;
}
});
}
});
{/literal} //-->
</script>
{/if}
src/IDF/templates/idf/wiki/update.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
{extends "idf/wiki/base.html"}
{block docclass}yui-t2{/block}
{block body}
{if $preview}
<h2 class="top">{trans 'Preview of the Page'}</h2>
{markdown $preview, $request}
{/if}
{if $form.errors}
<div class="px-message-error">
<p>{trans 'The form contains some errors. Please correct them to update the page.'}</p>
{if $form.get_top_errors}
{$form.render_top_errors|unsafe}
{/if}
</div>
{/if}
<form method="post" enctype="multipart/form-data" action="." >
<table class="form" summary="">{if $isOwner or $isMember}
<tr>
<th><strong>{$form.f.title.labelTag}:</strong></th>
<td>{if $form.f.title.errors}{$form.f.title.fieldErrors}{/if}
{$form.f.title|unsafe}<br />
<span class="helptext">{$form.f.title.help_text}</span>
</td>
</tr>
<tr>
<th><strong>{$form.f.summary.labelTag}:</strong></th>
<td>{if $form.f.summary.errors}{$form.f.summary.fieldErrors}{/if}
{$form.f.summary|unsafe}<br />
<span class="helptext">{$form.f.summary.help_text}</span>
</td>
</tr>{/if}
<tr>
<th><strong>{$form.f.content.labelTag}:</strong></th>
<td>{if $form.f.content.errors}{$form.f.content.fieldErrors}{/if}
{$form.f.content|unsafe}
</td>
</tr>
<tr>
<th><strong>{$form.f.comment.labelTag}:</strong></th>
<td>{if $form.f.comment.errors}{$form.f.comment.fieldErrors}{/if}
{$form.f.comment|unsafe}<br />
<span class="helptext">{$form.f.comment.help_text}</span>
</td>
</tr>{if $isOwner or $isMember}
<tr>
<th>{$form.f.label1.labelTag}:</th>
<td>
{if $form.f.label1.errors}{$form.f.label1.fieldErrors}{/if}{$form.f.label1|unsafe}
{if $form.f.label2.errors}{$form.f.label2.fieldErrors}{/if}{$form.f.label2|unsafe}
{if $form.f.label3.errors}{$form.f.label3.fieldErrors}{/if}{$form.f.label3|unsafe}
</td>
</tr>{/if}
<tr>
<td>&nbsp;</td>
<td><input type="submit" value="{trans 'Preview'}" name="preview" /> &nbsp; <input type="submit" value="{trans 'Update Page'}" name="submit" /> | <a href="{url 'IDF_Views_Wiki::index', array($project.shortname)}">{trans 'Cancel'}</a>
</td>
</tr>
</table>
</form>
{/block}
{block context}
<div class="issue-submit-info">
{include 'idf/wiki/edit-info.html'}
</div>
{/block}
{block javascript}
{include 'idf/wiki/js-autocomplete.html'}{/block}
src/IDF/templates/idf/wiki/view.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{extends "idf/wiki/base.html"}
{block docclass}yui-t3{assign $inView=true}{/block}
{block body}
<p class="desc">{$page.summary}</p>
{markdown $rev.content, $request}
{/block}
{block context}
{assign $submitter = $page.get_submitter()}
<p><strong>{trans 'Created:'}</strong> <span class="nobrk">{$page.creation_dtime|dateago}</span><br /><span class="nobrk">{blocktrans}by {$submitter}{/blocktrans}</span></p>
{if $rev.creation_dtime != $page.creation_dtime}<p>{assign $submitter = $rev.get_submitter()}
<strong>{trans 'Updated:'}</strong> <span class="nobrk">{$rev.creation_dtime|dateago}</span><br /><span class="nobrk">{blocktrans}by {$submitter}{/blocktrans}</span></p>{/if}
{if $tags.count()}
<p>
<strong>{trans 'Labels:'}</strong><br />
{foreach $tags as $tag}
<span class="label"><strong>{$tag.class}:</strong>{$tag.name}</span><br />
{/foreach}
</p>{/if}
{/block}
www/media/idf/css/style.css
578578
579579
580580
581
582
583
584
585
586
587
588
589
590
591
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
}
/**
* Wiki
*/
p.desc {
background-color: #eeeeec;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
padding: 4px;
width: 60%;
}

Archive Download the corresponding diff file

Page rendered in 0.21529s using 14 queries.