3 * Laconica, the distributed open-source microblogging tool
5 * Low-level generator for HTML
9 * LICENCE: This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 * @author Evan Prodromou <evan@controlyourself.ca>
25 * @author Sarven Capadisli <csarven@controlyourself.ca>
26 * @copyright 2008 Control Yourself, Inc.
27 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
28 * @link http://laconi.ca/
31 if (!defined('LACONICA')) {
35 require_once INSTALLDIR.'/lib/xmloutputter.php';
37 define('PAGE_TYPE_PREFS',
38 'text/html,application/xhtml+xml,'.
39 'application/xml;q=0.3,text/xml;q=0.2');
42 * Low-level generator for HTML
44 * Abstracts some of the code necessary for HTML generation. Especially
45 * has methods for generating HTML form elements. Note that these have
46 * been created kind of haphazardly, not with an eye to making a general
47 * HTML-creation class.
51 * @author Evan Prodromou <evan@controlyourself.ca>
52 * @author Sarven Capadisli <csarven@controlyourself.ca>
53 * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
54 * @link http://laconi.ca/
59 class HTMLOutputter extends XMLOutputter
64 * Just wraps the XMLOutputter constructor.
66 * @param string $output URI to output to, default = stdout
67 * @param boolean $indent Whether to indent output, default true
70 function __construct($output='php://output', $indent=true)
72 parent::__construct($output, $indent);
76 * Start an HTML document
78 * If $type isn't specified, will attempt to do content negotiation.
80 * Attempts to do content negotiation for language, also.
82 * @param string $type MIME type to use; default is to do negotation.
84 * @todo extract content negotiation code to an HTTP module or class.
89 function startHTML($type=null)
92 $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ?
93 $_SERVER['HTTP_ACCEPT'] : null;
95 // XXX: allow content negotiation for RDF, RSS, or XRDS
97 $cp = common_accept_to_prefs($httpaccept);
98 $sp = common_accept_to_prefs(PAGE_TYPE_PREFS);
100 $type = common_negotiate_type($cp, $sp);
103 common_user_error(_('This page is not available in a '.
104 'media type you accept'), 406);
109 header('Content-Type: '.$type);
111 $this->startXML('html',
112 '-//W3C//DTD XHTML 1.0 Strict//EN',
113 'http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd');
115 // FIXME: correct language for interface
117 $language = common_language();
119 $this->elementStart('html', array('xmlns' => 'http://www.w3.org/1999/xhtml',
120 'xml:lang' => $language,
121 'lang' => $language));
125 * Output an HTML text input element
127 * Despite the name, it is specifically for outputting a
128 * text input element, not other <input> elements. It outputs
129 * a cluster of elements, including a <label> and an associated
132 * @param string $id element ID, must be unique on page
133 * @param string $label text of label for the element
134 * @param string $value value of the element, default null
135 * @param string $instructions instructions for valid input
137 * @todo add a $name parameter
138 * @todo add a $maxLength parameter
139 * @todo add a $size parameter
144 function input($id, $label, $value=null, $instructions=null)
146 $this->elementStart('p');
147 $this->element('label', array('for' => $id), $label);
148 $attrs = array('name' => $id,
150 'class' => 'input_text',
153 $attrs['value'] = htmlspecialchars($value);
155 $this->element('input', $attrs);
157 $this->element('span', 'input_instructions', $instructions);
159 $this->elementEnd('p');
163 * output an HTML checkbox and associated elements
165 * Note that the value is default 'true' (the string), which can
166 * be used by Action::boolean()
168 * @param string $id element ID, must be unique on page
169 * @param string $label text of label for the element
170 * @param string $checked if the box is checked, default false
171 * @param string $instructions instructions for valid input
172 * @param string $value value of the checkbox, default 'true'
173 * @param string $disabled show the checkbox disabled, default false
177 * @todo add a $name parameter
180 function checkbox($id, $label, $checked=false, $instructions=null,
181 $value='true', $disabled=false)
183 $this->elementStart('p');
184 $attrs = array('name' => $id,
185 'type' => 'checkbox',
186 'class' => 'checkbox',
189 $attrs['value'] = htmlspecialchars($value);
192 $attrs['checked'] = 'checked';
195 $attrs['disabled'] = 'true';
197 $this->element('input', $attrs);
199 $this->element('label', array('class' => 'checkbox_label',
204 $this->element('span', 'input_instructions', $instructions);
206 $this->elementEnd('p');
210 * output an HTML combobox/select and associated elements
212 * $content is an array of key-value pairs for the dropdown, where
213 * the key is the option value attribute and the value is the option
214 * text. (Careful on the overuse of 'value' here.)
216 * @param string $id element ID, must be unique on page
217 * @param string $label text of label for the element
218 * @param array $content options array, value => text
219 * @param string $instructions instructions for valid input
220 * @param string $blank_select whether to have a blank entry, default false
221 * @param string $selected selected value, default null
225 * @todo add a $name parameter
228 function dropdown($id, $label, $content, $instructions=null,
229 $blank_select=false, $selected=null)
231 $this->elementStart('p');
232 $this->element('label', array('for' => $id), $label);
233 $this->elementStart('select', array('id' => $id, 'name' => $id));
235 $this->element('option', array('value' => ''));
237 foreach ($content as $value => $option) {
238 if ($value == $selected) {
239 $this->element('option', array('value' => $value,
240 'selected' => $value),
243 $this->element('option', array('value' => $value), $option);
246 $this->elementEnd('select');
248 $this->element('span', 'input_instructions', $instructions);
250 $this->elementEnd('p');
254 * output an HTML hidden element
256 * $id is re-used as name
258 * @param string $id element ID, must be unique on page
259 * @param string $value hidden element value, default null
263 * @todo add a $name parameter
266 function hidden($id, $value)
268 $this->element('input', array('name' => $id,
275 * output an HTML password input and associated elements
277 * @param string $id element ID, must be unique on page
278 * @param string $label text of label for the element
279 * @param string $instructions instructions for valid input
283 * @todo add a $name parameter
286 function password($id, $label, $instructions=null)
288 $this->elementStart('p');
289 $this->element('label', array('for' => $id), $label);
290 $attrs = array('name' => $id,
291 'type' => 'password',
292 'class' => 'password',
294 $this->element('input', $attrs);
296 $this->element('span', 'input_instructions', $instructions);
298 $this->elementEnd('p');
302 * output an HTML submit input and associated elements
304 * @param string $id element ID, must be unique on page
305 * @param string $label text of the button
306 * @param string $cls class of the button, default 'submit'
310 * @todo add a $name parameter
313 function submit($id, $label, $cls='submit')
315 $this->elementStart('p');
316 $this->element('input', array('type' => 'submit',
321 $this->elementEnd('p');
325 * output an HTML textarea and associated elements
327 * @param string $id element ID, must be unique on page
328 * @param string $label text of label for the element
329 * @param string $content content of the textarea, default none
330 * @param string $instructions instructions for valid input
334 * @todo add a $name parameter
335 * @todo add a $cols parameter
336 * @todo add a $rows parameter
339 function textarea($id, $label, $content=null, $instructions=null)
341 $this->elementStart('p');
342 $this->element('label', array('for' => $id), $label);
343 $this->element('textarea', array('rows' => 3,
347 ($content) ? $content : '');
349 $this->element('span', 'input_instructions', $instructions);
351 $this->elementEnd('p');