Browse Source

update to latest version, developed outside git

dev01
Dom SP 3 years ago
parent
commit
f8b8db5f3d
31 changed files with 1233 additions and 260 deletions
  1. +10
    -4
      app/controller/page.php
  2. +217
    -0
      app/freaParsedown.php
  3. +4
    -1
      app/modules/cachedimage.php
  4. +174
    -45
      app/modules/filesinfolders.php
  5. +5
    -0
      app/views/colors.css
  6. +10
    -9
      app/views/header.htm
  7. +39
    -26
      app/views/tpl/index.html
  8. +58
    -0
      doc/conetent_elements.md
  9. +47
    -15
      index.php
  10. +2
    -0
      main.cfg.sample
  11. BIN
      rsc/favicons/android-chrome-192x192.png
  12. BIN
      rsc/favicons/android-chrome-256x256.png
  13. BIN
      rsc/favicons/apple-touch-icon.png
  14. +9
    -0
      rsc/favicons/browserconfig.xml
  15. BIN
      rsc/favicons/favicon-16x16.png
  16. BIN
      rsc/favicons/favicon-32x32.png
  17. BIN
      rsc/favicons/favicon.ico
  18. BIN
      rsc/favicons/mstile-150x150.png
  19. +19
    -0
      rsc/favicons/site.webmanifest
  20. BIN
      rsc/img/back01.JPG
  21. BIN
      rsc/img/default.png
  22. BIN
      rsc/img/menu-icon.png
  23. +0
    -16
      rsc/sass/_design.scss
  24. +3
    -16
      rsc/sass/_fonts.scss
  25. +565
    -0
      rsc/sass/_include-media.scss
  26. +0
    -0
      rsc/sass/_onthefly.scss
  27. +0
    -58
      rsc/sass/_structure.scss
  28. +30
    -14
      rsc/sass/main.scss
  29. +23
    -1
      rsc/script.js
  30. +17
    -54
      rsc/style.css
  31. +1
    -1
      rsc/style.css.map

+ 10
- 4
app/controller/page.php View File

)); ));
self::folder2(); self::folder2();
break; break;
}
}
} }






$folder->prepare_files(); $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(); $folder->fill_content();

foreach($f3->get('siteColors') as $k=>$v){ foreach($f3->get('siteColors') as $k=>$v){
$f3->set($k, $f3->set($k,
array_key_exists($k,$folder->config) array_key_exists($k,$folder->config)
} }
if ($folder->extras['background'] if ($folder->extras['background']
&& !$folder->config['supressBackground']) { && !$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('background',$background);
$f3->set('content', implode("\n", $folder->content['default'])); $f3->set('content', implode("\n", $folder->content['default']));

+ 217
- 0
app/freaParsedown.php View File

<?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,
),
),
);
}
}
}

+ 4
- 1
app/modules/cachedimage.php View File

function get_src($inwidth = 500) { function get_src($inwidth = 500) {
$f3 = \Base::instance(); $f3 = \Base::instance();
if($this->is_image($this->original)) {
if($this->is_image($this->original) && TRUE) {
$info = pathinfo($this->original); $info = pathinfo($this->original);
$fn = basename($this->original,'.'.$info['extension']); $fn = basename($this->original,'.'.$info['extension']);
$width = $inwidth ? $inwidth : $this->default_width; $width = $inwidth ? $inwidth : $this->default_width;
$img1 = new \Image($this->original); $img1 = new \Image($this->original);
$img1->resize($width); $img1->resize($width);
$f3->write($out,$img1->dump('jpeg',75)); $f3->write($out,$img1->dump('jpeg',75));
unset($img1);
} }
} else { } else {
$out = $this->original; $out = $this->original;
} }


function is_image($path) { 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); $ex = explode('.',$path);
$ext = array_pop($ex); $ext = array_pop($ex);
return in_array(strtolower($ext),array( 'jpg', 'jpeg', 'png' )); return in_array(strtolower($ext),array( 'jpg', 'jpeg', 'png' ));

+ 174
- 45
app/modules/filesinfolders.php View File

private $state=array(); private $state=array();


function __construct($folder,$conf=array()) { function __construct($folder,$conf=array()) {
debug("about to construct FIF: $folder");
$f3 = \Base::instance(); $f3 = \Base::instance();
if(is_dir($folder)) { // are we given a valid path? if(is_dir($folder)) { // are we given a valid path?
} }
} }
} }

