function controller_pages($args) { default_html(true); html_add_css(base_url() . 'modules/page_browser/page_browser.css'); if (USE_MIN_FILES) { html_add_js(base_url() . 'modules/page_browser/page_browser.min.js'); } else { html_add_js(base_url() . 'modules/page_browser/page_browser.js'); } html_add_js_var('$.glue.conf.page.startpage', startpage()); $bdy =& body(); elem_attr($bdy, 'id', 'pages'); body_append('<h1>All pages</h1>'); load_modules('glue'); $pns = pagenames(array()); $pns = $pns['#data']; foreach ($pns as $pn) { // display only pages with 'head' if (is_dir(CONTENT_DIR . '/' . $pn . '/head')) { body_append('<div class="page_browser_entry" id="' . htmlspecialchars($pn, ENT_COMPAT, 'UTF-8') . '"><span class="page_browser_pagename"><a href="' . base_url() . '?' . htmlspecialchars(urlencode($pn), ENT_COMPAT, 'UTF-8') . '">' . htmlspecialchars($pn, ENT_NOQUOTES, 'UTF-8') . '</a></span> '); if ($pn . '.head' == startpage()) { body_append('<span id="page_browser_startpage">[startpage]</span> '); } } body_append('</div>'); } echo html_finalize(); }
function welcome_render_page_late($args) { global $page_has_object; if (!$args['edit'] || $page_has_object) { return false; } // we only display the information when there are no other pages in the // content directory except the current one load_modules('glue'); $pns = pagenames(array()); $pns = $pns['#data']; if (1 < count($pns)) { return false; } html_add_css(base_url() . 'modules/welcome/welcome-edit.css'); html_add_js(base_url() . 'modules/welcome/welcome.js'); body_append('<div id="welcome-msg">' . nl()); body_append(tab() . '<span id="welcome-first"><img style="float:left; margin:5px 10px 0 5px" src="' . base_url() . 'modules/welcome/gun32.gif">Welcome to HOTGLUE!</span><br>' . nl()); body_append(tab() . 'Your Content Manipulation System is ready to go!' . nl()); body_append(tab() . '<p>A short intro before you start:</p>' . nl()); body_append(tab() . '<span id="cont"><span id="text"><b>1.</b> Right now you are in <u>editing mode</u>. You can use single and double click to access the menus - they will appear next to the mouse pointer.</span>' . nl()); body_append(tab() . '<span id="text"><b>2.</b> Click on the canvas (white background of the page) to open a menu which will let you create new objects, upload files and embed YouTube and Vimeo videos! Once you made an object click on it to activate its contextual menu.</span>' . nl()); body_append(tab() . '<span id="text"><b>3.</b> Double-click on the canvas will give you a menu of options to change preferences, show a grid, make new pages, set background picture and more!</span>' . nl()); body_append(tab() . '<span id="text"><b>4.</b> Remove "' . (SHORT_URLS ? '' : '?') . 'edit" from the address of the page (the URL) to see the "view-only" version. That\'s how your page will look to everyone else!</span>' . nl()); body_append(tab() . '<span id="text"><b>5.</b> To get back to editing mode add "' . (SHORT_URLS ? '' : '?') . 'edit" to the URL of the page.<br>(for example: ' . base_url() . '<b>' . (SHORT_URLS ? '' : '?') . 'edit</b>)</span></span>' . nl()); body_append(tab() . '<p>We recommend you to use <a href="http://firefox.com" target="_blank">Mozilla Firefox</a> browser when editing in HOTGLUE. Firefox is a very reliable and modern web-browser, it is our favorite!' . nl()); body_append(tab() . '<p>You can find more information on how to work with HOTGLUE on our <a href="http://hotglue.me" target="_blank">web-site</a>. Make sure to check out "<a href="http://hotglue.me/what" target="_blank">What is HOTGLUE?</a>" and "<a href="http://hotglue.me/how" target="_blank">How to HOTGLUE?</a>" pages!' . nl()); body_append(tab() . '<p>Enjoy! <span id="welcome-light">[click this message to make it go away]</span></p>' . nl()); body_append('</div>' . nl()); return true; }
function welcome_render_page_late($args) { global $page_has_object; if (!$args['edit'] || $page_has_object) { return false; } // we only display the information when there are no other pages in the // content directory except the current one load_modules('glue'); $pns = pagenames(array()); $pns = $pns['#data']; if (1 < count($pns)) { return false; } html_add_css(base_url() . 'modules/welcome/welcome-edit.css'); html_add_js(base_url() . 'modules/welcome/welcome.js'); body_append('<div id="welcome-msg">' . nl()); body_append(tab() . '<span id="welcome-first">Welcome to HOTGLUE!</span><br>' . nl()); body_append(tab() . 'Your Content Manipulation System is ready to go!' . nl()); body_append(tab() . '<p>A short intro before you start:<br>' . nl()); body_append(tab() . '¤ To get back to editing mode in the future, add "' . (SHORT_URLS ? '' : '?') . 'edit" to the address in the address bar (i.e.: ' . base_url() . '<b>' . (SHORT_URLS ? '' : '?') . 'edit</b>)<br>' . nl()); body_append(tab() . '¤ In editing mode, you can use single and double click to access the menus.<br>' . nl()); body_append(tab() . '¤ Click the page\'s background once to open a menu that lets you create new objects, upload files and embed videos (YouTube and Vimeo).<br>' . nl()); body_append(tab() . '¤ Double-click to open a menu that allows you to change preferences, show a grid, make new pages and more.<br>' . nl()); body_append(tab() . '¤ Remove "' . (SHORT_URLS ? '' : '?') . 'edit" from the address in the address bar to go to the viewing-only mode of this page.</p>' . nl()); body_append(tab() . '<p>You can find more ideas on how to use HOTGLUE at the <a href="http://hotglue.me/how_basic" target="_blank">"How-to" section of our website</a>!' . nl()); body_append(tab() . '<p>Enjoy!<br>' . nl()); body_append(tab() . '<span id="welcome-light">[This message goes away when you click it]</span></p>' . nl()); body_append('</div>' . nl()); return true; }
function controller_revisions($args) { page_canonical($args[0][0]); $page = $args[0][0]; if (!page_exists($page)) { hotglue_error(404); } // get all revisions of page and determine the current revision's index load_modules('glue'); $a = expl('.', $page); $revs = revisions_info(array('pagename' => $a[0], 'sort' => 'time')); $revs = $revs['#data']; $cur_rev = false; for ($i = 0; $i < count($revs); $i++) { if ($revs[$i]['revision'] == $a[1]) { $cur_rev = $i; break; } } if ($cur_rev === false) { // we didn't find the current revision hotglue_error(500); } default_html(true); html_add_css(base_url() . 'modules/revisions_browser/revisions_browser.css'); if (USE_MIN_FILES) { html_add_js(base_url() . 'modules/revisions_browser/revisions_browser.min.js'); } else { html_add_js(base_url() . 'modules/revisions_browser/revisions_browser.js'); } html_add_js_var('$.glue.page', $page); $bdy =& body(); elem_attr($bdy, 'id', 'revisions'); render_page(array('page' => $page, 'edit' => false)); body_append('<div id="revisions_browser_ctrl">'); body_append('<div id="revisions_browser_prev">'); if ($cur_rev + 1 < count($revs)) { body_append('<a href="' . base_url() . '?' . htmlspecialchars(urlencode($revs[$cur_rev + 1]['page']), ENT_COMPAT, 'UTF-8') . '/revisions">prev</a>'); } body_append('</div><div id="revisions_browser_cur">'); if (substr($revs[$cur_rev]['revision'], 0, 5) == 'auto-') { body_append(date('d M y H:i', $revs[$cur_rev]['time'])); } else { body_append(htmlspecialchars($revs[$cur_rev]['revision'], ENT_NOQUOTES, 'UTF-8')); } body_append('<br>'); if ($a[1] == 'head') { body_append('<a href="' . base_url() . '?' . htmlspecialchars(urlencode($page), ENT_COMPAT, 'UTF-8') . '/edit">back to editing mode</a>'); } else { body_append('<a id="revisions_browser_revert_btn" href="#">revert</a>'); } body_append('</div><div id="revisions_browser_next">'); if (0 < $cur_rev) { body_append('<a href="' . base_url() . '?' . htmlspecialchars(urlencode($revs[$cur_rev - 1]['page']), ENT_COMPAT, 'UTF-8') . '/revisions">next</a>'); } body_append('</div>'); body_append('</div>'); echo html_finalize(); }
/** * controller that shows a textarea for editing either a page's or the global * user-defined css file */ function controller_user_css_stylesheet($args) { if ($args[0][1] == 'stylesheet') { // changing page stylesheet $page = $args[0][0]; page_canonical($page); if (!page_exists($page)) { hotglue_error(404); } } else { // changing global stylesheet $page = false; } default_html(true); html_add_js_var('$.glue.page', $page); html_add_css(base_url() . 'modules/user_css/user_css.css'); if (USE_MIN_FILES) { html_add_js(base_url() . 'modules/user_css/user_css.min.js'); } else { html_add_js(base_url() . 'modules/user_css/user_css.js'); } $bdy =& body(); elem_attr($bdy, 'id', 'user_css'); if ($page === false) { body_append('<h1>Global stylesheet</h1>' . nl()); // try to load css $css = @file_get_contents(CONTENT_DIR . '/usercss'); if ($css === false) { $css = ''; } } else { body_append('<h1>' . htmlspecialchars($page, ENT_NOQUOTES, 'UTF-8') . ' stylesheet</h1>' . nl()); load_modules('glue'); $obj = load_object(array('name' => $page . '.usercss')); if ($obj['#error']) { $css = ''; } else { $css = $obj['#data']['content']; } } // encoding to html must come before the replacement below $css = htmlspecialchars($css, ENT_NOQUOTES, 'UTF-8'); // replace newline characters by an entity to prevent render_object() // from adding some indentation $css = str_replace("\r\n", ' ', $css); $css = str_replace("\n", ' ', $css); // why not replace tabs as well why we are at it $css = str_replace("\t", '	', $css); body_append('<textarea id="user_css_text" placeholder="enter css code here">' . $css . '</textarea>' . nl()); body_append('<br>' . nl()); body_append('<input id="user_css_save" type="button" value="save">' . nl()); echo html_finalize(); }
/** * show a site where authenticated users can create new pages */ function controller_create_page($args) { page_canonical($args[0][0]); $page = $args[0][0]; if (page_exists($page)) { log_msg('debug', 'controller_create_page: page ' . quot($page) . 'already exists, invoking controller_edit'); controller_edit($args); return; } load_modules('glue'); default_html(true); html_add_css(base_url() . 'css/hotglue_error.css'); if (USE_MIN_FILES) { html_add_js(base_url() . 'js/create_page.min.js'); } else { html_add_js(base_url() . 'js/create_page.js'); } html_add_js_var('$.glue.page', $page); html_add_js_var('$.glue.q', SHORT_URLS ? '' : '?'); $bdy =& body(); elem_attr($bdy, 'id', 'create_page'); body_append(tab(1) . '<div id="paper">' . nl()); body_append(tab(2) . '<div id="wrapper">' . nl()); body_append(tab(3) . '<div id="content">' . nl()); body_append(tab(4) . '<div id="left-nav">' . nl()); body_append(tab(5) . '<img src="' . htmlspecialchars(base_url(), ENT_COMPAT, 'UTF-8') . 'img/hotglue-logo.png" alt="logo">' . nl()); body_append(tab(4) . '</div>' . nl()); body_append(tab(4) . '<div id="main">' . nl()); body_append(tab(5) . '<h1 id="error-title">Page does not exist yet!</h1>' . nl()); body_append(tab(5) . '<p>' . nl()); body_append(tab(6) . 'This page does not exist yet!<br>' . nl()); body_append(tab(6) . 'Would you like to create the page?' . nl()); body_append(tab(5) . '</p>' . nl()); body_append(tab(5) . '<form><input id="create_page_btn" type="button" value="Create it!"></form>' . nl()); body_append(tab(4) . '</div>' . nl()); body_append(tab(3) . '</div>' . nl()); body_append(tab(2) . '</div>' . nl()); body_append(tab(2) . '<div style="position: absolute; left: 200px; top: -10px; z-index: 2;">' . nl()); body_append(tab(3) . '<img src="' . htmlspecialchars(base_url(), ENT_COMPAT, 'UTF-8') . 'img/hotglue-404.png" alt="404">' . nl()); body_append(tab(2) . '</div>' . nl()); body_append(tab(1) . '</div>' . nl()); echo html_finalize(); }
/** * controller that shows a textarea for editing either a page's or the global * user-defined code files */ function controller_user_code_stylesheet($args) { if ($args[0][1] == 'code') { // changing page code $page = $args[0][0]; page_canonical($page); if (!page_exists($page)) { hotglue_error(404); } } else { // changing global code $page = false; } default_html(true); html_add_js_var('$.glue.page', $page); html_add_css(base_url() . 'modules/user_code/user_code.css'); if (USE_MIN_FILES) { html_add_js(base_url() . 'modules/user_code/user_code.min.js'); } else { html_add_js(base_url() . 'modules/user_code/user_code.js'); } $bdy =& body(); // create array with names of code elements $code = array('head' => '', 'body' => ''); elem_attr($bdy, 'id', 'user_code'); if ($page === false) { body_append('<h1>Global code</h1>' . nl()); // try to load code foreach ($code as $x => $v) { $code[$x] = @file_get_contents(CONTENT_DIR . '/user' . $x); if ($code[$x] === false) { $code[$x] = ''; } } } else { body_append('<h1>"' . htmlspecialchars(substr($page, 0, strpos($page, '.')), ENT_NOQUOTES, 'UTF-8') . '" page code</h1>' . nl()); load_modules('glue'); foreach ($code as $x => $v) { $obj = load_object(array('name' => $page . '.user' . $x)); if ($obj['#error']) { $code[$x] = ''; } else { $code[$x] = $obj['#data']['content']; } } } foreach ($code as $k => $v) { // encoding to html must come before the replacement below $v = htmlspecialchars($v, ENT_NOQUOTES, 'UTF-8'); // replace newline characters by an entity to prevent render_object() // from adding some indentation $v = str_replace("\r\n", ' ', $v); $v = str_replace("\n", ' ', $v); // why not replace tabs as well why we are at it $v = str_replace("\t", '	', $v); $code[$k] = $v; } body_append('<div id=\'text\'>add your custom code to <head> and <body> sections of this ' . ($page ? 'page.' : 'site.') . nl()); body_append('<br>' . nl()); body_append('be cautious - errors in the code below may render the whole ' . ($page ? 'page' : 'site') . ' unusable.</div>' . nl()); body_append('<br>' . nl()); body_append('<div id=\'fake_tags\'><head></div>' . nl()); body_append('<textarea id="user_head_text" placeholder="enter code here">' . $code['head'] . '</textarea>' . nl()); body_append('<br>' . nl()); body_append('<div id=\'fake_tags\'></head><br>' . nl()); body_append('<body></div>' . nl()); body_append('<textarea id="user_body_text" placeholder="enter code here">' . $code['body'] . '</textarea>' . nl()); body_append('<div id=\'fake_tags\'></body></div><br>' . nl()); body_append('<input id="user_code_save" type="button" value="save">' . nl()); echo html_finalize(); }
/** * turn an object into an html string * * the function also appends the resulting string to the output in * html.inc.php. * @param array $args arguments * string 'name' is the object name (i.e. page.rev.obj) * bool 'edit' are we editing or not * @return array response * html */ function render_object($args) { // maybe move this to common.inc.php in the future and get rid of some of // these checks in the beginning $obj = load_object($args); if ($obj['#error']) { return $obj; } else { $obj = $obj['#data']; } if (!isset($args['edit'])) { return response('Required argument "edit" missing', 400); } if ($args['edit']) { $args['edit'] = true; } else { $args['edit'] = false; } log_msg('debug', 'render_object: rendering ' . quot($args['name'])); $ret = invoke_hook_while('render_object', false, array('obj' => $obj, 'edit' => $args['edit'])); if (empty($ret)) { log_msg('warn', 'render_object: nobody claimed ' . quot($obj['name'])); return response(''); } else { $temp = array_keys($ret); log_msg('debug', 'render_object: ' . quot($obj['name']) . ' was handled by ' . quot($temp[0])); $temp = array_values($ret); // make sure object has a tailing newline if (0 < strlen($temp[0]) && substr($temp[0], -1) != "\n") { $temp[0] .= nl(); } body_append($temp[0]); // return the element as html-string as well return response($temp[0]); } }
/** * return a hotglue-themed error message to the client * * the function does not return if successful. * @param int $code error code * @param bool $no_header don't output any header * @return false if the error code is not supported yet */ function hotglue_error($code, $no_header = false) { if (!$no_header) { // output header if (USE_HOTGLUE_ERRORS) { $header_only = true; } else { $header_only = false; } if (!http_error($code, $header_only)) { return false; } } // output informative message html_flush(); default_html(false); html_add_css(base_url() . 'css/hotglue_error.css'); $bdy =& body(); elem_attr($bdy, 'id', 'hotglue_error'); body_append(tab(1) . '<div id="paper">' . nl()); body_append(tab(2) . '<div id="wrapper">' . nl()); body_append(tab(3) . '<div id="content">' . nl()); body_append(tab(4) . '<div id="left-nav">' . nl()); body_append(tab(5) . '<img src="' . htmlspecialchars(base_url(), ENT_COMPAT, 'UTF-8') . 'img/hotglue-logo.png" alt="logo">' . nl()); body_append(tab(4) . '</div>' . nl()); body_append(tab(4) . '<div id="main">' . nl()); if ($code == 400) { body_append(tab(5) . '<h1 id="error-title">ERROR 400, bad request!</h1>' . nl()); } elseif ($code == 401) { body_append(tab(5) . '<h1 id="error-title">Authorization required!</h1>' . nl()); } elseif ($code == 404) { body_append(tab(5) . '<h1 id="error-title">ERROR 404, not found!</h1>' . nl()); } elseif ($code == 500) { body_append(tab(5) . '<h1 id="error-title">ERROR 500, server fault!</h1>' . nl()); } body_append(tab(5) . '<p>' . nl()); if ($code == 400) { body_append(tab(6) . 'Something got screwed up...<br>' . nl()); body_append(tab(6) . 'The page is sending a bad request to the server!' . nl()); } elseif ($code == 401) { body_append(tab(6) . 'You need to be logged in in order to do this.<br>' . nl()); } elseif ($code == 404) { body_append(tab(6) . 'It looks like you got lost in cyber-space...<br>' . nl()); body_append(tab(6) . 'The page you are trying to reach does not exist!' . nl()); } elseif ($code == 500) { body_append(tab(6) . 'Are we runnining out of fuel?!<br>' . nl()); body_append(tab(6) . 'Something is causing serious server errors!' . nl()); } body_append(tab(5) . '</p>' . nl()); body_append(tab(6) . '<a href="' . htmlspecialchars(base_url(), ENT_COMPAT, 'UTF-8') . '" id="home">take me home!</a>' . nl()); body_append(tab(4) . '</div>' . nl()); body_append(tab(3) . '</div>' . nl()); body_append(tab(2) . '</div>' . nl()); body_append(tab(2) . '<div style="position: absolute; left: 200px; top: -10px; z-index: 2;">' . nl()); body_append(tab(3) . '<img src="' . htmlspecialchars(base_url(), ENT_COMPAT, 'UTF-8') . 'img/hotglue-404.png" alt="404">' . nl()); body_append(tab(2) . '</div>' . nl()); body_append(tab(1) . '</div>' . nl()); echo html_finalize(); die; }
/** * turn the page into a html string * * @param bool &$cache is output cachable (will only modified if $cache is * true before) * @return string html */ function html_finalize(&$cache = false) { global $html; // return html5 $ret = '<!DOCTYPE html>' . nl(); $ret .= '<html'; if (@is_array($html['header']['style'])) { $ret .= ' style="'; ksort($html['header']['style']); foreach ($html['header']['style'] as $key => $val) { $ret .= htmlspecialchars($key, ENT_COMPAT, 'UTF-8') . ': ' . htmlspecialchars($val, ENT_COMPAT, 'UTF-8') . '; '; } // strip the last space $ret = substr($ret, 0, -1); $ret .= '"'; } $ret .= '>' . nl(); $ret .= '<head>' . nl(); $ret .= '<title>' . htmlspecialchars($html['header']['title'], ENT_NOQUOTES, 'UTF-8') . '</title>' . nl(); $ret .= '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">' . nl(); if (@is_array($html['header']['alternate'])) { foreach ($html['header']['alternate'] as $e) { $ret .= '<link rel="alternate" type="' . htmlspecialchars($e['type'], ENT_COMPAT, 'UTF-8') . '" href="' . htmlspecialchars($e['url'], ENT_COMPAT, 'UTF-8') . '" title="' . htmlspecialchars($e['title'], ENT_COMPAT, 'UTF-8') . '">' . nl(); } } if (!empty($html['header']['favicon'])) { $ret .= '<link rel="shortcut icon" href="' . htmlspecialchars($html['header']['favicon'], ENT_COMPAT, 'UTF-8') . '">' . nl(); } if (@is_array($html['header']['css'])) { _array_sort_by_prio($html['header']['css']); // removed the removal of duplicates here as two different media might point to the same url //array_unique_element($html['header']['css'], 'url'); foreach ($html['header']['css'] as $e) { $ret .= '<link rel="stylesheet" type="text/css" href="' . htmlspecialchars($e['url'], ENT_COMPAT, 'UTF-8') . '"'; if (!empty($e['media'])) { $ret .= ' media="' . htmlspecialchars($e['media'], ENT_COMPAT, 'UTF-8') . '"'; } $ret .= '>' . nl(); } } if (@is_array($html['header']['css_inline'])) { _array_sort_by_prio($html['header']['css_inline']); if (0 < count($html['header']['css_inline'])) { $ret .= '<style type="text/css">' . nl(); } foreach ($html['header']['css_inline'] as $c) { $rule = $c['rule']; // if the rule ends with a newline character, remove it if (substr($rule, -1) == "\n") { $rule = substr($rule, 0, -1); } // move rule in by one tab $rule = str_replace("\n", "\n\t", $rule); $ret .= tab() . $rule . nl(); } if (0 < count($html['header']['css_inline'])) { $ret .= '</style>' . nl(); } } if (@is_array($html['header']['js'])) { _array_sort_by_prio($html['header']['js']); array_unique_element($html['header']['js'], 'url'); foreach ($html['header']['js'] as $e) { $ret .= '<script type="text/javascript" src="' . htmlspecialchars($e['url'], ENT_COMPAT, 'UTF-8') . '"></script>' . nl(); } } if (@is_array($html['header']['js_var'])) { $ret .= array_to_js($html['header']['js_var']); } if (@is_array($html['header']['js_inline'])) { _array_sort_by_prio($html['header']['js_inline']); foreach ($html['header']['js_inline'] as $c) { if (!empty($c['reason'])) { $ret .= '<!-- ' . $c['reason'] . ' -->' . nl(); $ret .= '<script type="text/javascript">' . nl(); // if the code ends with a newline character, remove it if (substr($c['code'], -1) == "\n") { $c['code'] = substr($c['code'], 0, -1); } // move code in by one tab $c = str_replace("\n", "\n\t", $c); $ret .= tab() . $c['code'] . nl(); $ret .= '</script>' . nl(); } } } if (@is_array($html['header']['head_inline'])) { _array_sort_by_prio($html['header']['head_inline']); if (0 < count($html['header']['head_inline'])) { $ret .= '<!-- user HEAD definitions -->' . nl(); } foreach ($html['header']['head_inline'] as $c) { $def = $c['def']; // if the definition ends with a newline character, remove it if (substr($def, -1) == "\n") { $def = substr($def, 0, -1); } // $rule = str_replace("\n", "\n\t", $def); $ret .= $def . nl(); } } $ret .= '</head>' . nl(); // load user body definitions if (@is_array($html['body']['body_inline'])) { _array_sort_by_prio($html['body']['body_inline']); if (0 < count($html['body']['body_inline'])) { $user_body = '<!-- user BODY definitions -->' . nl(); } foreach ($html['body']['body_inline'] as $c) { $def = $c['def']; // if the definition ends with a newline character, remove it if (substr($def, -1) == "\n") { $def = substr($def, 0, -1); } $rule = str_replace("\n", "\n\t", $def); $user_body .= $def . nl(); } body_append($user_body); } $ret .= elem_finalize($html['body']); $ret .= '</html>'; // pass caching information up if requested if ($cache) { if (!$html['cache']) { $cache = false; } } return $ret; }