@@ -23,7 +23,7 @@ class Page { | |||
)); | |||
self::folder2(); | |||
break; | |||
} | |||
} | |||
} | |||
@@ -81,9 +81,13 @@ class Page { | |||
$folder->prepare_files(); | |||
$this->register_key('backgroundColor',$folder); | |||
foreach($f3->get('customVars') as $key=>$value) { | |||
$f3->set($key,$value); | |||
$this->register_key($key,$folder); | |||
} | |||
$folder->fill_content(); | |||
foreach($f3->get('siteColors') as $k=>$v){ | |||
$f3->set($k, | |||
array_key_exists($k,$folder->config) | |||
@@ -103,8 +107,10 @@ class Page { | |||
} | |||
if ($folder->extras['background'] | |||
&& !$folder->config['supressBackground']) { | |||
$background = new \Modules\CachedImage($folder->extras['background']); | |||
$f3->set('backgroundImage',$background->get_src(3000)); | |||
//$background = new \Modules\CachedImage($folder->extras['background']); | |||
//$f3->set('backgroundImage',$background->get_src(3000)); | |||
$background = $folder->extras['background']; | |||
$f3->set('backgroundImage',$background); | |||
} | |||
// $f3->set('background',$background); | |||
$f3->set('content', implode("\n", $folder->content['default'])); |
@@ -0,0 +1,217 @@ | |||
<?php | |||
class freaParsedown extends Parsedown { | |||
function get_BlockTypes() { | |||
return $this->BlockTypes; | |||
} | |||
function deactivate_ol() { | |||
$ol_triggers= array( | |||
"0", | |||
"1", | |||
"2", | |||
"3", | |||
"4", | |||
"5", | |||
"6", | |||
"7", | |||
"8", | |||
"9" | |||
); | |||
foreach ($ol_triggers as $key) { | |||
unset($this->BlockTypes[$key]); | |||
} | |||
} | |||
function add_language_to_link_target($href) { | |||
$f3 = \Base::instance(); | |||
$data = []; | |||
$base = substr($href,0,strpos($href,'?') ? : strlen($href)); | |||
parse_str(parse_url($href,PHP_URL_QUERY),$data); | |||
$fragment = parse_url($href,PHP_URL_FRAGMENT); | |||
if ($f3->get('LANG') != $f3->get('default_lang')) { | |||
if (!array_key_exists('lang',$data)) { | |||
$data['lang'] = $f3->get('LANG'); | |||
} | |||
} | |||
$new = $base; | |||
if (count($data) > 0) { | |||
$new .= "?" . http_build_query($data); | |||
} | |||
if ($fragment) { | |||
$new .= "#" . $fragment; | |||
} | |||
return $new; | |||
} | |||
protected function inlineEmailTag($Excerpt) | |||
{ | |||
$hostnameLabel = '[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?'; | |||
$commonMarkEmail = '[a-zA-Z0-9.!#$%&\'*+\/=?^_`{|}~-]++@' | |||
. $hostnameLabel . '(?:\.' . $hostnameLabel . ')*'; | |||
if (strpos($Excerpt['text'], '>') !== false | |||
and preg_match("/^<((mailto:)?$commonMarkEmail)>/i", $Excerpt['text'], $matches) | |||
){ | |||
$url = $matches[1]; | |||
if ( ! isset($matches[2])) | |||
{ | |||
$url = 'mailto:' . $url; | |||
} | |||
return array( | |||
'extent' => strlen($matches[0]), | |||
'element' => array( | |||
'name' => 'a', | |||
'text' => $matches[1], | |||
'attributes' => array( | |||
'href' => $url, | |||
'data-link-text' => $matches[1], | |||
), | |||
), | |||
); | |||
} | |||
} | |||
protected function inlineLink($Excerpt) | |||
{ | |||
$Element = array( | |||
'name' => 'a', | |||
'handler' => 'line', | |||
'nonNestables' => array('Url', 'Link'), | |||
'text' => null, | |||
'attributes' => array( | |||
'href' => null, | |||
'title' => null, | |||
), | |||
); | |||
$extent = 0; | |||
$remainder = $Excerpt['text']; | |||
if (preg_match('/\[((?:[^][]++|(?R))*+)\]/', $remainder, $matches)) | |||
{ | |||
$Element['text'] = $matches[1]; | |||
$extent += strlen($matches[0]); | |||
$remainder = substr($remainder, $extent); | |||
} | |||
else | |||
{ | |||
return; | |||
} | |||
if (preg_match('/^[(]\s*+((?:[^ ()]++|[(][^ )]+[)])++)(?:[ ]+("[^"]*"|\'[^\']*\'))?\s*[)]/', $remainder, $matches)) | |||
{ | |||
$Element['attributes']['href'] = $matches[1]; | |||
if (isset($matches[2])) | |||
{ | |||
$Element['attributes']['title'] = substr($matches[2], 1, - 1); | |||
} | |||
$extent += strlen($matches[0]); | |||
} | |||
else | |||
{ | |||
if (preg_match('/^\s*\[(.*?)\]/', $remainder, $matches)) | |||
{ | |||
$definition = strlen($matches[1]) ? $matches[1] : $Element['text']; | |||
$definition = strtolower($definition); | |||
$extent += strlen($matches[0]); | |||
} | |||
else | |||
{ | |||
$definition = strtolower($Element['text']); | |||
} | |||
if ( ! isset($this->DefinitionData['Reference'][$definition])) | |||
{ | |||
return; | |||
} | |||
$Definition = $this->DefinitionData['Reference'][$definition]; | |||
$Element['attributes']['href'] = $Definition['url']; | |||
$Element['attributes']['title'] = $Definition['title']; | |||
} | |||
$Element['attributes']['data-link-text'] = $Element['text']; | |||
$url=&$Element['attributes']['href']; | |||
if (strpos($url,':') === FALSE) { | |||
$url = $this->add_language_to_link_target($url); | |||
} | |||
return array( | |||
'extent' => $extent, | |||
'element' => $Element, | |||
); | |||
} | |||
protected function inlineUrl($Excerpt) | |||
{ | |||
if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/') | |||
{ | |||
return; | |||
} | |||
if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE)) | |||
{ | |||
$url = $matches[0][0]; | |||
$Inline = array( | |||
'extent' => strlen($matches[0][0]), | |||
'position' => $matches[0][1], | |||
'element' => array( | |||
'name' => 'a', | |||
'text' => $url, | |||
'attributes' => array( | |||
'href' => $url, | |||
'data-link-text' => $url, | |||
), | |||
), | |||
); | |||
return $Inline; | |||
} | |||
} | |||
protected function inlineUrlTag($Excerpt) | |||
{ | |||
if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches)) | |||
{ | |||
$url = $matches[1]; | |||
return array( | |||
'extent' => strlen($matches[0]), | |||
'element' => array( | |||
'name' => 'a', | |||
'text' => $url, | |||
'attributes' => array( | |||
'href' => $url, | |||
'data-link-text' => $url, | |||
), | |||
), | |||
); | |||
} | |||
} | |||
} |
@@ -14,7 +14,7 @@ class CachedImage { | |||
function get_src($inwidth = 500) { | |||
$f3 = \Base::instance(); | |||
if($this->is_image($this->original)) { | |||
if($this->is_image($this->original) && TRUE) { | |||
$info = pathinfo($this->original); | |||
$fn = basename($this->original,'.'.$info['extension']); | |||
$width = $inwidth ? $inwidth : $this->default_width; | |||
@@ -30,6 +30,7 @@ class CachedImage { | |||
$img1 = new \Image($this->original); | |||
$img1->resize($width); | |||
$f3->write($out,$img1->dump('jpeg',75)); | |||
unset($img1); | |||
} | |||
} else { | |||
$out = $this->original; | |||
@@ -38,6 +39,8 @@ class CachedImage { | |||
} | |||
function is_image($path) { | |||
// this protects from accidently calling this class on a wrong file | |||
// it doesn't ensure that the file actually contains valid image data | |||
$ex = explode('.',$path); | |||
$ext = array_pop($ex); | |||
return in_array(strtolower($ext),array( 'jpg', 'jpeg', 'png' )); |
@@ -20,6 +20,7 @@ class FilesInFolders { | |||
private $state=array(); | |||
function __construct($folder,$conf=array()) { | |||
debug("about to construct FIF: $folder"); | |||
$f3 = \Base::instance(); | |||
if(is_dir($folder)) { // are we given a valid path? | |||
@@ -47,12 +48,14 @@ class FilesInFolders { | |||
} | |||
} | |||
} | |||
foreach($this->domains as $domain) { | |||
$this->content[$domain] = array(); | |||
} | |||
foreach($this->keyfiles as $keys=>$d) { | |||
$this->extras[$keys] = ""; | |||
} | |||
debug("constructed files in folder: $folder"); | |||
} | |||
@@ -116,15 +119,19 @@ class FilesInFolders { | |||
// prepare content as per the struct // | |||
/////////////////////////////////////// | |||
function fill_content() { | |||
$md = new \Parsedown(); | |||
$md = new \freaParsedown(); | |||
$md->deactivate_ol(); | |||
//var_dump($md->get_BlockTypes()); | |||
foreach($this->domains as $domain_key=>$domain) { | |||
// don't act on hidden files | |||
if ($domain == 'hidden') { continue; } | |||
$this->state['current_domain'] = $domain_key; | |||
foreach($this->structs[$domain_key]['txt'] as $key=>$file) { | |||
$str = $this->read_textfile($file); | |||
$str = self::content_element_dispatcher($str); | |||
$str = $md->text($str); | |||
$str = sprintf("<div class='post'>%s</div>", $str); | |||
//$str = sprintf("%s", $str); | |||
$this->content[$domain][$key] = sprintf( | |||
"<div class=\"item %s %s\">%s</div>", | |||
$page, | |||
@@ -221,10 +228,13 @@ class FilesInFolders { | |||
// Utility functions // | |||
/////////////////////// | |||
function read_textfile($file) { | |||
debug("about to read file: $file"); | |||
$str = file_get_contents($file); | |||
debug("read file: $file"); | |||
$str = self::linkify($str); | |||
$str = self::strip_comments($str); | |||
$str = self::get_config_from_content($str); | |||
debug("processed file: $file"); | |||
return $str; | |||
} | |||
function strip_comments($str) { | |||
@@ -315,7 +325,8 @@ class FilesInFolders { | |||
} | |||
function content_element_dispatcher($string) { | |||
$f3 = \Base::instance(); | |||
$md = new \Parsedown(); | |||
$md = new \freaParsedown(); | |||
$md->deactivate_ol(); | |||
$f0 = 0; | |||
// find occorances of {| keyword |} | |||
$pattern = "/\{\|(.+?)\|\}/s"; | |||
@@ -340,13 +351,19 @@ class FilesInFolders { | |||
$request[1] | |||
); | |||
break; | |||
case 'span': | |||
$new=sprintf("<span class=\"%s\">%s</span>", | |||
$request[1], | |||
$request[2] ? : implode("\n",$body) | |||
); | |||
break; | |||
case 'small-text': | |||
if(count($body)) { | |||
$new=sprintf("<div class=\"f1\">%s</div>", | |||
$new=sprintf("<div class=\"smalltext\">%s</div>", | |||
implode("\n",$body) | |||
); | |||
} else { | |||
$new=sprintf("<span class=\"f1\">%s</span>", | |||
$new=sprintf("<span class=\"smalltext\">%s</span>", | |||
$request[1] | |||
); | |||
} | |||
@@ -367,70 +384,155 @@ class FilesInFolders { | |||
$type = array_shift($request); | |||
$pics = explode(":",array_shift($body)); | |||
$pic = $pics[0]; | |||
$pic_hover = count($pics) > 1 ? $pics[1] : $pic; | |||
$cap1 = array_shift($body); | |||
$cap2 = array_shift($body); | |||
$cap1_hover = array_shift($body); | |||
$cap2_hover = array_shift($body); | |||
$pic = new CachedImage($this->folder.$pic); | |||
$pic_hover = new CachedImage($this->folder.$pic_hover); | |||
$pic_hover = count($pics) > 1 ? $pics[1] : $pic; | |||
if (count($body) >= 3) { | |||
$caption = ['normal'=>['cap1' => array_shift($body), | |||
'cap2' => array_shift($body)], | |||
'hover'=> ['cap1' => array_shift($body), | |||
'cap2' => array_shift($body)]]; | |||
$caption_html=[]; | |||
foreach ($caption as $state => $set) { | |||
if(!$set['cap2']) { | |||
$caption_html[$state] = [ | |||
sprintf('<span class="first"> </span>'), | |||
sprintf('<span class="first">%s</span>',$set['cap1']) | |||
]; | |||
} else if (!$set['cap1'] && $set['cap2']) { | |||
$caption_html[$state] = [ | |||
sprintf('<span class="second">%s</span>',$set['cap2']) | |||
]; | |||
} else { | |||
$caption_html[$state] = [ | |||
sprintf('<span class="first">%s</span>',$set['cap1']?:" "), | |||
sprintf('<span class="second">%s</span>',$set['cap2']) | |||
]; | |||
} | |||
} | |||
$has_caption = TRUE; | |||
} else { | |||
$has_caption = FALSE; | |||
} | |||
if (file_exists($this->folder.$pic)) { | |||
$pic = $this->folder.$pic; | |||
} else { | |||
$pic = $f3->get('RESOURCES')."img/default_img.png"; | |||
} | |||
if (file_exists($this->folder.$pic_hover)) { | |||
$pic_hover = $this->folder.$pic_hover; | |||
} else { | |||
$pic_hover = $pic; | |||
} | |||
if(0) { | |||
$PIC = new \Image($pic); | |||
$orientation = $PIC->width() > $PIC->height() | |||
? 'landscape' | |||
: 'portrait' | |||
; | |||
unset($PIC); | |||
} else { | |||
list($wwidth, $hheight) = getimagesize($pic); | |||
$orientation = $wwidth > $hheight ? 'landscape' : 'portrait'; | |||
} | |||
$pic = new CachedImage($pic); | |||
$pic_hover = new CachedImage($pic_hover); | |||
$class=""; | |||
$add=""; | |||
switch($type) { | |||
case 'plain': | |||
$link=false; | |||
break; | |||
case 'download': | |||
$file = "/".$this->folder.implode(":",$request); | |||
$link='href="'.$file.'" download '; | |||
break; | |||
case 'lightbox': | |||
$body = implode("\n",$body); | |||
if (count($request) % 2) { | |||
$class = array_pop($request); | |||
} | |||
if (count($request) >= 2) { | |||
$body=str_replace([$request[0],$request[1]],["{|","|}"],$body); | |||
$body=$this->content_element_dispatcher($body); | |||
} | |||
$hash=md5($body); | |||
$add=sprintf('<div id="%s" class="content_elment_box_body">%s</div>', | |||
$add=sprintf("<div id=\"%s\" class=\"content_elment_box_body\">\n%s\n</div>", | |||
$hash, | |||
$md->text($body)); | |||
$link='href="#" data-featherlight="#'.$hash.'" '; | |||
break; | |||
case 'internal': | |||
$dest=implode(":",$request); | |||
$link=sprintf('href="%s" ',$f3->get('SITE_URL')."/".$dest); | |||
$data = []; | |||
$base = substr($dest,0,strpos($dest,'?') ? : strlen($dest)); | |||
parse_str(parse_url($dest,PHP_URL_QUERY),$data); | |||
$fragment = parse_url($dest,PHP_URL_FRAGMENT); | |||
if ($f3->get('LANG') != $f3->get('default_lang')) { | |||
if (!array_key_exists('lang',$data)) { | |||
$data['lang'] = $f3->get('LANG'); | |||
} | |||
} | |||
$new_dest = $base; | |||
if (count($data) > 0) { | |||
$new_dest .= "?" . http_build_query($data); | |||
} | |||
if ($fragment) { | |||
$new_dest .= "#" . $fragment; | |||
} | |||
//if ($f3->get('LANG') != $f3->get('default_lang')) { | |||
// $dest .= "?lang=".$f3->get('LANG'); | |||
//} | |||
$link=sprintf('href="%s" ',$f3->get('SITE_URL')."/".$new_dest); | |||
break; | |||
case 'external': | |||
$dest=implode(":",$request); | |||
$link=sprintf('href="%s" target="_blank"',$dest); | |||
$target = $f3->get('external_links_open_in_new_window') | |||
? 'target="_blank"' | |||
: '' | |||
; | |||
$link=sprintf('href="%s" %s',$dest, $target); | |||
break; | |||
default: | |||
$link='href="#"'; | |||
break; | |||
} | |||
$new=sprintf("<div><a class=\"content_element_box\" %s><div class=\"content_element_box\"> | |||
$new=sprintf("<div class=\"brick %s\">\n<a class=\"content_element_box\" %s>\n<div class=\"content_element_box\"> | |||
<div class=\"image\"> | |||
<img class=\"standard\" src=\"%s\" /><img class=\"hover\" src=\"%s\" /> | |||
</div> | |||
<div class=\"caption standard\"> | |||
<span class=\"first\">%s</span><br> | |||
<span class=\"second\">%s</span> | |||
</div> | |||
<div class=\"caption hover\"> | |||
<span class=\"first\">%s</span><br> | |||
<span class=\"second\">%s</span> | |||
</div></div></a>%s</div>", | |||
%s | |||
%s | |||
\n</div>\n</a>\n%s\n</div>", | |||
implode(" ",[$orientation,$class,$type]), | |||
$link, | |||
$pic->get_src(400), | |||
$pic_hover->get_src(400), | |||
$cap1,$cap2, | |||
$cap1_hover,$cap2_hover, | |||
$pic->get_src(1600), | |||
$pic_hover->get_src(1600), | |||
($has_caption ? "<div class=\"caption standard\">".implode("<br>",$caption_html['normal'])."</div>": " "), | |||
($has_caption ? "<div class=\"caption hover\">".implode("<br>",$caption_html['hover'])."</div>" : " " ), | |||
$add | |||
); | |||
break; | |||
case 'brick': | |||
array_shift($request); | |||
$class = array_shift($request); | |||
$new = sprintf("<div class=\"content_element brick %s\">\n%s\n</div>", | |||
$class, | |||
$md->text(implode("\n",$body)) | |||
); | |||
break; | |||
case 'calendar': | |||
array_shift($request); | |||
$conf = array('path', $this->folder); | |||
$v = $this->read_config(); | |||
$cal = new \Modules\CCalendar($v,$conf); | |||
$new=sprintf("<div class=\"calendar\">%s</div>", | |||
$new=sprintf("<div class=\"calendar\">\n%s\n</div>", | |||
$cal); | |||
break; | |||
@@ -456,10 +558,10 @@ class FilesInFolders { | |||
case 'image': | |||
$key=$request[1]; | |||
$image=""; | |||
if(!$key) { | |||
$new=self::warn("Content Module \"Image\" needs name of a file (without extension)"); | |||
break; | |||
} | |||
// if(!$key) { | |||
// $new=self::warn("Content Module \"Image\" needs name of a file (without extension)"); | |||
// break; | |||
//} | |||
foreach($this->structs as $domain=>$destination) { | |||
if(array_key_exists($key, $this->structs[$domain]['pic'])) { | |||
@@ -490,38 +592,56 @@ class FilesInFolders { | |||
} | |||
} | |||
$new=sprintf("<div class='image-container %s'>" | |||
$new=sprintf("<div class='content_element_image %s'>" | |||
."<div class=\"media %s\"><a href=\"%s\" data-featherlight=\"image\"><img src=\"%s\" alt=\"user supplied image\" /></a></div>" | |||
."<img src=\"%s\" style=\"display:none;\" alt=\"user supplied image\" />" | |||
."<div class=\"caption\">%s</div>" | |||
."</div>", | |||
$class, | |||
$ratio, | |||
$cached->get_src(1400), | |||
$cached->get_src(500), | |||
$cached->get_src(1400), | |||
$cached->get_src(1600), | |||
$cached->get_src(1600), | |||
$cached->get_src(1600), | |||
$md->text(implode("\n",$body)) | |||
); | |||
} else { | |||
$new=self::warn("image \"$key\" not found"); | |||
$new=sprintf("<div class='content_element_image %s'>\n" | |||
."<div class=\"media %s\">\n" | |||
."<div class=\"caption\">\n%s\n</div>\n" | |||
."</div>\n", | |||
$class, | |||
$ratio, | |||
$md->text(implode("\n",$body)) | |||
); | |||
} | |||
break; | |||
case 'devide': | |||
$new = '<div class="content_element_devided">'; | |||
$contents = explode($request[1],implode("\n",$body)); | |||
$c=count($contents); | |||
$str=""; | |||
for ($iiii=0;$iiii<$c;$iiii++) { | |||
$str .= sprintf(" %f%%",100/$c); | |||
} | |||
$template = sprintf('grid-template-columns:%s;', | |||
$str); | |||
$counter=0; | |||
$new = sprintf('<div class="content_element_devided" style="%s">',$template); | |||
foreach($contents as $part) { | |||
$counter++; | |||
if (count($request) >= 4) { | |||
$part=str_replace([$request[2],$request[3]],["{|","|}"],$part); | |||
$part=$this->content_element_dispatcher($part); | |||
} | |||
$new .= sprintf("<div>%s</div>", | |||
$new .= sprintf("<div>\n%s\n</div>", | |||
$md->text($part) | |||
); | |||
} | |||
$new.="</div>"; | |||
break; | |||
case 'page': | |||
@@ -529,12 +649,21 @@ class FilesInFolders { | |||
$target = array_shift($request); | |||
$class = array_shift($request); | |||
$folder = $this->folder.$target."/"; | |||
$f = new \Modules\FilesInFolders($folder); | |||
$f->prepare_files(); | |||
$f->fill_content(); | |||
$new = sprintf('<div class="content_element_page %s">%s</div>', | |||
$fff = new \Modules\FilesInFolders( | |||
$folder, | |||
array( | |||
'content'=>array( | |||
'secondary'=>'secondary', | |||
'zzz'=>'hidden', | |||
'unpublish'=>'hidden' | |||
)) | |||
); | |||
$fff->prepare_files(); | |||
$fff->fill_content(); | |||
$new = sprintf("<div class=\"content_element_page %s\">\n%s\n</div>", | |||
$class, | |||
implode("\n",$f->content['default'])); | |||
implode("\n",$fff->content['default'])); | |||
break; | |||
case 'youtube': |
@@ -1,3 +1,8 @@ | |||
html { | |||
background-color: {{ @backgroundColor }}; | |||
background-image: url(/{{ @backgroundImage }}); | |||
background-position: bottom right; | |||
background-repeat: no-repeat; | |||
background-attachment: fixed; | |||
background-size: 2000px 2000px; | |||
} |
@@ -1,9 +1,10 @@ | |||
<a href="{{ 0 ? @SITE_URL : "/" }}"> | |||
<check if="{{ false }}"> | |||
<img class="logo" src="{{@RESOURCES}}img/logo.png" /> | |||
</check> | |||
<h1><img class="text" src="/{{ @banner }}" alt="{{ @title }}" /></h1> | |||
<nav id="languages"> | |||
<include href="navigation.htm" with="menu={{ @navi.languages }}" /> | |||
</nav> | |||
</a> | |||
<h1>{{ @title }}</h1> | |||
<check if="{{ @subTitle }}"> | |||
<h2>{{ @subTitle }}</h2> | |||
</check> | |||
<div class="headerInfo"> | |||
<span class="headerInfo1">{{ @headerInfo1 }}</span> | |||
<span class="headerInfo2">{{ @headerInfo2 }}</span> | |||
</div> |
@@ -7,62 +7,75 @@ | |||
<meta name="robots" content="noindex, nofollow"> | |||
</check> | |||
<meta name="viewport" content="width=device-width, initial-scale=1"> | |||
<link rel="icon" href="/{{ @RESOURCES }}favicon.png" /> | |||
<link rel="apple-touch-icon" sizes="180x180" href="/{{ @RESOURCES }}favicons/apple-touch-icon.png"> | |||
<link rel="icon" type="image/png" sizes="32x32" href="/{{ @RESOURCES }}favicons/favicon-32x32.png"> | |||
<link rel="icon" type="image/png" sizes="16x16" href="/{{ @RESOURCES }}favicons/favicon-16x16.png"> | |||
<link rel="manifest" href="/{{ @RESOURCES }}favicons/site.webmanifest"> | |||
<link rel="shortcut icon" href="/{{ @RESOURCES }}favicons/favicon.ico"> | |||
<meta name="msapplication-TileColor" content="#ffffff"> | |||
<meta name="msapplication-config" content="/{{ @RESOURCES }}favicons/browserconfig.xml"> | |||
<meta name="theme-color" content="#ffffff"> | |||
<link href="/{{ @RESOURCES }}featherlight.min.css" type="text/css" rel="stylesheet" /> | |||
<script type="text/javascript" src="/{{ @RESOURCES }}jquery-3.3.1.min.js"></script> | |||
<script type="text/javascript" src="/{{ @RESOURCES }}script.js"></script> | |||
<link type="text/css" href="/{{ @RESOURCES }}style.css" rel="stylesheet" /> | |||
<title>{{ @title }}</title> | |||
<style> | |||
<include href="colors.css" /> | |||
li { margin-left:1em; } | |||
</style> | |||
</head> | |||
<body class="{{ @bodyClass }}"> | |||
<div id="mobile-nav"> | |||
<a class="menu-toggle" onClick="javascript:toggle_menu();"></a> | |||
<div class="the_list"> | |||
<include href="navigation.htm" with="menu={{ @navi.main }}" /> | |||
<include href="navigation.htm" with="menu={{ @navi.footer }}" /> | |||
<include href="navigation.htm" with="menu={{ @navi.languages }}" /> | |||
</div> | |||
</div> <!-- #mobile-nav --> | |||
<div id="backdrop"></div> | |||
<div id="page-wrap"> | |||
<header> | |||
<include href="header.htm"> | |||
</header> | |||
<nav id="main-nav"> | |||
<include href="navigation.htm" with="menu={{ @navi.main }}" /> | |||
<div class="network"> | |||
<include href="navigation.htm" with="menu={{ @navi.network }}"> | |||
</div> | |||
</nav> | |||
<div id="mobile-nav"> | |||
<a class="menu-toggle" onClick="javascript:toggle_menu();"></a> | |||
<div class="the_list"><div> | |||
<a class="home_link {{ @is_home ? 'active': '' }}" href="{{ 0 ? @SITE_URL : "/" }}{{ @LANG != @default_lang ? "?lang=".@LANG : "" }}">HOME</a> | |||
<include href="navigation.htm" with="menu={{ @navi.main }}" /> | |||
<div id="modileFooterNav"> | |||
<include href="navigation.htm" with="menu={{ @navi.footer }}" /> | |||
</div> | |||
<div id="mobileLanguageNav"> | |||
<include href="navigation.htm" with="menu={{ @navi.mobilelang }}" /> | |||
</div> | |||
</div></div> | |||
</div> <!-- #mobile-nav --> | |||
<div id="platzhalter"></div> | |||
<section id="content"> | |||
<include href="maincontent.htm" /> | |||
<include href="sidebar.htm" /> | |||
</section> | |||
<footer id="main-footer"> | |||
<nav> | |||
<include href="navigation.htm" with="menu={{ @navi.footer }}" /> | |||
</nav> | |||
</footer> | |||
</div> <!-- #page-wrap --> | |||
<footer id="main-footer"> | |||
<nav> | |||
<include href="navigation.htm" with="menu={{ @navi.footer }}" /> | |||
</nav> | |||
</footer> | |||
<check if="{{ @backend }}"> | |||
<div id="admin-panel">{{ @backend | raw }}</div> | |||
</check> |
@@ -0,0 +1,58 @@ | |||
Content Elements | |||
================ | |||
Within text in content it is possible to embed special functionality. | |||
Keywords with a combination of curly brackets and the vertical line call corresponding code. | |||
{| KEYWORD |} | |||
generally *keyword* refers to a function that can be passed header arguments and a body. | |||
{| ELEMENT_NAME:ARG1:ARG2:... | |||
. | |||
...body... | |||
. | |||
|} | |||
## some conventions | |||
### [:CE:enable] | |||
Some content elements allow content to be included in the body. Some allow content elements inside this content. A nested bracket pair needs to be defined to do so. This is 1) because using the same combination {||} confuses the original dispatcher, and 2) to not clutter reserved keywords, it makes sense to define whatever suit you. | |||
{| devide:BREAK:<:> |} | |||
## available Content Elements | |||
### devide | |||
{| devide:BREAKPOINT[:CE:enable] | |||
BODY | |||
|} | |||
### box | |||
An image, with different hover states of annotations and action when clicked on. | |||
{| box:TYPE[:CE:enable] | |||
picture:optional_hover_picture | |||
caption1 | |||
caption2 | |||
caption1_hover | |||
caption2_hover | |||
BODY | |||
|} | |||
TYPE: lightbox|download|internal|external | |||
- plain | |||
- lightbox[:classname] | |||
this type shows BODY in a lightbox when element is clicked | |||
NOTE: use CE:enable before classname | |||
EXAMPLE: {| box:lightbox:<:>:media |} | |||
- download:HREF | |||
make click action offer a download with URI=HREF | |||
- internal:PATH | |||
change page on click | |||
- external:HREF | |||
open HREF in new page |
@@ -1,32 +1,47 @@ | |||
<?php | |||
function debug($message) { | |||
$f3 = \Base::instance(); | |||
if ($f3->get('DEBUG')) { | |||
printf("<hr>%s:<br>Memory Usage: %s <br>", $message, memory_get_usage()); | |||
} | |||
} | |||
///////////////////////////// | |||
// configure installation: // | |||
///////////////////////////// | |||
define("ROOT", "./"); | |||
require_once( ROOT.'lib/autoload.php' ); | |||
error_reporting(0); | |||
ini_set("log_errors", 1); | |||
ini_set("error_log", "php-error.log"); | |||
/** @var \Base $f3 */ | |||
$f3 = \Base::instance(); | |||
$f3->set('DEBUG',3); | |||
$f3->set('CACHE',FALSE); | |||
$f3->set('DEBUG', 0); | |||
$f3->set('CACHE', FALSE); | |||
$f3->set('AUTOLOAD', ROOT.'app/'); | |||
$f3->set('UI', implode(';',array( | |||
$f3->set('UI', implode(';', array( | |||
ROOT.'app/views/', | |||
ROOT.'content/' // content folders can contain .html templates | |||
))); | |||
if(!is_dir($f3->get('TEMP'))) { | |||
if (!is_dir($f3->get('TEMP'))) { | |||
mkdir($f3->get('TEMP')); | |||
} | |||
function query_string_from_array($in){ | |||
$out = []; | |||
foreach ($in as $key=>$value) { | |||
$out[] = sprintf("%s=%s", $key, $value); | |||
} | |||
return implode("&", $out); | |||
} | |||
///////////////////////// | |||
// main configuration: // | |||
///////////////////////// | |||
debug("before read config"); | |||
$f3->config( ROOT.'main.cfg' ); | |||
if(!setlocale(LC_TIME, 'de_DE.UTF-8')) { | |||
@@ -36,6 +51,13 @@ if(!setlocale(LC_TIME, 'de_DE.UTF-8')) { | |||
/////////////////////////////////////////////// | |||
// configuration based on configuration file // | |||
/////////////////////////////////////////////// | |||
// rerouting | |||
if(is_array($f3->get('reroutes'))) { | |||
foreach ($f3->get('reroutes') as $source=>$dest) { | |||
$f3->redirect('GET '.$source, $dest); | |||
} | |||
} | |||
// set language | |||
$languages = $f3->get('languages'); | |||
$f3->set('default_lang', array_shift($languages)); | |||
@@ -72,10 +94,23 @@ function menu_recursion($m,$root="") { | |||
$ex = explode(":=", $value); | |||
if (count($ex) > 1) { | |||
# external link | |||
$href = $ex[1]; | |||
$href = trim($ex[1]); | |||
if(!strncmp($href,"?",1)) { | |||
// if 'external link' starts with '?' | |||
// probably it is language switch | |||
foreach (explode("&",substr($href,1)) as $option) { | |||
if(!strncmp($option, "lang=", 5) !== FALSE) { | |||
$value = substr( $option, 5); | |||
$class .= ($value == $f3->get('LANG')) ? ' active' : ' away'; | |||
} | |||
} | |||
} | |||
} else { | |||
# internal link | |||
$href = $f3->get('SITE_URL').$path; | |||
$href .= count($f3->get('GET')) ? "?".query_string_from_array($f3->get('GET')):""; | |||
$class .= in_array($path,$f3->get('url')) ? ' active' : ' away'; | |||
} | |||
$out[$path]['name']=$ex[0]; | |||
@@ -111,11 +146,13 @@ for ($i=1;$i<=count($url_ex);$i++) { | |||
$url[]="/".implode("/",array_slice($url_ex,0,$i)); | |||
} | |||
$f3->set('url', $url); | |||
$f3->set('is_home', in_array($url[0],["/","/home"])); | |||
$f3->set('level', 1); // this is for templates, to be abl to count nesting | |||
read_menu("main"); | |||
read_menu("footer"); | |||
read_menu("network"); | |||
#read_menu("network"); | |||
read_menu("languages"); | |||
read_menu("mobilelang"); | |||
@@ -123,11 +160,6 @@ read_menu("languages"); | |||
// development utility functions // | |||
/////////////////////////////////// | |||
function debug($Message=".") { | |||
if(DEBUG > 0) { | |||
echo "<br>".$Message; | |||
} | |||
} | |||
############################################################################## | |||
@@ -186,6 +218,6 @@ $f3->mset(array( | |||
)); | |||
debug("before run fatfree"); | |||
$f3->run(); | |||
echo \Template::instance()->render($f3->get('template')); |
@@ -47,3 +47,5 @@ RESOURCES=rsc/ | |||
;default site template: | |||
template=tpl/index.html | |||
external_links_open_in_new_window=false |
@@ -0,0 +1,9 @@ | |||
<?xml version="1.0" encoding="utf-8"?> | |||
<browserconfig> | |||
<msapplication> | |||
<tile> | |||
<square150x150logo src="/favicons/mstile-150x150.png"/> | |||
<TileColor>#da532c</TileColor> | |||
</tile> | |||
</msapplication> | |||
</browserconfig> |
@@ -0,0 +1,19 @@ | |||
{ | |||
"name": "", | |||
"short_name": "", | |||
"icons": [ | |||
{ | |||
"src": "/favicons/android-chrome-192x192.png", | |||
"sizes": "192x192", | |||
"type": "image/png" | |||
}, | |||
{ | |||
"src": "/favicons/android-chrome-256x256.png", | |||
"sizes": "256x256", | |||
"type": "image/png" | |||
} | |||
], | |||
"theme_color": "#000000", | |||
"background_color": "#000000", | |||
"display": "standalone" | |||
} |
@@ -5,19 +5,3 @@ a { | |||
} | |||
} | |||
ul.nav { | |||
list-style: none; | |||
li { margin:0; } | |||
.active>a { | |||
font-weight: bold; | |||
} | |||
} | |||
#main-nav { | |||
background: #eec; | |||
border-radius:1.2em 1.2em 0 0; | |||
ul { padding-left: 1.5em; } | |||
.level1>li,.level2>li { margin-top: 1em; } | |||
} |
@@ -1,18 +1,5 @@ | |||
// fonts | |||
//@import url('https://fonts.googleapis.com/css?family=Poiret+One'); | |||
$poiret1:'Poiret One', cursive; | |||
$georgia:georgia, serif; | |||
$verdana:verdana, sans; | |||
$cursive: cursive;//$poiret1; | |||
$serif: $georgia; | |||
$sans: $verdana; | |||
$cursive: cursive; | |||
$serif: serif; | |||
$sans: sans-serif; | |||
.card, .item { | |||
// font-family: $sans; | |||
h2 { | |||
font-family: $serif; | |||
} | |||
} |
@@ -0,0 +1,565 @@ | |||
@charset "UTF-8"; | |||
// _ _ _ _ _ | |||
// (_) | | | | | (_) | |||
// _ _ __ ___| |_ _ __| | ___ _ __ ___ ___ __| |_ __ _ | |||
// | | '_ \ / __| | | | |/ _` |/ _ \ | '_ ` _ \ / _ \/ _` | |/ _` | | |||
// | | | | | (__| | |_| | (_| | __/ | | | | | | __/ (_| | | (_| | | |||
// |_|_| |_|\___|_|\__,_|\__,_|\___| |_| |_| |_|\___|\__,_|_|\__,_| | |||
// | |||
// Simple, elegant and maintainable media queries in Sass | |||
// v1.4.9 | |||
// | |||
// https://eduardoboucas.github.io/include-media | |||
// | |||
// Authors: Eduardo Boucas (@eduardoboucas) | |||
// Hugo Giraudel (@hugogiraudel) | |||
// | |||
// This project is licensed under the terms of the MIT license | |||
//// | |||
/// include-media library public configuration | |||
/// @author Eduardo Boucas | |||
/// @access public | |||
//// | |||
/// | |||
/// Creates a list of global breakpoints | |||
/// | |||
/// @example scss - Creates a single breakpoint with the label `phone` | |||
/// $breakpoints: ('phone': 320px); | |||
/// | |||
$breakpoints: ( | |||
'phone': 320px, | |||
'tablet': 768px, | |||
'desktop': 1024px | |||
) !default; | |||
/// | |||
/// Creates a list of static expressions or media types | |||
/// | |||
/// @example scss - Creates a single media type (screen) | |||
/// $media-expressions: ('screen': 'screen'); | |||
/// | |||
/// @example scss - Creates a static expression with logical disjunction (OR operator) | |||
/// $media-expressions: ( | |||
/// 'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi)' | |||
/// ); | |||
/// | |||
$media-expressions: ( | |||
'screen': 'screen', | |||
'print': 'print', | |||
'handheld': 'handheld', | |||
'landscape': '(orientation: landscape)', | |||
'portrait': '(orientation: portrait)', | |||
'retina2x': '(-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi), (min-resolution: 2dppx)', | |||
'retina3x': '(-webkit-min-device-pixel-ratio: 3), (min-resolution: 350dpi), (min-resolution: 3dppx)' | |||
) !default; | |||
/// | |||
/// Defines a number to be added or subtracted from each unit when declaring breakpoints with exclusive intervals | |||
/// | |||
/// @example scss - Interval for pixels is defined as `1` by default | |||
/// @include media('>128px') {} | |||
/// | |||
/// /* Generates: */ | |||
/// @media (min-width: 129px) {} | |||
/// | |||
/// @example scss - Interval for ems is defined as `0.01` by default | |||
/// @include media('>20em') {} | |||
/// | |||
/// /* Generates: */ | |||
/// @media (min-width: 20.01em) {} | |||
/// | |||
/// @example scss - Interval for rems is defined as `0.1` by default, to be used with `font-size: 62.5%;` | |||
/// @include media('>2.0rem') {} | |||
/// | |||
/// /* Generates: */ | |||
/// @media (min-width: 2.1rem) {} | |||
/// | |||
$unit-intervals: ( | |||
'px': 1, | |||
'em': 0.01, | |||
'rem': 0.1, | |||
'': 0 | |||
) !default; | |||
/// | |||
/// Defines whether support for media queries is available, useful for creating separate stylesheets | |||
/// for browsers that don't support media queries. | |||
/// | |||
/// @example scss - Disables support for media queries | |||
/// $im-media-support: false; | |||
/// @include media('>=tablet') { | |||
/// .foo { | |||
/// color: tomato; | |||
/// } | |||
/// } | |||
/// | |||
/// /* Generates: */ | |||
/// .foo { | |||
/// color: tomato; | |||
/// } | |||
/// | |||
$im-media-support: true !default; | |||
/// | |||
/// Selects which breakpoint to emulate when support for media queries is disabled. Media queries that start at or | |||
/// intercept the breakpoint will be displayed, any others will be ignored. | |||
/// | |||
/// @example scss - This media query will show because it intercepts the static breakpoint | |||
/// $im-media-support: false; | |||
/// $im-no-media-breakpoint: 'desktop'; | |||
/// @include media('>=tablet') { | |||
/// .foo { | |||
/// color: tomato; | |||
/// } | |||
/// } | |||
/// | |||
/// /* Generates: */ | |||
/// .foo { | |||
/// color: tomato; | |||
/// } | |||
/// | |||
/// @example scss - This media query will NOT show because it does not intercept the desktop breakpoint | |||
/// $im-media-support: false; | |||
/// $im-no-media-breakpoint: 'tablet'; | |||
/// @include media('>=desktop') { | |||
/// .foo { | |||
/// color: tomato; | |||
/// } | |||
/// } | |||
/// | |||
/// /* No output */ | |||
/// | |||
$im-no-media-breakpoint: 'desktop' !default; | |||
/// | |||
/// Selects which media expressions are allowed in an expression for it to be used when media queries | |||
/// are not supported. | |||
/// | |||
/// @example scss - This media query will show because it intercepts the static breakpoint and contains only accepted media expressions | |||
/// $im-media-support: false; | |||
/// $im-no-media-breakpoint: 'desktop'; | |||
/// $im-no-media-expressions: ('screen'); | |||
/// @include media('>=tablet', 'screen') { | |||
/// .foo { | |||
/// color: tomato; | |||
/// } | |||
/// } | |||
/// | |||
/// /* Generates: */ | |||
/// .foo { | |||
/// color: tomato; | |||
/// } | |||
/// | |||
/// @example scss - This media query will NOT show because it intercepts the static breakpoint but contains a media expression that is not accepted | |||
/// $im-media-support: false; | |||
/// $im-no-media-breakpoint: 'desktop'; | |||
/// $im-no-media-expressions: ('screen'); | |||
/// @include media('>=tablet', 'retina2x') { | |||
/// .foo { | |||
/// color: tomato; | |||
/// } | |||
/// } | |||
/// | |||
/// /* No output */ | |||
/// | |||
$im-no-media-expressions: ('screen', 'portrait', 'landscape') !default; | |||
//// | |||
/// Cross-engine logging engine | |||
/// @author Hugo Giraudel | |||
/// @access private | |||
//// | |||
/// | |||
/// Log a message either with `@error` if supported | |||
/// else with `@warn`, using `feature-exists('at-error')` | |||
/// to detect support. | |||
/// | |||
/// @param {String} $message - Message to log | |||
/// | |||
@function im-log($message) { | |||
@if feature-exists('at-error') { | |||
@error $message; | |||
} @else { | |||
@warn $message; | |||
$_: noop(); | |||
} | |||
@return $message; | |||
} | |||
/// | |||
/// Wrapper mixin for the log function so it can be used with a more friendly | |||
/// API than `@if im-log('..') {}` or `$_: im-log('..')`. Basically, use the function | |||
/// within functions because it is not possible to include a mixin in a function | |||
/// and use the mixin everywhere else because it's much more elegant. | |||
/// | |||
/// @param {String} $message - Message to log | |||
/// | |||
@mixin log($message) { | |||
@if im-log($message) {} | |||
} | |||
/// | |||
/// Function with no `@return` called next to `@warn` in Sass 3.3 | |||
/// to trigger a compiling error and stop the process. | |||
/// | |||
@function noop() {} | |||
/// | |||
/// Determines whether a list of conditions is intercepted by the static breakpoint. | |||
/// | |||
/// @param {Arglist} $conditions - Media query conditions | |||
/// | |||
/// @return {Boolean} - Returns true if the conditions are intercepted by the static breakpoint | |||
/// | |||
@function im-intercepts-static-breakpoint($conditions...) { | |||
$no-media-breakpoint-value: map-get($breakpoints, $im-no-media-breakpoint); | |||
@if not $no-media-breakpoint-value { | |||
@if im-log('`#{$im-no-media-breakpoint}` is not a valid breakpoint.') {} | |||
} | |||
@each $condition in $conditions { | |||
@if not map-has-key($media-expressions, $condition) { | |||
$operator: get-expression-operator($condition); | |||
$prefix: get-expression-prefix($operator); | |||
$value: get-expression-value($condition, $operator); | |||
@if ($prefix == 'max' and $value <= $no-media-breakpoint-value) or | |||
($prefix == 'min' and $value > $no-media-breakpoint-value) { | |||
@return false; | |||
} | |||
} @else if not index($im-no-media-expressions, $condition) { | |||
@return false; | |||
} | |||
} | |||
@return true; | |||
} | |||
//// | |||
/// Parsing engine | |||
/// @author Hugo Giraudel | |||
/// @access private | |||
//// | |||
/// | |||
/// Get operator of an expression | |||
/// | |||
/// @param {String} $expression - Expression to extract operator from | |||
/// | |||
/// @return {String} - Any of `>=`, `>`, `<=`, `<`, `≥`, `≤` | |||
/// | |||
@function get-expression-operator($expression) { | |||
@each $operator in ('>=', '>', '<=', '<', '≥', '≤') { | |||
@if str-index($expression, $operator) { | |||
@return $operator; | |||
} | |||
} | |||
// It is not possible to include a mixin inside a function, so we have to | |||
// rely on the `im-log(..)` function rather than the `log(..)` mixin. Because | |||
// functions cannot be called anywhere in Sass, we need to hack the call in | |||
// a dummy variable, such as `$_`. If anybody ever raise a scoping issue with | |||
// Sass 3.3, change this line in `@if im-log(..) {}` instead. | |||
$_: im-log('No operator found in `#{$expression}`.'); | |||
} | |||
/// | |||
/// Get dimension of an expression, based on a found operator | |||
/// | |||
/// @param {String} $expression - Expression to extract dimension from | |||
/// @param {String} $operator - Operator from `$expression` | |||
/// | |||
/// @return {String} - `width` or `height` (or potentially anything else) | |||
/// | |||
@function get-expression-dimension($expression, $operator) { | |||
$operator-index: str-index($expression, $operator); | |||
$parsed-dimension: str-slice($expression, 0, $operator-index - 1); | |||
$dimension: 'width'; | |||
@if str-length($parsed-dimension) > 0 { | |||
$dimension: $parsed-dimension; | |||
} | |||
@return $dimension; | |||
} | |||
/// | |||
/// Get dimension prefix based on an operator | |||
/// | |||
/// @param {String} $operator - Operator | |||
/// | |||
/// @return {String} - `min` or `max` | |||
/// | |||
@function get-expression-prefix($operator) { | |||
@return if(index(('<', '<=', '≤'), $operator), 'max', 'min'); | |||
} | |||
/// | |||
/// Get value of an expression, based on a found operator | |||
/// | |||
/// @param {String} $expression - Expression to extract value from | |||
/// @param {String} $operator - Operator from `$expression` | |||
/// | |||
/// @return {Number} - A numeric value | |||
/// | |||
@function get-expression-value($expression, $operator) { | |||
$operator-index: str-index($expression, $operator); | |||
$value: str-slice($expression, $operator-index + str-length($operator)); | |||
@if map-has-key($breakpoints, $value) { | |||
$value: map-get($breakpoints, $value); | |||
} @else { | |||
$value: to-number($value); | |||
} | |||
$interval: map-get($unit-intervals, unit($value)); | |||
@if not $interval { | |||
// It is not possible to include a mixin inside a function, so we have to | |||
// rely on the `im-log(..)` function rather than the `log(..)` mixin. Because | |||
// functions cannot be called anywhere in Sass, we need to hack the call in | |||
// a dummy variable, such as `$_`. If anybody ever raise a scoping issue with | |||
// Sass 3.3, change this line in `@if im-log(..) {}` instead. | |||
$_: im-log('Unknown unit `#{unit($value)}`.'); | |||
} | |||
@if $operator == '>' { | |||
$value: $value + $interval; | |||
} @else if $operator == '<' { | |||
$value: $value - $interval; | |||
} | |||
@return $value; | |||
} | |||
/// | |||
/// Parse an expression to return a valid media-query expression | |||
/// | |||
/// @param {String} $expression - Expression to parse | |||
/// | |||
/// @return {String} - Valid media query | |||
/// | |||
@function parse-expression($expression) { | |||
// If it is part of $media-expressions, it has no operator | |||
// then there is no need to go any further, just return the value | |||
@if map-has-key($media-expressions, $expression) { | |||
@return map-get($media-expressions, $expression); | |||
} | |||
$operator: get-expression-operator($expression); | |||
$dimension: get-expression-dimension($expression, $operator); | |||
$prefix: get-expression-prefix($operator); | |||
$value: get-expression-value($expression, $operator); | |||
@return '(#{$prefix}-#{$dimension}: #{$value})'; | |||
} | |||
/// | |||
/// Slice `$list` between `$start` and `$end` indexes | |||
/// | |||
/// @access private | |||
/// | |||
/// @param {List} $list - List to slice | |||
/// @param {Number} $start [1] - Start index | |||
/// @param {Number} $end [length($list)] - End index | |||
/// | |||
/// @return {List} Sliced list | |||
/// | |||
@function slice($list, $start: 1, $end: length($list)) { | |||
@if length($list) < 1 or $start > $end { | |||
@return (); | |||
} | |||
$result: (); | |||
@for $i from $start through $end { | |||
$result: append($result, nth($list, $i)); | |||
} | |||
@return $result; | |||
} | |||
//// | |||
/// String to number converter | |||
/// @author Hugo Giraudel | |||
/// @access private | |||
//// | |||
/// | |||
/// Casts a string into a number | |||
/// | |||
/// @param {String | Number} $value - Value to be parsed | |||
/// | |||
/// @return {Number} | |||
/// | |||
@function to-number($value) { | |||
@if type-of($value) == 'number' { | |||
@return $value; | |||
} @else if type-of($value) != 'string' { | |||
$_: im-log('Value for `to-number` should be a number or a string.'); | |||
} | |||
$first-character: str-slice($value, 1, 1); | |||
$result: 0; | |||
$digits: 0; | |||
$minus: ($first-character == '-'); | |||
$numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9); | |||
// Remove +/- sign if present at first character | |||
@if ($first-character == '+' or $first-character == '-') { | |||
$value: str-slice($value, 2); | |||
} | |||
@for $i from 1 through str-length($value) { | |||
$character: str-slice($value, $i, $i); | |||
@if not (index(map-keys($numbers), $character) or $character == '.') { | |||
@return to-length(if($minus, -$result, $result), str-slice($value, $i)) | |||
} | |||
@if $character == '.' { | |||
$digits: 1; | |||
} @else if $digits == 0 { | |||
$result: $result * 10 + map-get($numbers, $character); | |||
} @else { | |||
$digits: $digits * 10; | |||
$result: $result + map-get($numbers, $character) / $digits; | |||
} | |||
} | |||
@return if($minus, -$result, $result); | |||
} | |||
/// | |||
/// Add `$unit` to `$value` | |||
/// | |||
/// @param {Number} $value - Value to add unit to | |||
/// @param {String} $unit - String representation of the unit | |||
/// | |||
/// @return {Number} - `$value` expressed in `$unit` | |||
/// | |||
@function to-length($value, $unit) { | |||
$units: ('px': 1px, 'cm': 1cm, 'mm': 1mm, '%': 1%, 'ch': 1ch, 'pc': 1pc, 'in': 1in, 'em': 1em, 'rem': 1rem, 'pt': 1pt, 'ex': 1ex, 'vw': 1vw, 'vh': 1vh, 'vmin': 1vmin, 'vmax': 1vmax); | |||
@if not index(map-keys($units), $unit) { | |||
$_: im-log('Invalid unit `#{$unit}`.'); | |||
} | |||
@return $value * map-get($units, $unit); | |||
} | |||
/// | |||
/// This mixin aims at redefining the configuration just for the scope of | |||
/// the call. It is helpful when having a component needing an extended | |||
/// configuration such as custom breakpoints (referred to as tweakpoints) | |||
/// for instance. | |||
/// | |||
/// @author Hugo Giraudel | |||
/// | |||
/// @param {Map} $tweakpoints [()] - Map of tweakpoints to be merged with `$breakpoints` | |||
/// @param {Map} $tweak-media-expressions [()] - Map of tweaked media expressions to be merged with `$media-expression` | |||
/// | |||
/// @example scss - Extend the global breakpoints with a tweakpoint | |||
/// @include media-context(('custom': 678px)) { | |||
/// .foo { | |||
/// @include media('>phone', '<=custom') { | |||
/// // ... | |||
/// } | |||
/// } | |||
/// } | |||
/// | |||
/// @example scss - Extend the global media expressions with a custom one | |||
/// @include media-context($tweak-media-expressions: ('all': 'all')) { | |||
/// .foo { | |||
/// @include media('all', '>phone') { | |||
/// // ... | |||
/// } | |||
/// } | |||
/// } | |||
/// | |||
/// @example scss - Extend both configuration maps | |||
/// @include media-context(('custom': 678px), ('all': 'all')) { | |||
/// .foo { | |||
/// @include media('all', '>phone', '<=custom') { | |||
/// // ... | |||
/// } | |||
/// } | |||
/// } | |||
/// | |||
@mixin media-context($tweakpoints: (), $tweak-media-expressions: ()) { | |||
// Save global configuration | |||
$global-breakpoints: $breakpoints; | |||
$global-media-expressions: $media-expressions; | |||
// Update global configuration | |||
$breakpoints: map-merge($breakpoints, $tweakpoints) !global; | |||
$media-expressions: map-merge($media-expressions, $tweak-media-expressions) !global; | |||
@content; | |||
// Restore global configuration | |||
$breakpoints: $global-breakpoints !global; | |||
$media-expressions: $global-media-expressions !global; | |||
} | |||
//// | |||
/// include-media public exposed API | |||
/// @author Eduardo Boucas | |||
/// @access public | |||
//// | |||
/// | |||
/// Generates a media query based on a list of conditions | |||
/// | |||
/// @param {Arglist} $conditions - Media query conditions | |||
/// | |||
/// @example scss - With a single set breakpoint | |||
/// @include media('>phone') { } | |||
/// | |||
/// @example scss - With two set breakpoints | |||
/// @include media('>phone', '<=tablet') { } | |||
/// | |||
/// @example scss - With custom values | |||
/// @include media('>=358px', '<850px') { } | |||
/// | |||
/// @example scss - With set breakpoints with custom values | |||
/// @include media('>desktop', '<=1350px') { } | |||
/// | |||
/// @example scss - With a static expression | |||
/// @include media('retina2x') { } | |||
/// | |||
/// @example scss - Mixing everything | |||
/// @include media('>=350px', '<tablet', 'retina3x') { } | |||
/// | |||
@mixin media($conditions...) { | |||
@if ($im-media-support and length($conditions) == 0) or | |||
(not $im-media-support and im-intercepts-static-breakpoint($conditions...)) { | |||
@content; | |||
} @else if ($im-media-support and length($conditions) > 0) { | |||
@media #{unquote(parse-expression(nth($conditions, 1)))} { | |||
// Recursive call | |||
@include media(slice($conditions, 2)...) { | |||
@content; | |||
} | |||
} | |||
} | |||
} |
@@ -8,61 +8,3 @@ html,body { | |||
margin:0; | |||
padding:0; | |||
} | |||
.content_element_page.wall { | |||
a.content_element_box { | |||
float: left; | |||
} | |||
&:after { | |||
content:""; | |||
display: block; | |||
clear: both; | |||
} | |||
div.content_element_box { | |||
height:100px; | |||
} | |||
} | |||
#page-wrap { | |||
display: grid; | |||
grid-template-columns:250px auto; | |||
grid-template-rows:200px 100fr 3em; | |||
height:100vh; | |||
overflow: hidden; | |||
max-width:1300px; | |||
margin:0 auto; | |||
>header { | |||
grid-column:1 / -1; | |||
} | |||
#main-nav { | |||
grid-column:1 / span 1; | |||
grid-row:2 / -1; | |||
} | |||
#content { | |||
grid-column: 2 / -1; | |||
grid-row: 2 / 3; | |||
overflow-y: auto; | |||
} | |||
#main-footer { | |||
grid-column: 2 / -1; | |||
grid-row: -2 / -1; | |||
} | |||
} | |||
#main-nav { | |||
.level2 .away ul { | |||
display: none; | |||
} | |||
} | |||
#content { | |||
img { | |||
max-width: 100%; | |||
} | |||
} |
@@ -7,35 +7,51 @@ $susy: ( | |||
'spread': 'narrow', | |||
'container-spread': 'narrow', | |||
); | |||
@import "include-media"; | |||
//---------------------------------- | |||
// reset | |||
* { | |||
box-sizing:border-box; | |||
} | |||
$SiteMaxWidth: 1000px; | |||
$BannerMinWidth:750px; | |||
body { | |||
margin: .5em; | |||
} | |||
nav * { | |||
list-style: none; | |||
padding:0; | |||
margin:0; | |||
} | |||
html { | |||
height:100vh; | |||
} | |||
html { -webkit-text-size-adjust: 100%; } | |||
$view_mobile: "only screen and (max-width : 450px)"; | |||
$view_tablet: "only screen and (max-width : 1149px)"; | |||
$view_not_mobile: "only screen and (min-width : 1150px)"; | |||
// font-weight: | |||
// defaults taken from https://www.w3schools.com/csSref/pr_font_weight.asp | |||
$normal: 400; | |||
$bold: 700; | |||
$light: 100; | |||
$hspace: 1.3em; | |||
$vspace: 1.3em; | |||
$view_biggest: "only screen and (min-width : 1000px)"; | |||
$view_compact: "only screen and (max-width : 950px)"; | |||
$view_mobile: "only screen and (max-width : 750px)"; | |||
$view_not_mobile: "only screen and (min-width : 751px)"; | |||
$view_smallest_banner: "only screen and (max-width : 750px)"; | |||
@import "colours"; | |||
@import "freaCMSfeatures"; | |||
//@import "fonts"; | |||
@import "fonts"; | |||
@import "structure"; | |||
@import "design"; | |||
@import "onthefly"; | |||
//@import "admin"; | |||
//@import "dev"; | |||
// mobile query: | |||
$mobile-device: "only screen and (max-width : 800px)"; | |||
$not-mobile: "only screen and (min-width : 801px)"; | |||
@@ -1,8 +1,30 @@ | |||
var menu_open = false; | |||
var site_pos = 0; | |||
var menu_pos = 0; | |||
function toggle_menu(){ | |||
var menu = document.querySelector('#mobile-nav'); | |||
menu.classList.toggle('open'); | |||
var body = document.querySelector('body'); | |||
var content = $('html,body'); | |||
if (menu_open) { | |||
menu_open = false; | |||
menu.classList.toggle('open'); | |||
body.classList.toggle('openmobilenav'); | |||
$(content).scrollTop(site_pos); | |||
} else { | |||
menu_open = true; | |||
site_pos = $(content).scrollTop(); | |||
$(content).scrollTop(0); | |||
menu.classList.toggle('open'); | |||
body.classList.toggle('openmobilenav'); | |||
} | |||
} | |||
// $( document ).ready(function() { | |||
// var mainnav = $("#main-nav"); | |||
// var platzhalter = $("#platzhalter"); |
@@ -1,6 +1,20 @@ | |||
* { | |||
box-sizing: border-box; } | |||
body { | |||
margin: .5em; } | |||
nav * { | |||
list-style: none; | |||
padding: 0; | |||
margin: 0; } | |||
html { | |||
height: 100vh; } | |||
html { | |||
-webkit-text-size-adjust: 100%; } | |||
html { | |||
color: #777; | |||
background: #fff; } | |||
@@ -47,18 +61,18 @@ a.content_element_box div.content_element_box { | |||
top: -10px; | |||
right: -10px; | |||
font-size: 1.5em; } | |||
@media only screen and (max-width: 750px) { | |||
@media only screen and (max-width: 450px) { | |||
.featherlight .featherlight-content iframe { | |||
width: 100%; | |||
height: 100%; } } | |||
@media only screen and (max-width: 750px) { | |||
@media only screen and (max-width: 450px) { | |||
#main-nav { | |||
display: none; } } | |||
#mobile-nav { | |||
display: none; } | |||
@media only screen and (max-width: 750px) { | |||
@media only screen and (max-width: 450px) { | |||
#mobile-nav { | |||
display: block; } | |||
#mobile-nav a.menu-toggle { | |||
@@ -95,60 +109,9 @@ html, body { | |||
margin: 0; | |||
padding: 0; } | |||
.content_element_page.wall a.content_element_box { | |||
float: left; } | |||
.content_element_page.wall:after { | |||
content: ""; | |||
display: block; | |||
clear: both; } | |||
.content_element_page.wall div.content_element_box { | |||
height: 100px; } | |||
#page-wrap { | |||
display: grid; | |||
grid-template-columns: 250px auto; | |||
grid-template-rows: 200px 100fr 3em; | |||
height: 100vh; | |||
overflow: hidden; | |||
max-width: 1300px; | |||
margin: 0 auto; } | |||
#page-wrap > header { | |||
grid-column: 1 / -1; } | |||
#page-wrap #main-nav { | |||
grid-column: 1 / span 1; | |||
grid-row: 2 / -1; } | |||
#page-wrap #content { | |||
grid-column: 2 / -1; | |||
grid-row: 2 / 3; | |||
overflow-y: auto; } | |||
#page-wrap #main-footer { | |||
grid-column: 2 / -1; | |||
grid-row: -2 / -1; } | |||
#main-nav .level2 .away ul { | |||
display: none; } | |||
#content img { | |||
max-width: 100%; } | |||
a { | |||
text-decoration: none; } | |||
a:hover { | |||
text-decoration: underline; } | |||
ul.nav { | |||
list-style: none; } | |||
ul.nav li { | |||
margin: 0; } | |||
ul.nav .active > a { | |||
font-weight: bold; } | |||
#main-nav { | |||
background: #eec; | |||
border-radius: 1.2em 1.2em 0 0; } | |||
#main-nav ul { | |||
padding-left: 1.5em; } | |||
#main-nav .level1 > li, #main-nav .level2 > li { | |||
margin-top: 1em; } | |||
/*# sourceMappingURL=style.css.map */ |
@@ -1,6 +1,6 @@ | |||
{ | |||
"version": 3, | |||
"mappings": "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", | |||
"mappings": "AAaA,CAAE;EACE,UAAU,EAAC,UAAU;;AAEzB,IAAK;EACD,MAAM,EAAE,IAAI;;AAEhB,KAAM;EACF,UAAU,EAAE,IAAI;EAChB,OAAO,EAAC,CAAC;EACT,MAAM,EAAC,CAAC;;AAEZ,IAAK;EACD,MAAM,EAAC,KAAK;;AAEhB,IAAK;EAAE,wBAAwB,EAAE,IAAI;;ACpBrC,IAAK;EACD,KAAK,EALH,IAAI;EAMN,UAAU,EARP,IAAI;;AAWX,CAAE;EACE,KAAK,EAVH,IAAI;;ACCN,4BAAO;EACC,OAAO,EAAE,IAAI;AAGjB,kCAAO;EACH,OAAO,EAAE,MAAM;AAEnB,qCAAU;EACN,OAAO,EAAE,IAAI;AAGrB,6CAAwB;EACpB,OAAO,EAAE,YAAY;EACrB,QAAQ,EAAE,QAAQ;EAClB,MAAM,EAAE,KAAK;EACb,MAAM,EAAC,GAAG;EAEV,oDAAO;IAAE,MAAM,EAAC,IAAI;EACpB,iDAAI;IACA,MAAM,EAAE,IAAI;IACZ,KAAK,EAAE,IAAI;EAEf,sDAAS;IACL,QAAQ,EAAE,QAAQ;IAClB,KAAK,EAAE,IAAI;IACX,MAAM,EAAC,CAAC;IACR,KAAK,EAAC,CAAC;IACP,UAAU,EAAE,wBAAqB;;AAI7C,wBAAyB;EACrB,OAAO,EAAE,IAAI;;AAKjB,wBAAyB;EACrB,OAAO,EAAE,IAAI;EACb,qBAAqB,EAAC,OAAO;;AAKjC,mCAAoC;EAChC,UAAU,EAAE,IAAI;EAChB,QAAQ,EAAE,OAAO;EACjB,4DAAyB;IACrB,KAAK,EDnDN,IAAI;ICoDH,UAAU,EAAE,IAAI;IAChB,GAAG,EAAE,KAAK;IACV,KAAK,EAAE,KAAK;IACZ,SAAS,EAAE,KAAK;EAEpB,yCAAuB;IACnB,0CAAO;MAAE,KAAK,EAAC,IAAI;MAAE,MAAM,EAAC,IAAI;;AASpC,yCAAuB;EAD3B,SAAU;IAEF,OAAO,EAAE,IAAI;;AAIrB,WAAY;EACR,OAAO,EAAE,IAAI;EACb,yCAAuB;IAF3B,WAAY;MAGJ,OAAO,EAAE,KAAK;MACd,yBAAc;QACV,OAAO,EAAE,KAAK;EAGtB,qBAAU;IACN,OAAO,EAAE,IAAI;EAEjB,0BAAiB;IACb,OAAO,EAAE,KAAK;IACd,QAAQ,EAAE,KAAK;IACf,GAAG,EAAC,CAAC;IACL,IAAI,EAAC,CAAC;IACN,OAAO,EAAC,EAAE;IACV,UAAU,EAAE,wBAAqB;IACjC,MAAM,EAAC,IAAI;IACX,KAAK,EAAE,IAAI;IACX,QAAQ,EAAE,MAAM;EAEpB,yBAAc;IACV,QAAQ,EAAE,KAAK;IACf,GAAG,EAAC,CAAC;IACL,KAAK,EAAC,CAAC;IACP,KAAK,EAAC,IAAI;IACV,MAAM,EAAC,IAAI;IACX,OAAO,EAAC,GAAG;IACX,MAAM,EAAE,OAAO;IACf,UAAU,EAAE,wBAAqB;IACjC,gBAAgB,EAAE,oBAAoB;IACtC,mBAAmB,EAAE,GAAG;IACxB,eAAe,EAAE,IAAI;EAEzB,8BAAqB;IACjB,mBAAmB,EAAE,MAAM;;ACxGnC,UAAU;EACN,MAAM,EAAC,IAAI;EACX,MAAM,EAAC,CAAC;EACR,OAAO,EAAC,CAAC;;ACRb,CAAE;EACE,eAAe,EAAE,IAAI;EACrB,OAAQ;IACJ,eAAe,EAAE,SAAS", | |||
"sources": ["sass/main.scss","sass/_colours.scss","sass/_freaCMSfeatures.scss","sass/_structure.scss","sass/_design.scss"], | |||
"names": [], | |||
"file": "style.css" |