foreach($this->domains as $domain) { foreach($this->domains as $domain) {
$this->content[$domain] = array(); $this->content[$domain] = array();
} }
foreach($this->keyfiles as $keys=>$d) { foreach($this->keyfiles as $keys=>$d) {
$this->extras[$keys] = ""; $this->extras[$keys] = "";
} }
debug("constructed files in folder: $folder");
} }




// prepare content as per the struct // // prepare content as per the struct //
/////////////////////////////////////// ///////////////////////////////////////
function fill_content() { function fill_content() {
$md = new \Parsedown();
$md = new \freaParsedown();
$md->deactivate_ol();
//var_dump($md->get_BlockTypes());
foreach($this->domains as $domain_key=>$domain) { foreach($this->domains as $domain_key=>$domain) {
// don't act on hidden files
if ($domain == 'hidden') { continue; }
$this->state['current_domain'] = $domain_key; $this->state['current_domain'] = $domain_key;
foreach($this->structs[$domain_key]['txt'] as $key=>$file) { foreach($this->structs[$domain_key]['txt'] as $key=>$file) {
$str = $this->read_textfile($file); $str = $this->read_textfile($file);
$str = self::content_element_dispatcher($str); $str = self::content_element_dispatcher($str);
$str = $md->text($str); $str = $md->text($str);
$str = sprintf("<div class='post'>%s</div>", $str);
//$str = sprintf("%s", $str);
$this->content[$domain][$key] = sprintf( $this->content[$domain][$key] = sprintf(
"<div class=\"item %s %s\">%s</div>", "<div class=\"item %s %s\">%s</div>",
$page, $page,
// Utility functions // // Utility functions //
/////////////////////// ///////////////////////
function read_textfile($file) { function read_textfile($file) {
debug("about to read file: $file");
$str = file_get_contents($file); $str = file_get_contents($file);
debug("read file: $file");
$str = self::linkify($str); $str = self::linkify($str);
$str = self::strip_comments($str); $str = self::strip_comments($str);
$str = self::get_config_from_content($str); $str = self::get_config_from_content($str);
debug("processed file: $file");
return $str; return $str;
} }
function strip_comments($str) { function strip_comments($str) {
} }
function content_element_dispatcher($string) { function content_element_dispatcher($string) {
$f3 = \Base::instance(); $f3 = \Base::instance();
$md = new \Parsedown();
$md = new \freaParsedown();
$md->deactivate_ol();
$f0 = 0; $f0 = 0;
// find occorances of {| keyword |} // find occorances of {| keyword |}
$pattern = "/\{\|(.+?)\|\}/s"; $pattern = "/\{\|(.+?)\|\}/s";
$request[1] $request[1]
); );
break; break;
case 'span':
$new=sprintf("<span class=\"%s\">%s</span>",
$request[1],
$request[2] ? : implode("\n",$body)
);
break;
case 'small-text': case 'small-text':
if(count($body)) { if(count($body)) {
$new=sprintf("<div class=\"f1\">%s</div>",
$new=sprintf("<div class=\"smalltext\">%s</div>",
implode("\n",$body) implode("\n",$body)
); );
} else { } else {
$new=sprintf("<span class=\"f1\">%s</span>",
$new=sprintf("<span class=\"smalltext\">%s</span>",
$request[1] $request[1]
); );
} }
$type = array_shift($request); $type = array_shift($request);
$pics = explode(":",array_shift($body)); $pics = explode(":",array_shift($body));
$pic = $pics[0]; $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">&nbsp;</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']?:"&nbsp;"),
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) { switch($type) {
case 'plain':
$link=false;
break;
case 'download': case 'download':
$file = "/".$this->folder.implode(":",$request); $file = "/".$this->folder.implode(":",$request);
$link='href="'.$file.'" download '; $link='href="'.$file.'" download ';
break; break;
case 'lightbox': case 'lightbox':
$body = implode("\n",$body); $body = implode("\n",$body);
if (count($request) % 2) {
$class = array_pop($request);
}
if (count($request) >= 2) { if (count($request) >= 2) {
$body=str_replace([$request[0],$request[1]],["{|","|}"],$body); $body=str_replace([$request[0],$request[1]],["{|","|}"],$body);
$body=$this->content_element_dispatcher($body); $body=$this->content_element_dispatcher($body);
} }
$hash=md5($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, $hash,
$md->text($body)); $md->text($body));
$link='href="#" data-featherlight="#'.$hash.'" '; $link='href="#" data-featherlight="#'.$hash.'" ';
break; break;
case 'internal': case 'internal':
$dest=implode(":",$request); $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; break;
case 'external': case 'external':
$dest=implode(":",$request); $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; break;
default: default:
$link='href="#"'; $link='href="#"';
break; 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\"> <div class=\"image\">
<img class=\"standard\" src=\"%s\" /><img class=\"hover\" src=\"%s\" /> <img class=\"standard\" src=\"%s\" /><img class=\"hover\" src=\"%s\" />
</div> </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, $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 $add
); );
break; 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': case 'calendar':
array_shift($request); array_shift($request);
$conf = array('path', $this->folder); $conf = array('path', $this->folder);
$v = $this->read_config(); $v = $this->read_config();
$cal = new \Modules\CCalendar($v,$conf); $cal = new \Modules\CCalendar($v,$conf);
$new=sprintf("<div class=\"calendar\">%s</div>",
$new=sprintf("<div class=\"calendar\">\n%s\n</div>",
$cal); $cal);
break; break;


case 'image': case 'image':
$key=$request[1]; $key=$request[1];
$image=""; $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) { foreach($this->structs as $domain=>$destination) {
if(array_key_exists($key, $this->structs[$domain]['pic'])) { if(array_key_exists($key, $this->structs[$domain]['pic'])) {
} }
} }
$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>" ."<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\" />" ."<img src=\"%s\" style=\"display:none;\" alt=\"user supplied image\" />"
."<div class=\"caption\">%s</div>" ."<div class=\"caption\">%s</div>"
."</div>", ."</div>",
$class, $class,
$ratio, $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)) $md->text(implode("\n",$body))
); );
} else { } 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; break;
case 'devide': case 'devide':
$new = '<div class="content_element_devided">';
$contents = explode($request[1],implode("\n",$body)); $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; $counter=0;
$new = sprintf('<div class="content_element_devided" style="%s">',$template);
foreach($contents as $part) { foreach($contents as $part) {
$counter++; $counter++;
if (count($request) >= 4) { if (count($request) >= 4) {
$part=str_replace([$request[2],$request[3]],["{|","|}"],$part); $part=str_replace([$request[2],$request[3]],["{|","|}"],$part);
$part=$this->content_element_dispatcher($part); $part=$this->content_element_dispatcher($part);
} }
$new .= sprintf("<div>%s</div>",
$new .= sprintf("<div>\n%s\n</div>",
$md->text($part) $md->text($part)
); );
} }
$new.="</div>"; $new.="</div>";

