function theme_include($file, $root = '') { // Make sure $root ends with a slash / if it's not blank if ($root !== '' && $root[strlen($root) - 1] !== '/') { $root = $root . '/'; } $theme_info = App::$theme_info; if (array_key_exists('extends', $theme_info)) { $parent = $theme_info['extends']; } else { $parent = 'NOPATH'; } $theme = Zotlabs\Render\Theme::current(); $thname = $theme[0]; $ext = substr($file, strrpos($file, '.') + 1); $paths = array("{$root}view/theme/{$thname}/{$ext}/{$file}", "{$root}view/theme/{$parent}/{$ext}/{$file}", "{$root}view/site/{$ext}/{$file}", "{$root}view/{$ext}/{$file}"); foreach ($paths as $p) { // strpos() is faster than strstr when checking if one string is in another (http://php.net/manual/en/function.strstr.php) if (strpos($p, 'NOPATH') !== false) { continue; } if (file_exists($p)) { return $p; } } return ''; }
/** * @brief build the page. * * Build the page - now that we have all the components * * @param App &$a global application object */ function construct_page(&$a) { exec_pdl($a); $comanche = count(App::$layout) ? true : false; require_once theme_include('theme_init.php'); $installing = false; if (App::$module == 'setup') { $installing = true; } else { nav($a); } if ($comanche) { if (App::$layout['nav']) { App::$page['nav'] = get_custom_nav($a, App::$layout['nav']); } } $current_theme = Zotlabs\Render\Theme::current(); if (($p = theme_include($current_theme[0] . '.js')) != '') { head_add_js($p); } if (($p = theme_include('mod_' . App::$module . '.php')) != '') { require_once $p; } require_once 'include/js_strings.php'; if (x(App::$page, 'template_style')) { head_add_css(App::$page['template_style'] . '.css'); } else { head_add_css((x(App::$page, 'template') ? App::$page['template'] : 'default') . '.css'); } head_add_css('mod_' . App::$module . '.css'); head_add_css(Zotlabs\Render\Theme::url($installing)); head_add_js('mod_' . App::$module . '.js'); App::build_pagehead(); if (App::$page['pdl_content']) { App::$page['content'] = App::$comanche->region(App::$page['content']); } // Let's say we have a comanche declaration '[region=nav][/region][region=content]$nav $content[/region]'. // The text 'region=' identifies a section of the layout by that name. So what we want to do here is leave // App::$page['nav'] empty and put the default content from App::$page['nav'] and App::$page['section'] // into a new region called App::$data['content']. It is presumed that the chosen layout file for this comanche page // has a '<content>' element instead of a '<section>'. // This way the Comanche layout can include any existing content, alter the layout by adding stuff around it or changing the // layout completely with a new layout definition, or replace/remove existing content. if ($comanche) { $arr = array('module' => App::$module, 'layout' => App::$layout); call_hooks('construct_page', $arr); App::$layout = $arr['layout']; foreach (App::$layout as $k => $v) { if (strpos($k, 'region_') === 0 && strlen($v)) { if (strpos($v, '$region_') !== false) { $v = preg_replace_callback('/\\$region_([a-zA-Z0-9]+)/ism', array(App::$comanche, 'replace_region'), $v); } // And a couple of convenience macros if (strpos($v, '$htmlhead') !== false) { $v = str_replace('$htmlhead', App::$page['htmlhead'], $v); } if (strpos($v, '$nav') !== false) { $v = str_replace('$nav', App::$page['nav'], $v); } if (strpos($v, '$content') !== false) { $v = str_replace('$content', App::$page['content'], $v); } App::$page[substr($k, 7)] = $v; } } } if (App::$is_mobile || App::$is_tablet) { if (isset($_SESSION['show_mobile']) && !$_SESSION['show_mobile']) { $link = z_root() . '/toggle_mobile?f=&address=' . curPageURL(); } else { $link = z_root() . '/toggle_mobile?f=&off=1&address=' . curPageURL(); } if (isset($_SESSION) && $_SESSION['mobile_theme'] != '' && $_SESSION['mobile_theme'] != '---' || isset(App::$config['system']['mobile_theme']) && !isset($_SESSION['mobile_theme'])) { App::$page['footer'] .= replace_macros(get_markup_template("toggle_mobile_footer.tpl"), array('$toggle_link' => $link, '$toggle_text' => t('toggle mobile'))); } } $page = App::$page; $profile = App::$profile; // There's some experimental support for right-to-left text in the view/php/default.php page template. // In v1.9 we started providing direction preference in the per language hstrings.php file // This requires somebody with fluency in a RTL language to make happen $page['direction'] = 0; // ((App::$rtl) ? 1 : 0); header("Content-type: text/html; charset=utf-8"); // security headers - see https://securityheaders.io if (App::get_scheme() === 'https' && App::$config['system']['transport_security_header']) { header("Strict-Transport-Security: max-age=31536000"); } if (App::$config['system']['content_security_policy']) { header("Content-Security-Policy: script-src 'self' 'unsafe-inline' 'unsafe-eval'; style-src 'self' 'unsafe-inline'"); } if (App::$config['system']['x_security_headers']) { header("X-Frame-Options: SAMEORIGIN"); header("X-Xss-Protection: 1; mode=block;"); header("X-Content-Type-Options: nosniff"); } if (App::$config['system']['public_key_pins']) { header("Public-Key-Pins: " . App::$config['system']['public_key_pins']); } require_once theme_include((x(App::$page, 'template') ? App::$page['template'] : 'default') . '.php'); }