break; break;


case 'page': case 'page':
$target = array_shift($request); $target = array_shift($request);
$class = array_shift($request); $class = array_shift($request);
$folder = $this->folder.$target."/"; $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, $class,
implode("\n",$f->content['default']));
implode("\n",$fff->content['default']));
break; break;
case 'youtube': case 'youtube':

+ 5
- 0
app/views/colors.css View File

html { html {
background-color: {{ @backgroundColor }}; background-color: {{ @backgroundColor }};
background-image: url(/{{ @backgroundImage }});
background-position: bottom right;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: 2000px 2000px;
} }

+ 10
- 9
app/views/header.htm View File

<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>

+ 39
- 26
app/views/tpl/index.html View File

<meta name="robots" content="noindex, nofollow"> <meta name="robots" content="noindex, nofollow">
</check> </check>
<meta name="viewport" content="width=device-width, initial-scale=1"> <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" /> <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 }}jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="/{{ @RESOURCES }}script.js"></script> <script type="text/javascript" src="/{{ @RESOURCES }}script.js"></script>
<link type="text/css" href="/{{ @RESOURCES }}style.css" rel="stylesheet" /> <link type="text/css" href="/{{ @RESOURCES }}style.css" rel="stylesheet" />
<title>{{ @title }}</title> <title>{{ @title }}</title>
<style> <style>
<include href="colors.css" /> <include href="colors.css" />
li { margin-left:1em; }
</style> </style>
</head> </head>
<body class="{{ @bodyClass }}"> <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"> <div id="page-wrap">
<header> <header>
<include href="header.htm"> <include href="header.htm">
</header> </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> <div id="platzhalter"></div>
<section id="content"> <section id="content">
<include href="maincontent.htm" /> <include href="maincontent.htm" />
<include href="sidebar.htm" /> <include href="sidebar.htm" />
</section> </section>
<footer id="main-footer">
<nav>
<include href="navigation.htm" with="menu={{ @navi.footer }}" />
</nav>
</footer>


</div> <!-- #page-wrap --> </div> <!-- #page-wrap -->
<footer id="main-footer">
<nav>
<include href="navigation.htm" with="menu={{ @navi.footer }}" />
</nav>
</footer>
<check if="{{ @backend }}"> <check if="{{ @backend }}">
<div id="admin-panel">{{ @backend | raw }}</div> <div id="admin-panel">{{ @backend | raw }}</div>
</check> </check>

+ 58
- 0
doc/conetent_elements.md View File

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

+ 47
- 15
index.php View File

<?php <?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: // // configure installation: //
///////////////////////////// /////////////////////////////

define("ROOT", "./"); define("ROOT", "./");
require_once( ROOT.'lib/autoload.php' ); require_once( ROOT.'lib/autoload.php' );
error_reporting(0);
ini_set("log_errors", 1);
ini_set("error_log", "php-error.log");


/** @var \Base $f3 */ /** @var \Base $f3 */
$f3 = \Base::instance(); $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('AUTOLOAD', ROOT.'app/');
$f3->set('UI', implode(';',array(
$f3->set('UI', implode(';', array(
ROOT.'app/views/', ROOT.'app/views/',
ROOT.'content/' // content folders can contain .html templates ROOT.'content/' // content folders can contain .html templates
))); )));


if(!is_dir($f3->get('TEMP'))) {
if (!is_dir($f3->get('TEMP'))) {
mkdir($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: // // main configuration: //
///////////////////////// /////////////////////////

debug("before read config");
$f3->config( ROOT.'main.cfg' ); $f3->config( ROOT.'main.cfg' );
if(!setlocale(LC_TIME, 'de_DE.UTF-8')) { if(!setlocale(LC_TIME, 'de_DE.UTF-8')) {


/////////////////////////////////////////////// ///////////////////////////////////////////////
// configuration based on configuration file // // 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 // set language
$languages = $f3->get('languages'); $languages = $f3->get('languages');
$f3->set('default_lang', array_shift($languages)); $f3->set('default_lang', array_shift($languages));
$ex = explode(":=", $value); $ex = explode(":=", $value);
if (count($ex) > 1) { if (count($ex) > 1) {
# external link # 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 { } else {
# internal link # internal link
$href = $f3->get('SITE_URL').$path; $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'; $class .= in_array($path,$f3->get('url')) ? ' active' : ' away';
} }
$out[$path]['name']=$ex[0]; $out[$path]['name']=$ex[0];
$url[]="/".implode("/",array_slice($url_ex,0,$i)); $url[]="/".implode("/",array_slice($url_ex,0,$i));
} }
$f3->set('url', $url); $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 $f3->set('level', 1); // this is for templates, to be abl to count nesting
read_menu("main"); read_menu("main");
read_menu("footer"); read_menu("footer");
read_menu("network");
#read_menu("network");
read_menu("languages"); read_menu("languages");
read_menu("mobilelang");






// development utility functions // // development utility functions //
/////////////////////////////////// ///////////////////////////////////


function debug($Message=".") {
if(DEBUG > 0) {
echo "<br>".$Message;
}
}




############################################################################## ##############################################################################
)); ));




debug("before run fatfree");
$f3->run(); $f3->run();
echo \Template::instance()->render($f3->get('template')); echo \Template::instance()->render($f3->get('template'));

+ 2
- 0
main.cfg.sample View File

;default site template: ;default site template:
template=tpl/index.html template=tpl/index.html



external_links_open_in_new_window=false

BIN
rsc/favicons/android-chrome-192x192.png View File

Before After
Width: 192  |  Height: 192  |  Size: 1.3KB

BIN
rsc/favicons/android-chrome-256x256.png View File

Before After
Width: 256  |  Height: 256  |  Size: 1.5KB

BIN
rsc/favicons/apple-touch-icon.png View File

Before After
Width: 180  |  Height: 180  |  Size: 1.3KB

+ 9
- 0
rsc/favicons/browserconfig.xml View File

<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
<msapplication>
<tile>
<square150x150logo src="/favicons/mstile-150x150.png"/>
<TileColor>#da532c</TileColor>
</tile>
</msapplication>
</browserconfig>

BIN
rsc/favicons/favicon-16x16.png View File

Before After
Width: 16  |  Height: 16  |  Size: 1003B

BIN
rsc/favicons/favicon-32x32.png View File

Before After
Width: 32  |  Height: 32  |  Size: 1006B

BIN
rsc/favicons/favicon.ico View File

Before After

BIN
rsc/favicons/mstile-150x150.png View File

Before After
Width: 270  |  Height: 270  |  Size: 1.4KB

+ 19
- 0
rsc/favicons/site.webmanifest View File

{
"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"
}

BIN
rsc/img/back01.JPG View File

Before After
Width: 4608  |  Height: 3456  |  Size: 3.2MB

BIN
rsc/img/default.png View File

Before After
Width: 170  |  Height: 164  |  Size: 26KB Width: 170  |  Height: 164  |  Size: 11KB

BIN
rsc/img/menu-icon.png View File

Before After
Width: 790  |  Height: 1580  |  Size: 49KB

+ 0
- 16
rsc/sass/_design.scss View File

} }
} }


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; }
}

+ 3
- 16
rsc/sass/_fonts.scss View File

// 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;
}
}

+ 565
- 0
rsc/sass/_include-media.scss View File

@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;
}
}
}
}

+ 0
- 0
rsc/sass/_onthefly.scss View File


+ 0
- 58
rsc/sass/_structure.scss View File

margin:0; margin:0;
padding: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%;
}
}

+ 30
- 14
rsc/sass/main.scss View File

'spread': 'narrow', 'spread': 'narrow',
'container-spread': 'narrow', 'container-spread': 'narrow',
); );
@import "include-media";


//----------------------------------
// reset
* { * {
box-sizing:border-box; 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 "colours";
@import "freaCMSfeatures"; @import "freaCMSfeatures";
//@import "fonts";
@import "fonts";
@import "structure"; @import "structure";
@import "design"; @import "design";
@import "onthefly";
//@import "admin"; //@import "admin";


//@import "dev"; //@import "dev";



// mobile query:
$mobile-device: "only screen and (max-width : 800px)";
$not-mobile: "only screen and (min-width : 801px)";


+ 23
- 1
rsc/script.js View File


var menu_open = false;
var site_pos = 0;
var menu_pos = 0;
function toggle_menu(){ function toggle_menu(){
var menu = document.querySelector('#mobile-nav'); 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() { // $( document ).ready(function() {
// var mainnav = $("#main-nav"); // var mainnav = $("#main-nav");
// var platzhalter = $("#platzhalter"); // var platzhalter = $("#platzhalter");

+ 17
- 54
rsc/style.css View File

* { * {
box-sizing: border-box; } 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 { html {
color: #777; color: #777;
background: #fff; } background: #fff; }
top: -10px; top: -10px;
right: -10px; right: -10px;
font-size: 1.5em; } font-size: 1.5em; }
@media only screen and (max-width: 750px) {
@media only screen and (max-width: 450px) {
.featherlight .featherlight-content iframe { .featherlight .featherlight-content iframe {
width: 100%; width: 100%;
height: 100%; } } height: 100%; } }


@media only screen and (max-width: 750px) {
@media only screen and (max-width: 450px) {
#main-nav { #main-nav {
display: none; } } display: none; } }


#mobile-nav { #mobile-nav {
display: none; } display: none; }
@media only screen and (max-width: 750px) {
@media only screen and (max-width: 450px) {
#mobile-nav { #mobile-nav {
display: block; } display: block; }
#mobile-nav a.menu-toggle { #mobile-nav a.menu-toggle {
margin: 0; margin: 0;
padding: 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 { a {
text-decoration: none; } text-decoration: none; }
a:hover { a:hover {
text-decoration: underline; } 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 */ /*# sourceMappingURL=style.css.map */

+ 1
- 1
rsc/style.css.map View File

{ {
"version": 3, "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"], "sources": ["sass/main.scss","sass/_colours.scss","sass/_freaCMSfeatures.scss","sass/_structure.scss","sass/_design.scss"],
"names": [], "names": [],
"file": "style.css" "file": "style.css"

Loading…
Cancel
Save