Browse Source

Produktive initial version

Markus Spring 1 year ago
parent
commit
7234230e6a
65 changed files with 3381 additions and 0 deletions
  1. 4 0
      .gitignore
  2. BIN
      270.png
  3. BIN
      Proxima Nova Alt Bold.otf
  4. BIN
      Proxima Nova Alt Light.otf
  5. BIN
      Proxima Nova Alt Thin.otf
  6. BIN
      Proxima Nova Black.otf
  7. BIN
      Proxima Nova Bold.otf
  8. BIN
      Proxima Nova Extrabold.otf
  9. BIN
      Proxima Nova Thin.otf
  10. BIN
      ProximaNova-Regular.otf
  11. BIN
      TerminalDosis-Bold.woff
  12. BIN
      TerminalDosis-Bold.woff2
  13. BIN
      TerminalDosis-ExtraBold.woff
  14. BIN
      TerminalDosis-ExtraBold.woff2
  15. BIN
      TerminalDosis-ExtraLight.woff
  16. BIN
      TerminalDosis-ExtraLight.woff2
  17. BIN
      TerminalDosis-Light.woff
  18. BIN
      TerminalDosis-Light.woff2
  19. BIN
      TerminalDosis-Medium.woff
  20. BIN
      TerminalDosis-Medium.woff2
  21. BIN
      TerminalDosis-Regular.woff
  22. BIN
      TerminalDosis-Regular.woff2
  23. BIN
      TerminalDosis-SemiBold.woff
  24. BIN
      TerminalDosis-SemiBold.woff2
  25. 73 0
      archive.php
  26. 68 0
      archive_loop.php
  27. 139 0
      archives.php
  28. 272 0
      blogroll.php
  29. 276 0
      blogroll_lfi.php
  30. 116 0
      comments-page.php
  31. BIN
      fonts/raleway-v29-latin-300.ttf
  32. BIN
      fonts/raleway-v29-latin-300.woff2
  33. BIN
      fonts/raleway-v29-latin-300italic.ttf
  34. BIN
      fonts/raleway-v29-latin-300italic.woff2
  35. BIN
      fonts/raleway-v29-latin-500.ttf
  36. BIN
      fonts/raleway-v29-latin-500.woff2
  37. BIN
      fonts/raleway-v29-latin-700.ttf
  38. BIN
      fonts/raleway-v29-latin-700.woff2
  39. BIN
      fonts/raleway-v29-latin-700italic.ttf
  40. BIN
      fonts/raleway-v29-latin-700italic.woff2
  41. BIN
      fonts/raleway-v29-latin-italic.ttf
  42. BIN
      fonts/raleway-v29-latin-italic.woff2
  43. BIN
      fonts/raleway-v29-latin-regular.ttf
  44. BIN
      fonts/raleway-v29-latin-regular.woff2
  45. 385 0
      functions.php
  46. 35 0
      header.php
  47. 32 0
      index-common-places.php
  48. 32 0
      index-vernacular.php
  49. 48 0
      index.php
  50. 191 0
      linkpage2.php
  51. 40 0
      linkpage4.php
  52. 392 0
      linkpage5.php
  53. 42 0
      linkpage6.php
  54. 288 0
      postie-helper.php
  55. BIN
      proxima_nova_alt_light-webfont.woff
  56. BIN
      proxima_nova_alt_light-webfont.woff2
  57. BIN
      proxima_nova_thin-webfont.woff
  58. BIN
      proxima_nova_thin-webfont.woff2
  59. BIN
      proximanova-regular-webfont.woff
  60. BIN
      proximanova-regular-webfont.woff2
  61. 421 0
      style.css
  62. 45 0
      template-parts/header/site-branding.php
  63. 30 0
      template-parts/header/titlepage-header.php
  64. 179 0
      titlepage.css
  65. 273 0
      titlepage.php

+ 4 - 0
.gitignore

@@ -0,0 +1,4 @@
+*~
+titlepage.css.min
+cronlinks2.html
+cronlinks.html

BIN
270.png


BIN
Proxima Nova Alt Bold.otf


BIN
Proxima Nova Alt Light.otf


BIN
Proxima Nova Alt Thin.otf


BIN
Proxima Nova Black.otf


BIN
Proxima Nova Bold.otf


BIN
Proxima Nova Extrabold.otf


BIN
Proxima Nova Thin.otf


BIN
ProximaNova-Regular.otf


BIN
TerminalDosis-Bold.woff


BIN
TerminalDosis-Bold.woff2


BIN
TerminalDosis-ExtraBold.woff


BIN
TerminalDosis-ExtraBold.woff2


BIN
TerminalDosis-ExtraLight.woff


BIN
TerminalDosis-ExtraLight.woff2


BIN
TerminalDosis-Light.woff


BIN
TerminalDosis-Light.woff2


BIN
TerminalDosis-Medium.woff


BIN
TerminalDosis-Medium.woff2


BIN
TerminalDosis-Regular.woff


BIN
TerminalDosis-Regular.woff2


BIN
TerminalDosis-SemiBold.woff


BIN
TerminalDosis-SemiBold.woff2


+ 73 - 0
archive.php

@@ -0,0 +1,73 @@
+<?php
+/**
+ * The template for displaying archive pages.
+ *
+ * @link https://codex.wordpress.org/Template_Hierarchy
+ *
+ * @package Optics-mws
+ */
+
+#!-- ---------------------------------------------- for infinite-scroll --- --
+add_filter('next_posts_link_attributes', 'next_posts_link_attributes');
+function next_posts_link_attributes() {
+    return 'class="next pagination__next" style="float:right"';
+}
+
+get_header();
+?>
+<article id="comments-page" class="comments-page page type-page status-publish hentry entry">    
+  <header class="entry-header alignwide">
+    <?php
+    the_archive_title( '<h1 class="page-title">', '</h1>' );
+    the_archive_description( '<div class="taxonomy-description">', '</div>' );
+    ?>
+  </header><!-- .page-header -->
+  <div class="entry-content archive-wider">
+    <ul class="blocks-gallery-grid">
+    <?php while ( have_posts() ) : ?>
+              
+      <?php
+      /* get_template_part( 'template-parts/content', get_post_format() ); */
+      $post = get_post(the_post());
+      echo "<!-- post->ID: $post->ID -->\n";
+      $image = false;
+      if ( get_attached_media('image', $post->ID) ) {
+          $image = array_shift(get_attached_media('image', $post->ID));
+          $image = $image->ID;
+          echo "<!-- image->ID: $image -->\n";
+          $imgs = get_attached_media('image', $post->ID);
+          foreach($imgs as $img) 
+              echo "<!-- // img->ID: $img->ID -->\n";
+      }
+      if (! $image) {
+          $image = get_post_thumbnail_id($post->ID);
+          echo "<!-- get_the_post_thumbnail " . $image . " -->\n";
+      }
+      if ( $image ) {
+          /* $thumbsrc = wp_get_attachment_image_src($image->ID, 'optics-mws-gallery-thumb')[0]; */
+          $thumbsrc = wp_get_attachment_image_src($image, 'thumbnail')[0];
+          $fullsrc =  wp_get_attachment_image_src($image,'full')[0];
+          $style = "";
+          echo "<!-- thumbsrc: $thumbsrc // fullsrc: $fullsrc -->\n";
+      } else {
+          $thumbsrc = get_stylesheet_uri() . '/../270.png';
+          $tithumbsrc = get_stylesheet_uri() . '/../560.png';
+          echo "<!-- thumbsrc: $thumbsrc // tithumbsrc: $tithumbsrc -->\n";
+          $style = "style='display: inline-block !important; background: #ddd;'";
+      }
+      /* echo "<li class='blocks-gallery-item'><figure><a href='$fullsrc'><img src='$thumbsrc' /></a>\n"; */
+      echo "<li class='archive-slide'><figure><a href='$fullsrc'><img src='$thumbsrc' class='archive-slide-slide'/></a>\n";
+      echo "<div class='archive-slide-titlebar' $style><a href='", get_permalink($post->ID),
+      "' title='", get_the_date('', $post->ID), "'><span>", get_the_title($post->ID), "<br />(",
+      get_the_date('', $post->ID), ")</span></a></div>";   
+      echo '</figure></li>';
+      ?>
+    <?php endwhile; ?>
+    </ul>
+    <?php the_posts_pagination(); ?>
+  </div>
+</article>
+
+<?php 
+get_footer();
+?>

+ 68 - 0
archive_loop.php

@@ -0,0 +1,68 @@
+<main id="main" class="site-main" role="main"> 
+<div id="primary" class="content-area">
+<article id="comments-page" class="comments-page page type-page status-publish hentry entry">    
+  <header class="entry-header alignwide">
+    <?php
+    the_archive_title( '<h1 class="page-title">', '</h1>' );
+    the_archive_description( '<div class="taxonomy-description">', '</div>' );
+    ?>
+  </header><!-- .page-header -->
+  
+  <?php
+  if ( have_posts() ) : ?>
+    
+    <div class="entry-content">
+      <?php /* Start the Loop */ ?>
+      <div class="mosaic-container entry-content post">
+        
+      </div><!-- #mosaic-container -->
+    </div>
+  <?php else :
+  
+  get_template_part( 'template-parts/content', 'none' );
+  
+  endif; ?>
+</article>
+    <header class="entry-header alignwide">
+      <?php
+      the_archive_title( '<h1 class="page-title">', '</h1>' );
+      the_archive_description( '<div class="taxonomy-description">', '</div>' );
+      ?>
+    </header><!-- .page-header -->
+
+
+
+
+
+
+<?php while ( have_posts() ) : ?>
+              
+	      <?php
+              /* get_template_part( 'template-parts/content', get_post_format() ); */
+              $post = get_post(the_post());
+              $image = false;
+              if ( get_attached_media('image', $post->ID) ) {
+                  $image = array_shift(get_attached_media('image', $post->ID));
+                  $image = $image->ID;
+              }
+              if (! $image) {
+                  $image = get_post_thumbnail_id($post->ID);
+                  echo "<!-- get_the_post_thumbnail " . $image . " -->\n";
+              }
+              if ( $image ) {
+                  /* $thumbsrc = wp_get_attachment_image_src($image->ID, 'optics-mws-gallery-thumb')[0]; */
+                  $thumbsrc = wp_get_attachment_image_src($image, 'thumbnail')[0];
+                  $fullsrc =  wp_get_attachment_image_src($image,'full')[0];
+                  $style = "";
+              } else {
+                  $thumbsrc = get_stylesheet_uri() . '/../270.png';
+                  $tithumbsrc = get_stylesheet_uri() . '/../560.png';
+                  $style = "style='display: inline-block !important; background: #ddd;'";
+              }
+              echo "<div class='box box2'><a href='$fullsrc'><img src='$thumbsrc' /></a>\n";
+              echo "<div class='imagetitlebar' $style><a href='", get_permalink($post->ID),
+              "'><span><b>", get_the_title($post->ID), "</b><br />(",
+              get_the_date('', $post->ID), ")</span></a></div>";   
+              echo '</div><!-- end box -->';
+              ?>
+	    <?php endwhile; ?>

+ 139 - 0
archives.php

@@ -0,0 +1,139 @@
+<?php
+/*
+Template Name: Archives Template
+*/
+/************* Archive Category Walker *****************/
+$ms_stylesheet_directory = get_bloginfo('stylesheet_directory');
+class Walker_Category_Rabbit extends Walker_Category {
+    function start_el( &$output, $category, $depth = 0, $args = array(), $id = 0 ) {
+        extract($args);
+        global $ms_stylesheet_directory;
+        
+        $cat_name = esc_attr( $category->name );
+        $cat_name = apply_filters( 'list_cats', $cat_name, $category );
+        $link = '<a href="' . esc_url( get_term_link($category) ) . '" ';
+        if ( $use_desc_for_title == 0 || empty($category->description) )
+            $link .= 'title="' . esc_attr( sprintf(__( 'View all posts filed under %s' ), $cat_name) ) . '"';
+        else
+            $link .= 'title="' . esc_attr( strip_tags( apply_filters( 'category_description', $category->description, $category ) ) ) . '"';
+        $link .= '>';
+        $link .= $cat_name . '</a>';
+            
+    if ( !empty($feed_image) || !empty($feed) ) {
+      $link .= ' ';
+      
+      if ( empty($feed_image) )
+        $link .= '(';
+      
+      $link .= '<a href="' . esc_url( get_term_feed_link( $category->term_id, $category->taxonomy, $feed_type ) ) . '"';
+      
+      if ( empty($feed) ) {
+        $alt = ' alt="' . sprintf(__( 'Feed for all posts filed under %s' ), $cat_name ) . '"';
+      } else {
+        $title = ' title="' . $feed . '"';
+        $alt = ' alt="' . $feed . '"';
+        $name = $feed;
+        $link .= $title;
+      }
+
+      $link .= '>';
+      
+      if ( empty($feed_image) )
+        $link .= $name;
+      else
+        $link .= "<img src='$feed_image'$alt$title" . ' />';
+      
+      $link .= '</a>';
+      
+      if ( empty($feed_image) )
+        $link .= ')';
+    }
+    
+    if ( !empty($show_count) )
+      $link .= ' (' . intval($category->count) . ')';
+    
+    if ( 'list' == $args['style'] ) {
+      $output .= "\t<li";
+      $class = 'cat-item cat-item-' . $category->term_id;
+      if ( !empty($current_category) ) {
+        $_current_category = get_term( $current_category, $category->taxonomy );
+        if ( $category->term_id == $current_category )
+          $class .=  ' current-cat';
+        elseif ( $category->term_id == $_current_category->parent )
+          $class .=  ' current-cat-parent';
+      }
+      $output .=  ' class="' . $class . '"';
+      $output .= ">$link\n";
+    } else {
+      $output .= "\t$link<br />\n";
+    }
+  }
+}
+
+/* called in archives.php
+   adds link to mosaic_page for monthly archives */
+function miech_archive_mosaic_filter ( $link_html ) {
+    preg_match('/\/(\d\d\d\d)\/(\d\d)\//', $link_html, $match);
+    $link_html = preg_replace('/<li>\s*<a href=["\'].*?["\']/i', '<li><a href="' . home_url() . '/image-mosaic?mosaic_month=' . $match[2]
+                            . '&mosaic_year=' . $match[1] . '"', $link_html );
+    return $link_html;
+}
+
+/* debugging helper
+   from http://www.stumiller.me/sending-output-to-the-wordpress-debug-log/ */
+if (!function_exists('write_log')) {
+    function write_log ( $log )  {
+        if ( true === WP_DEBUG ) {
+            if ( is_array( $log ) || is_object( $log ) ) {
+                error_log( print_r( $log, true ) );
+            } else {
+                error_log( $log );
+            }
+        }
+    }
+}
+
+?>
+<?php get_header(); ?>
+
+<div id="content" class="site-content">
+  <div id="primary" class="content-area">
+    <main id="main" class="site-main" role="main">
+      
+      <article id="post-31164" class="post-31164 page type-page status-publish hentry entry">
+        
+	<header class="entry-header alignwide">
+	  <h1 class="entry-title">Archives</h1>			
+	</header>
+	
+	<div class="entry-content">
+	  
+          <div class="wp-block-columns">
+            <div class="wp-block-column">
+              <strong>Archives by Month</strong>
+              <ul>
+                <?php
+                #          add_filter('get_archives_link', 'miech_archive_mosaic_filter', 10, 1);
+                wp_get_archives('type=monthly&show_post_count=1');
+                #          remove_filter('get_archives_link', 'miech_archive_mosaic_filter', 10, 1);
+                ?>
+              </ul>
+            </div>
+            
+            <div class="wp-block-column">
+              <strong>Archives by Category</strong>
+              <ul>
+                <?php /* wp_list_categories('title_li=0&show_count=1&exclude=1140&walker=Walker_Category_Rabbit'); */
+                $MyWalker = new Walker_Category_Rabbit();
+                wp_list_categories(array('title_li'   => 0,
+                                         'show_count' => 1,
+                                         /* 'exclude'    => '1140', */
+                                         'walker'     => $MyWalker));
+                ?><!--  -->
+              </ul>
+            </div>
+          </div>
+        </div>
+      </article>
+
+<?php get_footer(); ?>

+ 272 - 0
blogroll.php

@@ -0,0 +1,272 @@
+<?php
+/*
+Template Name: Blogroll
+*/
+
+function scratch99_fromthisblog() {
+    $ref = $_SERVER['HTTP_REFERER'];
+    $host = $_SERVER['HTTP_HOST'];
+    if( $ref == "" ) return true;
+    if( strpos($host, $ref) !== false ) return false;
+    return false;
+} 
+
+function scratch99_last_post_thumbnail_link () {
+    $recent_posts = wp_get_recent_posts(array(
+        'numberposts' => 10, // Number of recent posts thumbnails to display
+        'post_status' => 'publish' // Show only the published posts
+    ));
+    foreach( $recent_posts as $recent ) {
+        if ( has_post_thumbnail($recent['ID']) ) { // check if the post has a Post Thumbnail assigned to it.
+            echo "<div style='text-align: right;'><a href='" . get_permalink($recent['ID']) . "'>";
+            echo "<span style='padding-right: 1em; font-weight: bold;'>New on spring2life</span> ";
+            echo get_the_post_thumbnail($recent['ID'],'thumbnail', 'style=float:right;') . "</a></div>";
+            break;
+        }
+    }
+}
+
+function debug_echo ( $text ) {
+    if ( true ) {
+        /* echo 'debug: <![CDATA[ ', str_replace('<', '&lt;', $text), " ]]><br>\n"; */
+        /* echo 'debug: ', $text, "<br>\n"; */
+    }
+}
+
+function insert_chunk_before( $before, $newest_only, $chunk ) {
+    return preg_replace("/<\/ul>\n<li class='linkhead'><h4>$before<\/h4>/",
+                        "<li>$chunk</li>\n</ul>\n<li class='linkhead'><h4>$before</h4>", $newest_only);
+}
+
+function process_oren_grad($chunk, $newest_only, $omitflag) {
+    $chunk = preg_replace('#<div class=[\'"]item-content[\'"]>.*</div>#s', '', $chunk);
+    $chunk = preg_replace('#</div>#s', '', $chunk);
+    $now = date_timestamp_get(date_create());
+    if ( false === ( $og = get_transient( 'orengrad' ) ) ) { /* no transient could be restored */
+        $result = curlDownload('http://orengrad.com/thingsseen/index.html');
+        $og[1] = md5($result); 
+        $og[0] = $now;
+        set_transient('orengrad', $og);
+    } else {                            /* there is a transient */
+        if ( $now - $og[0] > 1*3600 ) { /* timestamp older than 12h, so compare again */
+            $oldhash = $og[1];
+            $result = curlDownload('http://orengrad.com/thingsseen/index.html');/* nochmal holen */
+            $og[1] = md5($result);
+            if ( $og[1] <> $oldhash ) { /* not equal, so save again */
+                $og[0] = $now; 
+                set_transient('orengrad', $og);/* set transient with new timestamp */
+                /* } else {
+                   debug_echo('Hashes are equal'); */
+            }
+        }
+    }
+    $diff_in_seconds = date_timestamp_get(date_create()) - $og[0];
+    echo "<!-- orengrad diff_in_seconds: $diff_in_seconds -->";
+    if ( $diff_in_seconds < 24 * 3600 ) {
+        $newest_only = insert_chunk_before('A day and older', $newest_only, $chunk);
+    } elseif ( $diff_in_seconds < 30 * 24 * 3600 ) {
+        $newest_only = insert_chunk_before('Less than a month old', $newest_only, $chunk);
+    } else {
+        $newest_only = insert_chunk_before('Older', $newest_only, $chunk);
+    }
+    /* delete_transient('orengrad');  */
+    $omitflag = true;
+    return array($newest_only, $omitflag);
+}
+
+function process_lfi_online($chunk, $newest_only, $omitflag) {
+    $chunk = preg_replace('#<div class=[\'"]item-content[\'"]>.*</div>#s', '', $chunk);
+    $chunk = preg_replace('#</div>#s', '', $chunk);
+    if ( false === ( $result = get_transient( 'lfionlinede' ) ) ) {
+        $result = curlDownload('https://lfi-online.de/ceemes/en/blog/');
+        $chunk = str_replace('<div class=[\'"]blog-title[\'"]>', '', $chunk);
+        if ( preg_match('#<div class="titlebox30 cu-pointer" onclick="window.location = \'(.*?)\'">\s*<h1 class="typo-1">(.*?)</h1>\s*<span class="subline">\s*<h2 class="sl typo-26">.*?</h2>\s*<h3 class="sl typo-27">(.*?)</h3>#s', $result, $matches)) {
+            $chunk = $chunk . ":&nbsp;<span class=\"item-title\">\n<a href=\"$matches[1]\" target=\"_blank\">\n$matches[2]</a></span>";
+            set_transient('lfionlinede', $chunk, 12*3600);
+        }
+    } else {
+        $chunk = $result;
+    }
+    /* delete_transient('lfionlinede'); */
+    /* Assumption: LFI comes in the last section of all entries, because it does not show a date to google.
+       Therefore all headlines are already written to $newestonly and we can insert before */
+    /* $age_in_days = date_diff(date_create($matches[3]), date_create(date("d.m.Y")))->format('%a'); */
+    $age_in_days = date_diff(date_create($matches[3]), date_create(date("d.m.Y")));
+    #echo "<!-- lfi age in days: ", $age_in_days, " -->";
+    if ($age_in_days < 1) {
+        $newest_only = insert_chunk_before('A day and older', $newest_only, $chunk);
+    } elseif ($age_in_days < 30) {
+        $newest_only = insert_chunk_before('Less than a month old', $newest_only, $chunk);
+    } else {
+        $newest_only = insert_chunk_before('Older', $newest_only, $chunk);
+    } 
+    $omitflag = true;
+    return array($newest_only, $omitflag);
+}
+
+function cleanup_chunk ( $chunk ) {
+    $chunk = preg_replace("/[\s]*<div class=[\"']item-time[\"']>.*<\/div>/ism", "", $chunk);
+    $chunk = preg_replace("/<div class=[\"']item-content[\"']>[\r\n]?/ism", "", $chunk);
+    $chunk = preg_replace("/<div class=[\"']blog-title[\"']>[\r\n]?/ism", "<li>", $chunk);
+    $chunk = preg_replace("/<\/div>[\r\n]?/ism", ":&nbsp;", $chunk);
+    $chunk = preg_replace("/<\/span>/ism", "</span></li>", $chunk);
+    return $chunk;
+}
+
+function blogs_i_read() {
+    $url = "http://spring2life-links.blogspot.de";
+    if ( false === ( $html = get_transient( $url ) ) ) {
+        $html = curlDownload($url);
+        if ( ! $html ) {
+            echo "<h2>There is a problem with the http request!</h2>";
+        } else {
+            if ( ! preg_match('/(<ul id=\'BlogList1_blogs.*?<\/ul>)/is', $html, $matches)) {
+                echo "Error: could not retrieve valid spring2life-links blogroll<br>", $html;
+                return;
+            } else { 
+                set_transient( $url, $html, 3600 );
+            }
+        }
+    }
+    /* delete_transient($url); */
+    $html = preg_replace('/.*<div class=["\']widget BlogList["\'] id=["\']BlogList1["\']>/ism', '', $html);
+    $newest_only = "";
+    $stundenflag = false;
+    $tagflag = false;
+    $wochenflag = false;
+    $monatflag = false;
+    $pleistoflag = false;
+    preg_match_all('/<div class=["\']blog-title["\']>.*<div class=["\']item-time["\']>.*<\\/div>/Us', $html, $matches);
+    foreach ($matches[0] as $chunk) {
+        $omitflag = false;
+        if ( preg_match("/orengrad.com/ism", $chunk) ) {
+            list ($newest_only, $omitflag) = process_oren_grad($chunk, $newest_only, $omitflag);
+        }
+        if ( preg_match("#/lfi-online.de/ceemes/#", $chunk) ) {
+            list ($newest_only, $omitflag) = process_lfi_online($chunk, $newest_only, $omitflag);
+        }
+        if ( preg_match("/vor\s+\d+\s+(Minute|Stunde)/ism", $chunk) )
+            if (! $stundenflag) {
+                $chunk = "<li class='linkhead'><h4>Hot from the Sphere</h4></li>\n\n<ul>\n" . $chunk;
+                $stundenflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+(Tag)/ism", $chunk) )
+            if (! $tagflag) {
+                $chunk = "</ul>\n<li class='linkhead'><h4>A day and older</h4></li>\n<ul>\n" . $chunk;
+                $tagflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+Woche/ism", $chunk) )
+            if (! $wochenflag) {
+                $chunk = "</ul>\n<li class='linkhead'><h4>Less than a month old</h4></li>\n<ul>\n" . $chunk;
+                $wochenflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+(Monat)/ism", $chunk) )
+            if (! $monatflag) {
+                $chunk = "</ul><li class='linkhead'><h4>Older</h4></li>\n<ul>\n" . $chunk; $monatflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+(Jahr)/ism", $chunk) )
+            if (! $pleistoflag) {
+                $chunk = "</ul><li class='linkhead'><h4>From the Pleistozaen</h4></li>\n<ul>\n" . $chunk; $pleistoflag = true;
+            }
+        $chunk = cleanup_chunk($chunk);
+        if ( $omitflag == false )
+            $newest_only .= $chunk;
+        if ( preg_match('/href=\'(http:\/\/feedproxy.google.com.*?)\'/', $chunk, $match) ) {
+            $proxyurl = $match[1];
+            if ( false === ( $cleanurl = get_transient( md5('cleanurlof' . $proxyurl) ) ) ) {
+                $cleanurl = resolveUrl($proxyurl);
+                $cleanurl = doHardcore($cleanurl);
+                set_transient( md5("cleanurlof" . $proxyurl), $cleanurl, 90000 + rand(1,3600) );
+            } $chunk = str_replace($match[1], $cleanurl, $chunk);
+        }
+    }
+    return $newest_only;
+}
+
+function resolveUrl($url) {
+    try {
+        $header = doCurlRequest($url); return $header['redirect_url']; } catch (Exception $ex) {
+            _log("error freeing url $url: " . $ex->getMessage()); return $url;
+        }
+}
+
+function curlDownload($Url){
+    $ch = curl_init();
+    curl_setopt($ch, CURLOPT_URL, $Url);
+    curl_setopt($ch, CURLOPT_REFERER, "https://markus-spring.info");
+    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0");
+    curl_setopt($ch, CURLOPT_HEADER, 0);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+    curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
+    $output = curl_exec($ch);
+    curl_close($ch);
+    return $output;
+}
+
+if(!function_exists('_log')) {
+    function _log( $message ) {
+        if( WP_DEBUG === true ) {
+            if( is_array( $message ) || is_object( $message ) ) {
+                error_log( print_r( $message, true ) );
+            } else {
+                error_log( $message );
+            }
+        }
+    }
+}
+
+function doCurlRequest($url) {
+    $curlSession = curl_init($url);
+    curl_setopt($curlSession, CURLOPT_NOBODY, 1);
+    $curlResponse = curl_exec($curlSession);
+    $header = curl_getinfo($curlSession);
+    curl_close($curlSession);
+    return $header;
+}
+
+function doHardcore($url) {
+    try {
+        $parts = explode("?", $url);
+        $ret = $parts[0];
+        _log("do hardcore: [$url] -> [$ret]");
+        return $ret;
+    } catch (Exception $ex) {
+        _log("error in hardcore: " . $ex->getMessage());
+        return $url;
+    }
+}
+
+?>
+<?php get_header(); ?>
+<div id="content" class="site-content">
+  <div id="primary" class="content-area">
+    <main id="main" class="site-main" role="main">
+      <article id="post--31201" class="post--31201 post type-post status-publish format-image hentry category-vernacular post_format-post-format-image entry">
+        <header class="entry-header">
+	  <h2 class="entry-title default-max-width">Blogs I read</h2>
+	</header><!-- .entry-header -->
+        
+        <div id="content" class="site-content">
+          <div id="primary" class="content-area">
+            <main id="main" class="site-main" role="main">
+	
+	      <div class="entry-content">
+                <ul class="linktable">
+                  <?php
+                  if (scratch99_fromthisblog()) {
+                      scratch99_last_post_thumbnail_link();
+                  }
+                  ?>
+                  <?php echo blogs_i_read(); ?>
+                </ul>
+              </div><!-- .entry-content -->
+            </main>
+          </div>
+        </div>
+      </article><!-- #post-31164 -->
+    </main><!-- #main -->
+  </div><!-- #primary -->
+</div><!-- #content -->
+<?php get_footer(); ?>

+ 276 - 0
blogroll_lfi.php

@@ -0,0 +1,276 @@
+<?php
+/*
+Template Name: Blogroll Test
+*/
+
+function scratch99_fromthisblog() {
+    $ref = $_SERVER['HTTP_REFERER'];
+    $host = $_SERVER['HTTP_HOST'];
+    if( $ref == "" ) return true;
+    if( strpos($host, $ref) !== false ) return false;
+    return false;
+} 
+
+function scratch99_last_post_thumbnail_link () {
+    $recent_posts = wp_get_recent_posts(array(
+        'numberposts' => 10, // Number of recent posts thumbnails to display
+        'post_status' => 'publish' // Show only the published posts
+    ));
+    foreach( $recent_posts as $recent ) {
+        if ( has_post_thumbnail($recent['ID']) ) { // check if the post has a Post Thumbnail assigned to it.
+            echo "<div style='text-align: right;'><a href='" . get_permalink($recent['ID']) . "'>";
+            echo "<span style='padding-right: 1em; font-weight: bold;'>New on spring2life</span> ";
+            echo get_the_post_thumbnail($recent['ID'],'thumbnail', 'style=float:right;') . "</a></div>";
+            break;
+        }
+    }
+}
+
+function debug_echo ( $text ) {
+    /* if ( false ) { */
+        /* echo 'debug: <![CDATA[ ', str_replace('<', '&lt;', $text), " ]]><br>\n"; */
+        echo 'debug: ', $text, "<br>\n";
+    /* } */
+}
+
+function insert_chunk_before( $before, $newest_only, $chunk ) {
+    return preg_replace("/<\/ul>\n<li class='linkhead'><h4>$before<\/h4>/",
+                        "<li>$chunk</li>\n</ul>\n<li class='linkhead'><h4>$before</h4>", $newest_only);
+}
+
+function process_oren_grad($chunk, $newest_only, $omitflag) {
+    $chunk = preg_replace('#<div class=[\'"]item-content[\'"]>.*</div>#s', '', $chunk);
+    $chunk = preg_replace('#</div>#s', '', $chunk);
+    $now = date_timestamp_get(date_create());
+    if ( false === ( $og = get_transient( 'orengrad' ) ) ) { /* no transient could be restored */
+        $result = curlDownload('http://orengrad.com/thingsseen/index.html');
+        $og[1] = md5($result); 
+        $og[0] = $now;
+        set_transient('orengrad', $og);
+    } else {                            /* there is a transient */
+        if ( $now - $og[0] > 1*3600 ) { /* timestamp older than 12h, so compare again */
+            $oldhash = $og[1];
+            $result = curlDownload('http://orengrad.com/thingsseen/index.html');/* nochmal holen */
+            $og[1] = md5($result);
+            if ( $og[1] <> $oldhash ) { /* not equal, so save again */
+                $og[0] = $now; 
+                set_transient('orengrad', $og);/* set transient with new timestamp */
+                /* } else {
+                   debug_echo('Hashes are equal'); */
+            }
+        }
+    }
+    $diff_in_seconds = date_timestamp_get(date_create()) - $og[0];
+    echo "<!-- orengrad diff_in_seconds: $diff_in_seconds -->";
+    if ( $diff_in_seconds < 24 * 3600 ) {
+        $newest_only = insert_chunk_before('A day and older', $newest_only, $chunk);
+    } elseif ( $diff_in_seconds < 30 * 24 * 3600 ) {
+        $newest_only = insert_chunk_before('Less than a month old', $newest_only, $chunk);
+    } else {
+        $newest_only = insert_chunk_before('Older', $newest_only, $chunk);
+    }
+    /* delete_transient('orengrad');  */
+    $omitflag = true;
+    return array($newest_only, $omitflag);
+}
+
+function process_lfi_online($chunk, $newest_only, $omitflag) {
+    $chunk = preg_replace('#<div class=[\'"]item-content[\'"]>.*</div>#s', '', $chunk);
+    $chunk = preg_replace('#</div>#s', '', $chunk);
+    $matches = [];
+    if ( false === ( $result = get_transient( 'lfionlinede' ) ) ) {
+        $result = curlDownload('https://lfi-online.de/ceemes/en/blog/');
+        $chunk = str_replace('<div class=[\'"]blog-title[\'"]>', '', $chunk);
+        if ( preg_match('#<div class="titlebox30 cu-pointer" onclick="window.location = \'(.*?)\'">\s*<h1 class="typo-1">(.*?)</h1>\s*<span class="subline">\s*<h2 class="sl typo-26">.*?</h2>\s*<h3 class="sl typo-27">(.*?)</h3>#s', $result, $matches)) {
+            $chunk = $chunk . ":&nbsp;<span class=\"item-title\">\n<a href=\"$matches[1]\" target=\"_blank\">\n$matches[2]</a></span>";
+            set_transient('lfionlinede', $chunk, 12*3600);
+        }
+    } else {
+        $chunk = $result;
+    }
+    /* delete_transient('lfionlinede'); */
+    /* Assumption: LFI comes in the last section of all entries, because it does not show a date to google.
+       Therefore all headlines are already written to $newestonly and we can insert before */
+    /* $age_in_days = date_diff(date_create($matches[3]), date_create(date("d.m.Y")))->format('%a'); */
+    $age_in_days = date_diff(date_create($matches[3]), date_create(date("d.m.Y")));
+    debug_echo($matches[0]);
+    /* debug_echo(date_create($matches[3])); */
+    /*     debug_echo(date_create(date("d.m.Y"))); */
+    #echo "<!-- lfi age in days: ", $age_in_days, " -->";
+    if ($age_in_days < 1) {
+        $newest_only = insert_chunk_before('A day and older', $newest_only, $chunk);
+    } elseif ($age_in_days < 30) {
+        $newest_only = insert_chunk_before('Less than a month old', $newest_only, $chunk);
+    } else {
+        $newest_only = insert_chunk_before('Older', $newest_only, $chunk);
+    } 
+    $omitflag = true;
+    return array($newest_only, $omitflag);
+}
+
+function cleanup_chunk ( $chunk ) {
+    $chunk = preg_replace("/[\s]*<div class=[\"']item-time[\"']>.*<\/div>/ism", "", $chunk);
+    $chunk = preg_replace("/<div class=[\"']item-content[\"']>[\r\n]?/ism", "", $chunk);
+    $chunk = preg_replace("/<div class=[\"']blog-title[\"']>[\r\n]?/ism", "<li>", $chunk);
+    $chunk = preg_replace("/<\/div>[\r\n]?/ism", ":&nbsp;", $chunk);
+    $chunk = preg_replace("/<\/span>/ism", "</span></li>", $chunk);
+    return $chunk;
+}
+
+function blogs_i_read() {
+    $url = "http://spring2life-links.blogspot.de";
+    if ( false === ( $html = get_transient( $url ) ) ) {
+        $html = curlDownload($url);
+        if ( ! $html ) {
+            echo "<h2>There is a problem with the http request!</h2>";
+        } else {
+            if ( ! preg_match('/(<ul id=\'BlogList1_blogs.*?<\/ul>)/is', $html, $matches)) {
+                echo "Error: could not retrieve valid spring2life-links blogroll<br>", $html;
+                return;
+            } else { 
+                set_transient( $url, $html, 3600 );
+            }
+        }
+    }
+    /* delete_transient($url); */
+    $html = preg_replace('/.*<div class=["\']widget BlogList["\'] id=["\']BlogList1["\']>/ism', '', $html);
+    $newest_only = "";
+    $stundenflag = false;
+    $tagflag = false;
+    $wochenflag = false;
+    $monatflag = false;
+    $pleistoflag = false;
+    preg_match_all('/<div class=["\']blog-title["\']>.*<div class=["\']item-time["\']>.*<\\/div>/Us', $html, $matches);
+    foreach ($matches[0] as $chunk) {
+        $omitflag = false;
+        if ( preg_match("/orengrad.com/ism", $chunk) ) {
+            list ($newest_only, $omitflag) = process_oren_grad($chunk, $newest_only, $omitflag);
+        }
+        if ( preg_match("#/lfi-online.de/ceemes/#", $chunk) ) {
+            list ($newest_only, $omitflag) = process_lfi_online($chunk, $newest_only, $omitflag);
+        }
+        if ( preg_match("/vor\s+\d+\s+(Minute|Stunde)/ism", $chunk) )
+            if (! $stundenflag) {
+                $chunk = "<li class='linkhead'><h4>Hot from the Sphere</h4></li>\n\n<ul>\n" . $chunk;
+                $stundenflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+(Tag)/ism", $chunk) )
+            if (! $tagflag) {
+                $chunk = "</ul>\n<li class='linkhead'><h4>A day and older</h4></li>\n<ul>\n" . $chunk;
+                $tagflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+Woche/ism", $chunk) )
+            if (! $wochenflag) {
+                $chunk = "</ul>\n<li class='linkhead'><h4>Less than a month old</h4></li>\n<ul>\n" . $chunk;
+                $wochenflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+(Monat)/ism", $chunk) )
+            if (! $monatflag) {
+                $chunk = "</ul><li class='linkhead'><h4>Older</h4></li>\n<ul>\n" . $chunk; $monatflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+(Jahr)/ism", $chunk) )
+            if (! $pleistoflag) {
+                $chunk = "</ul><li class='linkhead'><h4>From the Pleistozaen</h4></li>\n<ul>\n" . $chunk; $pleistoflag = true;
+            }
+        $chunk = cleanup_chunk($chunk);
+        if ( $omitflag == false )
+            $newest_only .= $chunk;
+        if ( preg_match('/href=\'(http:\/\/feedproxy.google.com.*?)\'/', $chunk, $match) ) {
+            $proxyurl = $match[1];
+            if ( false === ( $cleanurl = get_transient( md5('cleanurlof' . $proxyurl) ) ) ) {
+                $cleanurl = resolveUrl($proxyurl);
+                $cleanurl = doHardcore($cleanurl);
+                set_transient( md5("cleanurlof" . $proxyurl), $cleanurl, 90000 + rand(1,3600) );
+            } $chunk = str_replace($match[1], $cleanurl, $chunk);
+        }
+    }
+    return $newest_only;
+}
+
+function resolveUrl($url) {
+    try {
+        $header = doCurlRequest($url); return $header['redirect_url']; } catch (Exception $ex) {
+            _log("error freeing url $url: " . $ex->getMessage()); return $url;
+        }
+}
+
+function curlDownload($Url){
+    $ch = curl_init();
+    curl_setopt($ch, CURLOPT_URL, $Url);
+    curl_setopt($ch, CURLOPT_REFERER, "https://markus-spring.info");
+    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0");
+    curl_setopt($ch, CURLOPT_HEADER, 0);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+    curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
+    $output = curl_exec($ch);
+    curl_close($ch);
+    return $output;
+}
+
+if(!function_exists('_log')) {
+    function _log( $message ) {
+        if( WP_DEBUG === true ) {
+            if( is_array( $message ) || is_object( $message ) ) {
+                error_log( print_r( $message, true ) );
+            } else {
+                error_log( $message );
+            }
+        }
+    }
+}
+
+function doCurlRequest($url) {
+    $curlSession = curl_init($url);
+    curl_setopt($curlSession, CURLOPT_NOBODY, 1);
+    $curlResponse = curl_exec($curlSession);
+    $header = curl_getinfo($curlSession);
+    curl_close($curlSession);
+    return $header;
+}
+
+function doHardcore($url) {
+    try {
+        $parts = explode("?", $url);
+        $ret = $parts[0];
+        _log("do hardcore: [$url] -> [$ret]");
+        return $ret;
+    } catch (Exception $ex) {
+        _log("error in hardcore: " . $ex->getMessage());
+        return $url;
+    }
+}
+
+?>
+<?php get_header(); ?>
+<div id="content" class="site-content">
+  <div id="primary" class="content-area">
+    <main id="main" class="site-main" role="main">
+      <article id="post--31201" class="post--31201 post type-post status-publish format-image hentry category-vernacular post_format-post-format-image entry">
+        <header class="entry-header">
+	  <h2 class="entry-title default-max-width">Blogs I read</h2>
+	</header><!-- .entry-header -->
+        
+        <div id="content" class="site-content">
+          <div id="primary" class="content-area">
+            <main id="main" class="site-main" role="main">
+	
+	      <div class="entry-content">
+                <ul class="linktable">
+                  <?php
+                  if (scratch99_fromthisblog()) {
+                      scratch99_last_post_thumbnail_link();
+                  }
+                  ?>
+                  <?php echo blogs_i_read(); ?>
+                </ul>
+              </div><!-- .entry-content -->
+            </main>
+          </div>
+        </div>
+      </article><!-- #post-31164 -->
+    </main><!-- #main -->
+  </div><!-- #primary -->
+</div><!-- #content -->
+<?php get_footer(); ?>

+ 116 - 0
comments-page.php

@@ -0,0 +1,116 @@
+<?php
+/*
+Template Name: Comments page
+ */
+
+$limit = 25; /* Comments per Page */
+
+function get_url_var($name) {
+    $strURL = $_SERVER['REQUEST_URI'];
+    $arrVals = split("/",$strURL);
+    $found = 0;
+    foreach ($arrVals as $index => $value) {
+        if($value == $name)
+            $found = $index;
+    }
+    $place = $found + 1;
+    return $arrVals[$place];
+}
+
+/* return thumbnail url and image find url for first image of a given post */
+function get_comment_thumb_full ( $post_id ) {
+    $images = get_attached_media('image', $post_id);
+    $thumbsrc = '';
+    $fullsrc = '';
+    foreach($images as $image) {
+        #       $thumbsrc = wp_get_attachment_image_src($image->ID,'optics-mws-gallery-thumb')[0];
+        $thumbsrc = wp_get_attachment_image_src($image->ID,'thumbnail')[0];
+        $fullsrc =  wp_get_attachment_image_src($image->ID,'full')[0];
+        break;
+    }
+    return [$thumbsrc, $fullsrc];
+}
+
+$page = get_query_var('comments');
+
+$offset = (intval($page) * $limit) - $limit;
+if ( $offset < 0 ) {
+    $offset = 0;
+}
+
+$param = array( 'status' => 'approve',
+                'offset' => $offset,
+                'number' => $limit );
+$total_comments = get_comments( array( 'status' => 'approve' ) ); 
+$pages = ceil( count( $total_comments ) / $limit );
+$comments = get_comments( $param );
+
+get_header(); ?>
+
+<div id="content" class="site-content">
+  <div id="primary" class="content-area">
+    <main id="main" class="site-main" role="main">
+    
+      <article id="comments-page" class="comments-page page type-page status-publish hentry entry">
+      
+	<header class="entry-header alignwide">
+	  <h2 class="entry-title">Comments</h1>			
+	</header>
+	
+	<div class="entry-content">
+          <?php
+          foreach( $comments as $comment ) {
+              $post_id = $comment->comment_post_ID;
+              if ( $old_post_id && $old_post_id == $post_id) {
+                  echo "	                      <div class='entry-summary'>\n";
+                  if ($comment->comment_author == 'Markus Spring') {
+                      echo " <strong><a href='{$comment->comment_author_url}' class='owner' "
+                         . "target='_blank'>{$comment->comment_author}</a></strong>\n";
+                  } else {
+                      echo " <strong><a href='{$comment->comment_author_url}'"
+                         . "target='_blank'>{$comment->comment_author}</a></strong>\n";
+                  }
+                  echo " said at {$comment->comment_date}:<br />{$comment->comment_content}\n";
+                  echo "</div><!-- .entry-summary -->\n";
+              } else {
+                  if ($old_post_id) {
+                      echo "<br style='clear: both;' /><hr class='comment-sep' />\n";
+                  }
+                  $old_post_id = $post_id;
+                  list( $thumbsrc, $fullsrc ) = get_comment_thumb_full( $post_id );
+                  if ( $thumbsrc ) {
+                      echo "<div class='wp-block-image' style='margin-bottom: 5px !important;'>"
+                         . "<a href='" . get_permalink($post_id)
+                         . "'><figure class='alignleft size-thumbnail'>"
+                         . "<img loading='lazy' width='268' height='268' "
+                         . "src='" . $thumbsrc . "' alt='' class='wp-image-comments'/></figure></a></div>\n";
+                      echo "<h4 style='display: inline;'>On&nbsp;<a href='" . get_permalink($post_id) . "'>"
+                         . get_the_title($post_id) . "</a></h4>\n"; 
+                  } else {
+                      echo "                        On '" . get_the_title($post_id) . "',<br />"; 
+                  }
+                  echo "	                      <div class='entry-summary'>\n";
+                  if ($comment->comment_author == 'Markus Spring') {
+                      echo "                            <strong><a href='{$comment->comment_author_url}' class='owner' "
+                         . "target='_blank'>{$comment->comment_author}</a></strong>\n";
+                  } else {
+                      echo "                            <strong><a href='{$comment->comment_author_url}'"
+                         . "target='_blank'>{$comment->comment_author}</a></strong>\n";
+                  }
+                  /* echo "                            said at {$comment->comment_date}:<br />{$comment->comment_content}\n"; */
+                  echo "                            said at {$comment->comment_date}:<br />"
+                     . apply_filters('the_content', $comment->comment_content) . "\n";
+                  echo "                        </div><!-- .entry-summary -->\n";
+              }
+          }
+          ?>
+          <footer class="entry-footer">
+            <?php //optics_entry_footer(); ?>
+          </footer><!-- .entry-footer -->
+        </div><!-- end search-result -->
+      </article><!-- #post-## -->
+      
+<?php
+/* get_sidebar();
+   get_footer(); */
+?>

BIN
fonts/raleway-v29-latin-300.ttf


BIN
fonts/raleway-v29-latin-300.woff2


BIN
fonts/raleway-v29-latin-300italic.ttf


BIN
fonts/raleway-v29-latin-300italic.woff2


BIN
fonts/raleway-v29-latin-500.ttf


BIN
fonts/raleway-v29-latin-500.woff2


BIN
fonts/raleway-v29-latin-700.ttf


BIN
fonts/raleway-v29-latin-700.woff2


BIN
fonts/raleway-v29-latin-700italic.ttf


BIN
fonts/raleway-v29-latin-700italic.woff2


BIN
fonts/raleway-v29-latin-italic.ttf


BIN
fonts/raleway-v29-latin-italic.woff2


BIN
fonts/raleway-v29-latin-regular.ttf


BIN
fonts/raleway-v29-latin-regular.woff2


+ 385 - 0
functions.php

@@ -0,0 +1,385 @@
+<?php
+/* test */
+remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
+remove_action( 'wp_print_styles', 'print_emoji_styles' );
+
+/* enqueue scripts and style from parent theme */
+function twentytwentyone_styles() {
+    wp_enqueue_style( 'child-style', get_stylesheet_uri(),
+                      array( 'twenty-twenty-one-style' ), wp_get_theme()->get('Version') );
+}
+
+add_action( 'wp_enqueue_scripts', 'twentytwentyone_styles', 99);
+
+include 'postie-helper.php';
+
+add_filter(
+    'wp_sitemaps_posts_entry',
+    function( $entry, $post ) {
+        $entry['lastmod'] = $post->post_modified_gmt;
+        return $entry;
+    },
+    10,
+    2
+);
+// disable taxonomy sitemap
+function shapeSpace_disable_sitemap_taxonomy($taxonomies) {
+	unset($taxonomies['post_tag']); // can be post_tag, category, post_format, or any taxonomy
+	unset($taxonomies['post_format']); // can be post_tag, category, post_format, or any taxonomy
+	return $taxonomies;
+}
+add_filter('wp_sitemaps_taxonomies', 'shapeSpace_disable_sitemap_taxonomy');
+
+// disable users sitemap
+function shapeSpace_disable_sitemap_users($provider, $name) {
+	return ($name == 'users') ? false : $provider;
+}
+add_filter('wp_sitemaps_add_provider', 'shapeSpace_disable_sitemap_users', 10, 2);
+
+// disable post type sitemap
+function shapeSpace_disable_sitemap_post_types($post_types) {
+	unset($post_types['page']); // can be post, page, or any post type
+	
+	return $post_types;
+}
+add_filter('wp_sitemaps_post_types', 'shapeSpace_disable_sitemap_post_types');
+
+/* https://firstsiteguide.com/wordpress-titles/ */
+function wploop_change_separator() {
+    return '//';
+}
+add_filter('document_title_separator', 'wploop_change_separator');
+
+/* -- https://wordpress.stackexchange.com/questions/240221/modify-page-title-format-when-using-title-tag */
+add_filter( 'document_title_parts', function( $title_parts_array ) {
+    if ( get_the_ID() == 31286 ) {
+        $title_parts_array['title'] = 'Markus Spring Photography';
+    } else {
+        $title_parts_array['site'] = str_replace('spring2life', 'Markus Spring Photography',
+                                                  $title_parts_array['site']);
+    }
+    return $title_parts_array;
+}, 10, 2 );
+
+/* Basic WP SEO
+	Usage: 
+		1. add this code to functions.php
+		2. replace the $default_keywords with your own
+		3. add <?php echo basic_wp_seo(); ?> to header.php
+		4. test well and fine tune as needed
+
+	Optional: add custom description, keywords, and/or title
+	to any post or page using these custom field keys:
+
+		mm_seo_desc
+		mm_seo_keywords
+		mm_seo_title
+
+	To migrate from any SEO plugin, replace its custom field 
+	keys with those listed above. More information:
+
+		@ https://digwp.com/2013/08/basic-wp-seo/
+ */
+function wp_seo_get_description ($post) {
+    // description
+    $seo_desc = get_post_meta($post->ID, 'mm_seo_desc', true);
+    $description = get_bloginfo('description', 'display');
+    $pagedata = get_post($post->ID);
+    if (is_singular()) {
+	if (!empty($seo_desc)) {
+	    $content = $seo_desc;
+	} else if (!empty($pagedata)) {
+	    $content = apply_filters('the_excerpt_rss', $pagedata->post_content);
+	    $content = substr(trim(strip_tags($content)), 0, 155);
+	    $content = preg_replace('#\n#', ' ', $content);
+	    $content = preg_replace('#\s{2,}#', ' ', $content);
+	    $content = trim($content);
+	} 
+    } else {
+	$content = $description;	
+    }
+    return esc_attr($content);
+}
+
+function wp_seo_get_keywords ($post) {
+    // keywords
+    $default_keywords = 'Markus Spring, spring2life, Fotografie, photography, fotoblog, photoblog'; // customize
+    $keys = get_post_meta($post->ID, 'mm_seo_keywords', true);
+    $cats = get_the_category();
+    $tags = get_the_tags();
+    if (empty($keys)) {
+	if (!empty($cats)) foreach($cats as $cat) $keys .= $cat->name . ', ';
+	if (!empty($tags)) foreach($tags as $tag) $keys .= $tag->name . ', ';
+	$keys .= $default_keywords;
+    }
+    return esc_attr($keys);
+}
+
+function basic_wp_seo() {
+    global $page, $paged, $post;
+    $default_keywords = 'Markus Spring, spring2life, Fotografie, photography, fotoblog, photoblog'; // customize
+    $output = '';
+    $output .= '<meta name="description" content="' . wp_seo_get_description($post) . '">' . "\n";
+    $output .= "\t\t" . '<meta name="keywords" content="' . wp_seo_get_keywords($post) . '">' . "\n";
+    // robots
+    if (is_category() || is_tag()) {
+        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
+        if ($paged > 1) {
+            $output .=  "\t\t" . '<meta name="robots" content="noindex,follow">' . "\n";
+        } else {
+            $output .=  "\t\t" . '<meta name="robots" content="index,follow">' . "\n";
+        }
+    } else if (is_home() || is_singular()) {
+        $output .=  "\t\t" . '<meta name="robots" content="index,follow">' . "\n";
+    } else {
+        $output .= "\t\t" . '<meta name="robots" content="noindex,follow">' . "\n";
+    }
+    
+    // title
+    $title_custom = get_post_meta($post->ID, 'mm_seo_title', true);
+    $url = ltrim(esc_url($_SERVER['REQUEST_URI']), '/');
+    $name = get_bloginfo('name', 'display');
+    $title = trim(wp_title('', false));
+    $cat = single_cat_title('', false);
+    $tag = single_tag_title('', false);
+    $search = get_search_query();
+    
+    if (!empty($title_custom)) $title = $title_custom;
+    if ($paged >= 2 || $page >= 2) $page_number = ' | ' . sprintf('Page %s', max($paged, $page));
+    else $page_number = '';
+    
+    if (is_home() || is_front_page()) $seo_title = $name . ' | ' . $description;
+    elseif (is_singular())            $seo_title = $title . ' | ' . $name;
+    elseif (is_tag())                 $seo_title = 'Tag Archive: ' . $tag . ' | ' . $name;
+    elseif (is_category())            $seo_title = 'Category Archive: ' . $cat . ' | ' . $name;
+    elseif (is_archive())             $seo_title = 'Archive: ' . $title . ' | ' . $name;
+    elseif (is_search())              $seo_title = 'Search: ' . $search . ' | ' . $name;
+    elseif (is_404())                 $seo_title = '404 - Not Found: ' . $url . ' | ' . $name;
+    else                              $seo_title = $name . ' | ' . $description;
+
+    
+    $output .= "\t\t" . '<title>' . esc_attr($seo_title . $page_number) . '</title>' . "\n";
+    
+    // OpenGraph
+    $permalink = get_permalink($post->ID);  
+    $output .= '<meta property="og:locale" content="en_GB" />' . "\n";
+    $output .= "<meta property='og:url' content='$permalink'>\n";
+    $output .= "<meta property='og:type' content='article'> \n";
+    $output .= "<meta property='og:title' content='$title'> \n";
+    $output .= "<meta property='og:site_name' content='Markus Spring Photography // spring2life'> \n";
+    $output .= "<meta property='og:description' content='$title | Markus Spring Photography'>\n";
+    $output .= "<meta property='og:image' content='" . get_post_image($post->ID) . "'> \n";
+    // <meta property="article:modified_time" content="2021-03-16T20:48:44+00:00" />
+    /*             echo "<!-- " . print_r($image_attributes) . " -->\n"; */
+    
+    return $output;
+}
+
+function get_post_image ($postID)
+{                   
+    $args = array(
+    'numberposts' => 1,
+    'order'=> 'ASC',
+    'post_mime_type' => 'image',
+    'post_parent' => $postID,
+    'post_status' => null,
+    'post_type' => 'attachment'
+    );
+    $attachments = get_children( $args );
+    //print_r($attachments);
+    if ($attachments) {
+        foreach($attachments as $attachment) {
+            $image_attributes = wp_get_attachment_image_src( $attachment->ID, 'full' );
+            /*             echo "<!-- " . print_r($image_attributes) . " -->\n"; */
+            return $image_attributes[0];
+        }
+    }
+}
+
+/* -------------------------------------------------- further cleanup --- */
+/* Disable emojicons introduced with WP 4.2 */
+/* from http://wordpress.stackexchange.com/questions/185577/disable-emojicons-introduced-with-wp-4-2 */
+function disable_wp_emojicons() {
+  // all actions related to emojis
+  remove_action( 'admin_print_styles', 'print_emoji_styles' );
+  remove_action( 'wp_head', 'print_emoji_detection_script', 7 );
+  remove_action( 'admin_print_scripts', 'print_emoji_detection_script' );
+  remove_action( 'wp_print_styles', 'print_emoji_styles' );
+  remove_filter( 'wp_mail', 'wp_staticize_emoji_for_email' );
+  remove_filter( 'the_content_feed', 'wp_staticize_emoji' );
+  remove_filter( 'comment_text_rss', 'wp_staticize_emoji' );
+  // filter to remove TinyMCE emojis
+  // add_filter( 'tiny_mce_plugins', 'disable_emojicons_tinymce' );
+}
+add_action( 'init', 'disable_wp_emojicons' );
+
+/* from https://wordpress.org/support/topic/remove-googlewebfonts */
+function remove_open_sans() {
+	wp_dequeue_style( 'open-sans-web-font' );
+	wp_deregister_style( 'open-sans-web-font' );
+}
+add_action( 'wp_enqueue_scripts', 'remove_open_sans', 25 );
+
+add_image_size( 'semilarge', 602, 0, false );
+add_image_size( 'old_old_large', 1100, 1100, false );
+add_filter( 'image_size_names_choose','miech_custom_image_sizes' );
+function miech_custom_image_sizes( $sizes ) {
+    return array_merge( $sizes, array(
+        'semilarge' => 'SemiLarge',
+        'old_old_large' => 'Old_old_Large',
+    ) );
+}
+
+/*-- ------------------------------ run postie get posts from admin bar --- --*/
+// https://markus-spring.info/wp-admin/admin.php?page=postie-settings&action=runpostie&Submit=Process+Email
+function webriti_toolbar_link($wp_admin_bar) {
+    $args = array(
+        'id' => 'customlink',
+        'title' => 'Run Postie',
+        'href' => 'https://markus-spring.info/wp-admin/admin.php?page=postie-settings&action=runpostie&Submit=Process+Email',
+        'meta' => array(
+            'class' => 'customlink',
+            'title' => 'run Postie'
+        )
+    );
+    $wp_admin_bar->add_node($args);
+}
+add_action('admin_bar_menu', 'webriti_toolbar_link', 999);
+
+add_action( 'pre_get_posts', 'prefix_category_query' );
+/**
+ * Customize category query using pre_get_posts.
+ * 
+ * @author     FAT Media <http://youneedfat.com>
+ * @copyright  Copyright (c) 2013, FAT Media, LLC
+ * @license    GPL-2.0+
+ * @todo       Change prefix to theme or plugin prefix
+ *
+ */
+function prefix_category_query( $query ) {
+    /* if ( $query->is_main_query() && ! $query->is_feed() && ! is_admin() && is_category() ) { */
+	if ( $query->is_main_query() && ! $query->is_feed() && ! is_admin() && is_archive() ) {
+		$query->set( 'posts_per_page', '40' ); //Change this number to anything you like.
+	}
+
+}
+
+/* ----------------------------------- for manipulating the main loop --- */
+$miech_active_cat;
+
+function miech_get_active_cat ($id) {
+    //_log("Querying active cat for $id");
+    $my_query = new WP_Query('posts_per_page=1');
+    while ( $my_query->have_posts() )
+        $my_query->the_post();
+    $featured_category_1 = get_theme_mod( 'featured_category_1', 'default_value' );
+    $featured_category_2 = get_theme_mod( 'featured_category_2', 'default_value' );
+    $do_not_duplicate = $id; //This is the magic line
+    if (has_category ( $featured_category_1, $id)) { /* Featured Category 1 */
+        $active_cat = $featured_category_1;
+    } else {
+        $active_cat = $featured_category_2;          /* Featured Category 2 */
+    }
+    wp_reset_query();
+    //_log("miech_get_active_cat: Active cat is $active_cat");
+    return $active_cat;
+}
+
+function miech_set_active_cat ( $this_cat ) {
+    global $miech_active_cat;
+    if (have_posts()) {
+        if ( $this_cat ) {
+            $miech_active_cat = $this_cat;
+        } else {
+            $miech_active_cat = miech_get_active_cat($post->ID);
+        }
+        //error_log("miech_set_active_cat: miech_active_cat is $miech_active_cat");
+        if ( get_query_var('paged') )
+           { $paged = get_query_var('paged'); }
+        elseif ( get_query_var('page') )
+           { $paged = get_query_var('page'); }
+        else
+           { $paged = 1; }
+        //error_log("paged: $paged");
+        if ( is_single() )
+            $posts_per_page = 1;
+        else
+            $posts_per_page = 25;
+
+        query_posts( array(
+            'order' => 'DESC',
+            'paged' => $paged,
+            'cat'   => $miech_active_cat,
+            'posts_per_page' => $posts_per_page
+        ) );
+    }
+}
+
+// turn Photon off so we can get the correct image
+$photon_removed = '';
+if ( class_exists( 'Jetpack' ) && Jetpack::is_module_active( 'photon' ) ) { // check that we are, in fact, using Photon in the first place
+    $photon_removed = remove_filter( 'image_downsize', array( Jetpack_Photon::instance(), 'filter_image_downsize' ) );
+}
+
+/*
+Diverse Einstellungen für die functions.php (dort am Ende einfügen)
+von https://faq.netzprisma.de/wordpress-html-ausmisten/
+*/
+
+// Diverse Einträge entfernen
+remove_action('wp_head', 'wp_generator');
+remove_action('wp_head', 'rsd_link');
+remove_action('wp_head', 'wlwmanifest_link');
+
+// Generator-Angaben, z.B. im Feed, entfernen
+function remove_wp_generator() { return ''; }
+add_filter('the_generator','remove_wp_generator');
+// // prev+next Links in Beiträgen entfernen
+// remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
+
+// // shortlink entfernen
+// remove_action('wp_head', 'wp_shortlink_wp_head', 10, 0);
+
+// Post+Kommentar+Kategorie RSS Feed-Links entfernen (entfernt nicht die Feeds selbst)
+remove_action('wp_head', 'feed_links', 2);
+remove_action('wp_head', 'feed_links_extra', 3);
+
+// wp Versions-Parameter ?ver=... von Skripts entfernen, falls unsere WordPress-Version angegeben wird
+function vc_remove_wp_ver_css_js( $src )
+{
+   if (  strpos($src, 'ver='. get_bloginfo('version') )  )
+      $src = remove_query_arg('ver', $src);
+   return $src;
+}
+add_filter('style_loader_src',  'vc_remove_wp_ver_css_js', 9999);
+add_filter('script_loader_src', 'vc_remove_wp_ver_css_js', 9999);
+
+// Emoji js, css und dns-preload entfernen
+remove_action('wp_head', 'print_emoji_detection_script', 7);
+remove_action('wp_print_styles', 'print_emoji_styles');
+add_filter('emoji_svg_url', '__return_false');
+
+// // REST Api Hinweise entfernen
+// remove_action('wp_head', 'rest_output_link_wp_head');
+// remove_action('wp_head', 'wp_oembed_add_discovery_links');
+// remove_action('template_redirect', 'rest_output_link_header', 11, 0);
+
+// function remove_json_api ()
+// {
+//    // REST API Zeilen aus dem HTML Header entfernen
+//    remove_action('wp_head', 'rest_output_link_wp_head', 10);
+//    remove_action('wp_head', 'wp_oembed_add_discovery_links', 10);
+//    // REST API endpoint entfernen
+//    remove_action('rest_api_init', 'wp_oembed_register_route');
+//    // oEmbed auto discovery entfernen
+//    add_filter('embed_oembed_discover', '__return_false');
+//    // oEmbed results nicht filtern
+//    remove_filter('oembed_dataparse', 'wp_filter_oembed_result', 10);
+//    // oEmbed discovery links entfernen
+//    remove_action('wp_head', 'wp_oembed_add_discovery_links');
+//    // oEmbed-JavaScript entfernen
+//    remove_action('wp_head', 'wp_oembed_add_host_js');
+//    // rewrite rules zum Einbetten entfernen
+//    add_filter('rewrite_rules_array', 'disable_embeds_rewrites');
+// }
+// add_action('after_setup_theme', 'remove_json_api');

+ 35 - 0
header.php

@@ -0,0 +1,35 @@
+<?php
+/**
+ * The header.
+ *
+ * This is the template that displays all of the <head> section and everything up until main.
+ *
+ * @link https://developer.wordpress.org/themes/basics/template-files/#template-partials
+ *
+ * @package WordPress
+ * @subpackage Twenty_Twenty_One
+ * @since Twenty Twenty-One 1.0
+ */
+
+?>
+<!doctype html>
+<html <?php language_attributes(); ?> <?php twentytwentyone_the_html_classes(); ?>>
+<head>
+	<meta charset="<?php bloginfo( 'charset' ); ?>" />
+	<meta name="viewport" content="width=device-width, initial-scale=1" />
+	<?php wp_head(); ?>
+	<?php echo basic_wp_seo(); ?>
+</head>
+
+<body <?php body_class(); ?>>
+<div style="z-index:9999" class="cr cr-top cr-right cr-sticky cr-black">#StandWithUkraine</div>
+<!-- <div style="z-index:9999" class="cl cl-top cl-right cl-sticky cl-white">Support Israel</div> -->
+<?php wp_body_open(); ?>
+<div id="page" class="site">
+	<a class="skip-link screen-reader-text" href="#content"><?php esc_html_e( 'Skip to content', 'twentytwentyone' ); ?></a>
+
+	<?php get_template_part( 'template-parts/header/site-header' ); ?>
+
+	<div id="content" class="site-content">
+		<div id="primary" class="content-area">
+			<main id="main" class="site-main">

+ 32 - 0
index-common-places.php

@@ -0,0 +1,32 @@
+<?php
+/**
+Template Name: Common places template 
+ */
+
+global $featured_post_id;
+miech_set_active_cat( get_theme_mod( 'featured_category_2', 1140 ) );
+echo '<!-- featured_category_1 => '.get_theme_mod( 'featured_category_1', 1140 )." -->\n";
+
+get_header();
+
+if ( have_posts() ) {
+
+	// Load posts loop.
+	while ( have_posts() ) {
+		the_post();
+
+		get_template_part( 'template-parts/content/content', get_theme_mod( 'display_excerpt_or_full_post', 'excerpt' ) );
+	}
+
+	// Previous/next page navigation.
+	twenty_twenty_one_the_posts_navigation();
+
+} else {
+
+	// If no content, include the "No posts found" template.
+	get_template_part( 'template-parts/content/content-none' );
+
+}
+
+get_footer();
+?>

+ 32 - 0
index-vernacular.php

@@ -0,0 +1,32 @@
+<?php
+/**
+Template Name: Vernacular template 
+ */
+
+global $featured_post_id;
+miech_set_active_cat( get_theme_mod( 'featured_category_1', 1964) );
+echo '<!-- featured_category_1 => '.get_theme_mod( 'featured_category_1', 1964 )." -->\n";
+
+get_header();
+
+if ( have_posts() ) {
+
+	// Load posts loop.
+	while ( have_posts() ) {
+		the_post();
+
+		get_template_part( 'template-parts/content/content', get_theme_mod( 'display_excerpt_or_full_post', 'excerpt' ) );
+	}
+
+	// Previous/next page navigation.
+	twenty_twenty_one_the_posts_navigation();
+
+} else {
+
+	// If no content, include the "No posts found" template.
+	get_template_part( 'template-parts/content/content-none' );
+
+}
+
+get_footer();
+?>

+ 48 - 0
index.php

@@ -0,0 +1,48 @@
+<?php
+/**
+Template Name: Original twentytwentyone template 
+ */
+/**
+ * The main template file
+ *
+ * This is the most generic template file in a WordPress theme
+ * and one of the two required files for a theme (the other being style.css).
+ * It is used to display a page when nothing more specific matches a query.
+ * E.g., it puts together the home page when no home.php file exists.
+ *
+ * @link https://developer.wordpress.org/themes/basics/template-hierarchy/
+ *
+ * @package WordPress
+ * @subpackage Twenty_Twenty_One
+ * @since Twenty Twenty-One 1.0
+ */
+
+get_header(); ?>
+
+<?php if ( is_home() && ! is_front_page() && ! empty( single_post_title( '', false ) ) ) : ?>
+	<header class="page-header alignwide">
+		<h1 class="page-title"><?php single_post_title(); ?></h1>
+	</header><!-- .page-header -->
+<?php endif; ?>
+
+<?php
+if ( have_posts() ) {
+
+	// Load posts loop.
+	while ( have_posts() ) {
+		the_post();
+
+		get_template_part( 'template-parts/content/content', get_theme_mod( 'display_excerpt_or_full_post', 'excerpt' ) );
+	}
+
+	// Previous/next page navigation.
+	twenty_twenty_one_the_posts_navigation();
+
+} else {
+
+	// If no content, include the "No posts found" template.
+	get_template_part( 'template-parts/content/content-none' );
+
+}
+
+get_footer();

+ 191 - 0
linkpage2.php

@@ -0,0 +1,191 @@
+<?php
+/*
+Template Name: NEW Blogroll TEST
+ */
+
+/*
+   * get html from linkpage blog
+   * for each blog save url, title, last post url, last post title, timestamp as transient, key is ????
+   * for leicaphilia and oren grad, get last post title and url with special function
+ */
+
+$pdo = new PDO(
+    'sqlite::memory:',
+    null,
+    null,
+    array(PDO::ATTR_PERSISTENT => false)
+); 
+
+function scratch99_fromthisblog() {
+    $ref = $_SERVER['HTTP_REFERER'];
+    $host = $_SERVER['HTTP_HOST'];
+    /* echo "<p style='color:green!important;'>Referer: $ref <br>Host: $host</p>"; */
+    if( $ref == "" ) return true;
+    if( strpos($host, $ref) !== false ) return false;
+    return false;
+} 
+
+function scratch99_last_post_thumbnail_link () {
+    $recent_posts = wp_get_recent_posts(array(
+        'numberposts' => 10, // Number of recent posts thumbnails to display
+        'post_status' => 'publish' // Show only the published posts
+    ));
+    foreach( $recent_posts as $recent ) {
+        if ( has_post_thumbnail($recent['ID']) ) { // check if the post has a Post Thumbnail assigned to it.
+            echo "<div style='text-align: right;'><a href='" . get_permalink($recent['ID']) . "'>";
+            echo "<span style='padding-right: 1em; font-weight: bold;'>New on spring2life</span> ";
+            echo get_the_post_thumbnail($recent['ID'],'thumbnail', 'style=float:right;') . "</a></div>";
+            break;
+        }
+    }
+}
+
+function blogs_i_read() {
+    $url = "http://spring2life-links.blogspot.de";
+    //$html = file_get_contents('/tmp/spring2life-links.html');
+    $html = curlDownload($url);
+    set_transient( $url, $html, 1800 );
+    if ( false === ( $html = get_transient( $url ) ) ) {
+        $html = curlDownload($url);
+        if ( ! $html )
+            echo "<h2>There is a problem with the http request!</h2>";
+        else
+            set_transient( $url, $html, 1800 );
+    }
+    if ( ! preg_match('/(<ul id=\'BlogList1_blogs.*?<\/ul>)/is', $html, $matches)) {
+        echo $html;
+        echo "Error: could not retrieve spring2life-links blogroll";
+        return;
+    }
+    $html = preg_replace('/.*<div class=["\']widget BlogList["\'] id=["\']BlogList1["\']>/ism', '', $html);
+    $newest_only = "";
+    $stundenflag = false;
+    $tagflag = false;
+    $wochenflag = false;
+    $monatflag = false;
+    $pleistoflag = false;
+    preg_match_all('/<div class=["\']blog-title["\']>.*<div class=["\']item-time["\']>.*<\\/div>/Us', $html, $matches);
+    foreach ($matches[0] as $chunk) {
+        /* if ( preg_match("/orengrad.com/ism", $chunk) ) {
+           $result = curlDownload('http://orengrad.com/thingsseen/index.html');
+           $result = preg_replace('/</ism', '&lt;', $result);
+           $result = preg_replace('/>/ism', '&gt;', $result);
+           echo "<br><tt>Orengrad: $chunk</tt><br><pre>$result</pre><br>";
+           } */
+        if ( preg_match("/vor\s+\d+\s+(Minute|Stunde)/ism", $chunk) )
+            if (! $stundenflag) {
+                $chunk = "<li class='linkhead'>Hot from the Sphere</li>\n\n" . $chunk; $stundenflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+(Tag)/ism", $chunk) )
+            if (! $tagflag) {
+                $chunk = "<li class='linkhead'>A day and older</li>\n\n" . $chunk; $tagflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+Woche/ism", $chunk) )
+            if (! $wochenflag) {
+                $chunk = "<li class='linkhead'>Less than a month old</li>\n\n" . $chunk; $wochenflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+(Monat)/ism", $chunk) )
+            if (! $monatflag) {
+                $chunk = "<li class='linkhead'>Older</li>\n\n" . $chunk; $monatflag = true;
+            }
+        if ( preg_match("/vor\s+\d+\s+(Jahr)/ism", $chunk) )
+            if (! $pleistoflag) {
+                $chunk = "<li class='linkhead'>From the Pleistozaen</li>\n\n" . $chunk; $pleistoflag = true;
+            }
+        /* if (! preg_match("/<li>/ism", $chunk) )
+           $chunk = "<li>" . $chunk; */
+        $chunk = preg_replace("/[\s]*<div class=[\"']item-time[\"']>.*<\/div>/ism", "", $chunk);
+        $chunk = preg_replace("/<div class=[\"']item-content[\"']>[\r\n]?/ism", "", $chunk);
+        $chunk = preg_replace("/<div class=[\"']blog-title[\"']>[\r\n]?/ism", "<li>", $chunk);
+        $chunk = preg_replace("/<\/div>[\r\n]?/ism", ":&nbsp;", $chunk);
+        $chunk = preg_replace("/<\/span>/ism", "</span></li>", $chunk);
+        $newest_only .= $chunk;
+        if ( preg_match('/href=\'(http:\/\/feedproxy.google.com.*?)\'/', $chunk, $match) ) {
+            $proxyurl = $match[1];
+            if ( false === ( $cleanurl = get_transient( md5('cleanurlof' . $proxyurl) ) ) ) {
+                $cleanurl = resolveUrl($proxyurl);
+                $cleanurl = doHardcore($cleanurl);
+                set_transient( md5("cleanurlof" . $proxyurl), $cleanurl, 90000 + rand(1,3600) );
+            } $chunk = str_replace($match[1], $cleanurl, $chunk);
+            /*             print_r($newest_only); die; */
+        }
+        /* $chunk = preg_replace( '/<\/li>[\s\r\n]*<\/ul>/ism', '', $chunk ); */
+        /* $newest_only .= $chunk . "</div></li>\n"; */
+    }
+    return $newest_only;
+}
+
+function resolveUrl($url) {
+    try {
+        $header = doCurlRequest($url); return $header['redirect_url']; } catch (Exception $ex) {
+            _log("error freeing url $url: " . $ex->getMessage()); return $url;
+        }
+}
+
+function curlDownload($Url){
+    $ch = curl_init();
+    curl_setopt($ch, CURLOPT_URL, $Url);
+    curl_setopt($ch, CURLOPT_REFERER, "http://markus-spring.info");
+    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0");
+    curl_setopt($ch, CURLOPT_HEADER, 0);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+    curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
+    $output = curl_exec($ch);
+    curl_close($ch);
+    return $output;
+}
+
+if(!function_exists('_log')) {
+    function _log( $message ) {
+        if( WP_DEBUG === true ) {
+            if( is_array( $message ) || is_object( $message ) ) {
+                error_log( print_r( $message, true ) );
+            } else {
+                error_log( $message );
+            }
+        }
+    }
+}
+
+function doCurlRequest($url) {
+    $curlSession = curl_init($url);
+    curl_setopt($curlSession, CURLOPT_NOBODY, 1);
+    $curlResponse = curl_exec($curlSession);
+    $header = curl_getinfo($curlSession);
+    curl_close($curlSession);
+    return $header;
+}
+
+function doHardcore($url) {
+    try {
+        $parts = explode("?", $url);
+        $ret = $parts[0];
+        _log("do hardcore: [$url] -> [$ret]");
+        return $ret;
+    } catch (Exception $ex) {
+        _log("error in hardcore: " . $ex->getMessage());
+        return $url;
+    }
+}
+
+?>
+<?php get_header(); ?>
+<div id="content">
+  <div id="inner-content" class="wrap group">
+    <?php get_sidebar(); ?>
+    <div id="main" class="col-4-5 group" role="main">
+      <ul class="blogroll">
+        <?php
+        if (scratch99_fromthisblog()) {
+            /* echo "<p style='color:ping!important;'>Referer: $ref POSITIV</p>"; */
+            scratch99_last_post_thumbnail_link();
+        }
+        ?>
+        <?php echo blogs_i_read(); ?>
+      </ul>
+    </div> <!-- #main -->
+  </div> <!-- #inner-content -->  
+</div> <!-- #content -->  
+<?php get_footer(); ?>

+ 40 - 0
linkpage4.php

@@ -0,0 +1,40 @@
+<?php
+/*
+Template Name: NEW Blogroll 4
+ */
+?>
+<?php
+$text= file_get_contents('/var/www/html/wp-content/themes/twentytwentyone-child-spring2life/cronlinks2.html');
+?>
+<?php get_header(); ?>
+<div id="content" class="site-content">
+  <div id="primary" class="content-area">
+    <main id="main" class="site-main" role="main">
+      <article id="post--31201" class="post--31201 post type-post status-publish format-image hentry category-vernacular post_format-post-format-image entry">
+        <header class="entry-header">
+	  <h2 class="entry-title default-max-width">Blogs I read</h2>
+	</header><!-- .entry-header -->
+        
+        <div id="content" class="site-content">
+          <div id="primary" class="content-area">
+            <main id="main" class="site-main" role="main">
+	
+	      <div class="entry-content">
+                <ul class="linktable">
+                  <?php echo $text; ?>
+                </ul>
+              </div><!-- .entry-content -->
+            </main>
+          </div>
+        </div>
+      </article><!-- #post-31164 -->
+    </main><!-- #main -->
+  </div><!-- #primary -->
+</div><!-- #content -->
+<?php get_footer(); ?>
+
+<?php
+// Local variables:
+// compile-command: "php linkpage4.php"
+// End:
+?>

+ 392 - 0
linkpage5.php

@@ -0,0 +1,392 @@
+<?php
+/*
+Template Name: Blogroll 5 High Performance
+ */
+?>
+<?php
+
+$GLOBALS['blogs_i_read_min_time']     = 900;
+$GLOBALS['external_service_min_time'] = 1800; 
+$GLOBALS['external_service_pre_aged'] = 600; 
+
+// retrieve_list();
+
+function resolveUrl($url) {
+    try {
+        $header = doCurlRequest($url); return $header['redirect_url']; } catch (Exception $ex) {
+            _log("error freeing url $url: " . $ex->getMessage()); return $url;
+        }
+}
+
+function curlDownload($Url){
+    $ch = curl_init();
+    curl_setopt($ch, CURLOPT_URL, $Url);
+    curl_setopt($ch, CURLOPT_REFERER, "https://markus-spring.info");
+    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:31.0) Gecko/20100101 Firefox/31.0");
+    curl_setopt($ch, CURLOPT_HEADER, 0);
+    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
+    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
+    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
+    curl_setopt($ch, CURLOPT_MAXREDIRS, 10);
+    $output = curl_exec($ch);
+    curl_close($ch);
+    return $output;
+}
+
+function reduce_lines( $html ) {
+    $lines = explode("\n", $html);
+    $found = 0;
+    $bloglist = '';
+    for ($i = 0; $i < count($lines); $i++) {
+        if ($lines[$i] ==  "<ul id='BlogList1_blogs'>")
+            $found = 1;
+        if ($found == 1 and $lines[$i] == "</ul>")
+            break;
+        if ($found == 1) 
+            $bloglist .= $lines[$i] . "\n";
+    }
+    return($bloglist); 
+}
+
+function make_timestamp($chunk) {   // 
+    preg_match('/vor\s(\d+)\s(\D+)/m', $chunk, $m);
+    $t = time() - 20*365*24*3600;
+    if ($m) {
+        // echo $m[1] . " " . $m[2] . " ";
+        if (strpos($m[2], 'Minute') === 0) 
+            $t =  time() - $m[1] * 60;
+        if (strpos($m[2], 'Stunde') === 0) 
+            $t =  time() - $m[1] * 3600;
+        elseif (strpos($m[2], 'Tag') === 0) 
+            $t =  time() - $m[1] * 24 * 3600;
+        elseif (strpos($m[2], 'Woche') === 0) 
+            $t =  time() - $m[1] * 7 * 24 * 3600;
+        elseif (strpos($m[2], 'Monat') === 0) 
+            $t =  time() - $m[1] * 30 * 24 * 3600;
+        elseif (strpos($m[2], 'Jahr') === 0) 
+            $t =  time() - $m[1] * 365 * 24 * 3600;
+        return $t;
+    } else
+    return 0;
+}
+
+function rework_entry ($match, $list, $offset, $housekeeping) {
+    $url = $match[1];
+    $domain = preg_replace('/(https?:\/\/|\/<?.*?$)/m', "", $match[1]);
+    $protocol = preg_replace('/:\/\/.*/', '://', $match[1]); 
+    $title = $match[2];
+    $lasturl = '';
+    $lasttitle = '';
+    # match: [0] url [1] blog title [2] post title [3] post url [4] time indicator
+    # echo "<pre style='font-size: 10px; font-weight: normal'>$domain: " . $match[3] . "</pre>\n";
+    if (preg_match('`href=\'(.*?)\'.*?>\s*(.*?)\s*</a>`m', $match[3], $m)) {
+        #echo "<pre style='font-size: 10px; font-weight: normal'>" . $match[3] . "</pre>\n";
+        $lasturl  = $m[1];
+        $lasttitle  = $m[2];
+        /* echo "Last post 1:" . $lasturl . "\n"; */
+        $timestamp  = make_timestamp($match[4]) + $offset;
+    } else {
+        if ( strpos($domain, 'lfi-online.de') === 0 ) 
+            list($timestamp, $lasturl, $lasttitle) = update_lfi($url, $list);
+        if ( strpos($domain, 'jims-ramblings.blogspot.com') === 0 ) 
+            list($timestamp, $lasturl, $lasttitle) = update_jims_ramblings($url, $list);
+        if ( strpos($domain, 'www.orengrad.com') === 0) 
+            list($timestamp, $lasturl, $lasttitle) = update_oren_grad($url, $domain, $list);
+        else {
+            // echo "unmatched domain $domain\n";
+            $id = array_search($domain, array_column($list, 'domain'));
+            $timestamp = $list[$id]['timestamp'];
+            // $timestamp  = make_timestamp($match[4]) + $offset;
+        }
+    }
+    return ['domain' => $domain, 'url' => $url, 'title' => $title, 'lasturl' => $lasturl,
+            'lasttitle' => $lasttitle, 'timestamp' => $timestamp, 'housekeeping' => $housekeeping];
+}
+
+function debug_echo ( $flag, $args ) {
+    if ($flag == 1)
+        echo "<div>" . $args . "</div>\n";
+}
+
+function update_oren_grad($url, $domain, $list) {
+    $debug = 0;
+    // foreach($list as $l)
+    //     debug_echo($l['domain']);
+    // echo '<pre>'; echo print_r($list); echo '</pre>';
+    $id = array_search($url, array_column($list, 'url'));
+    // $id = array_search($domain, array_column($list, 'domain'));
+    $lasttitle = '';
+    if ( $id === false ) { // not found in list
+        debug_echo($debug, "OG: $domain not found in list");
+        preg_match('/bodycontent[\'"]>\s*<p><img src=[\'"](pictures\/.*)[\'"] alt=[\'"]/ms', curlDownload($url), $m);
+        $timestamp = time() - $GLOBALS['external_service_pre_aged'];
+        $lasturl   = $url . '/' . $m[1];
+    } else { // found
+        debug_echo($debug, "OG: $domain found in list");
+        $timestamp = $list[$id]['timestamp'];
+        $lasturl   = $list[$id]['lasturl'];
+    }
+    debug_echo($debug, "OG: lasturl age " . (time() - $timestamp ) . "s");
+    if ( (time() - $timestamp ) > $GLOBALS['external_service_min_time'] ) {
+        debug_echo($debug, "OG: $domain found in list but outdated");
+        preg_match('/bodycontent[\'"]>\s*<p><img src=[\'"](pictures\/.*)[\'"] alt=[\'"]/ms', curlDownload($url), $m);
+        $lasturl   = $url . '/' . $m[1];
+        if ( $lasturl == $list[$id]['lasturl'] ) {
+            debug_echo( $debug, "OG: lasturl unchanged, timestamp unchanged: " . (time() - $timestamp) . "s");
+            $timestamp = $list[$id]['timestamp'];
+        } else {
+            debug_echo($debug, "OG: lasturl CHANGED, timestamp unchanged: " . (time() - $timestamp) . "s");
+            $timestamp = time() - $GLOBALS['external_service_pre_aged'];
+        }
+    }
+    debug_echo( $debug, "OG: $domain final timestamp: " . (time() - $timestamp) . "s");
+    return [$timestamp, $lasturl, $lasttitle];
+}
+
+function update_jims_ramblings($url, $list) {
+    $id = array_search($url, array_column($list, 'url'));
+    if ( $id === false ) { // not found in list
+        // echo "$url not found in list\n";
+        preg_match('/<h3 class=\'post-title entry-title\'>\s*?<a href=\'(.*?)\'>(.*?)<\/a/', curlDownload($url), $m);
+        $timestamp = time() - $GLOBALS['external_service_pre_aged'];
+        $lasturl   = $m[1];
+        $lasttitle = $m[2];
+    } else { // found
+        // echo "$url found in list\n";
+        $timestamp = $list[$id]['timestamp'];
+        $lasturl   = $list[$id]['lasturl'];
+        $lasttitle = $list[$id]['lasttitle'];
+    }
+    // echo "lasturl age " . (time() - $timestamp - 600 ) . "s\n";
+    if ( (time() - $timestamp ) > $GLOBALS['external_service_min_time'] + 600 ) {
+        // echo "$url found in list but outdated\n";
+        preg_match('/<h3 class=\'post-title entry-title\'>\s*?<a href=\'(.*?)\'>(.*?)<\/a/', curlDownload($url), $m);
+        $timestamp = time() - $GLOBALS['external_service_pre_aged'];
+        $lasturl   = $m[1];
+        $lasttitle = $m[2];
+        if ( $lasttitle == $list[$id]['lasttitle'] )
+            $timestamp = $list[$id]['timestamp'];
+    }
+    return [$timestamp, $lasturl, $lasttitle];
+}
+
+function update_lfi($url, $list) {
+    $id = array_search($url, array_column($list, 'url'));
+    if ( $id === false ) { // not found in list
+        // echo "$url not found in list\n";
+        preg_match('/location = \'(.*?)\'">\s*?<h1 class="typo-\d+">(.*?)</msi', curlDownload($url), $m);
+        $timestamp = time() - $GLOBALS['external_service_pre_aged'];
+    } else { // found
+        // echo "$url found in list\n";
+        $timestamp = $list[$id]['timestamp'];
+        $lasturl   = $list[$id]['lasturl'];
+        $lasttitle = $list[$id]['lasttitle'];
+    }
+    // echo "lasturl age " . (time() - $timestamp - 600 ) . "s\n";
+    if ( (time() - $timestamp ) > $GLOBALS['external_service_min_time'] + 600 ) {
+        // echo "$url found in list but outdated\n";
+        preg_match('/location = \'(.*?)\'">\s*?<h1 class="typo-\d+">(.*?)</msi', curlDownload($url), $m);
+        $timestamp = time() - $GLOBALS['external_service_pre_aged'];
+        $lasturl   = $m[1];
+        $lasttitle = $m[2];
+        if ( $lasttitle == $list[$id]['lasttitle'] )
+            $timestamp = $list[$id]['timestamp'];
+    }
+    return [$timestamp, $lasturl, $lasttitle];
+}
+
+function create_linklist ($list, $housekeeping) {
+    // echo '<pre>' . $housekeeping . '<pre>';
+    $debug = 0;
+    $hurl = "http://spring2life-links.blogspot.de";
+    debug_echo($debug, $hurl);
+    $html = curlDownload($hurl);
+    $bloglines = reduce_lines($html);
+    // debug_echo($debug, $bloglines);
+    # matches: 1: url 2: blog title 3. post title 4. time indicator
+    $re = '/<div class=\'blog-title\'>\s*<a href=\'(.*?)\'.*?>\s*(.*?)<\/a>.*?\'item-title\'>\s*(.*?)\s*<\/span.*?\'item-time\'>\s*(.*?)\s*<\/div>/ms';
+    preg_match_all($re, $bloglines, $matches, PREG_SET_ORDER, 0);
+    $offset = 0;
+    for ($i = 0; $i < count($matches); $i++) {
+        $result = rework_entry($matches[$i], $list, $offset, $housekeeping);
+        // print_r($result['domain'] . "\n");
+        $id = array_search( $result['domain'], array_column( $list, 'domain' ));
+        // debug_echo($debug, $result['domain']);
+        if ( is_int($id) ) {
+            $list[$id]['lasturl'] = $result['lasturl'];
+            $list[$id]['lasttitle'] = $result['lasttitle'];
+            $list[$id]['timestamp'] = $result['timestamp'];
+            $list[$id]['housekeeping'] = $housekeeping;
+        } else {
+            array_push($list, $result);
+        }
+        $offset += 1;
+    }
+    $hk = $housekeeping - 2;
+    $op = array_search('www.ruedulavoir.com', array_column($list, 'domain'));
+    echo "<pre>$op</pre>";
+    unset($list[$op]);
+    // while ( $hk < $housekeeping ) {
+    //     debug_echo($debug, $hk);
+    //     while ( is_int($to_delete = array_search($hk, array_column($list, 'housekeeping' ))) ) {
+    //         echo '<pre style="color:green;">' . $hk . ' ';
+    //         echo print_r( $list[$to_delete] );
+    //         echo '</pre>';
+    //         unset($list[$to_delete]);
+    //     }
+    //     // while ( $to_delete = array_search($hk, array_column($list, 'housekeeping' )) !== NULL) {
+    //     //     debug_echo(1, $to_delete);
+    //         // unset($list[$to_delete]);
+    //     // }
+    //     $hk = $hk + 1;
+    // }
+    return $list;
+}
+
+function retrieve_list() {
+    $debug = 0;
+    $time1 = (float) microtime(true);
+    // echo "getting content from stored list " . (time() - filemtime('/tmp/file.ser')) . "s\n";
+    // $str = file_get_contents('/tmp/file.ser');
+    // $str = get_transient( $hurl + "_hp" );
+    // if ( $str === false ) { // not found
+    //     $list = create_linklist([]);
+    // } else {                    // found
+    //     // $list = unserialize( $str );
+    //     $list = create_linklist($str);
+    // }
+    $queried_object = get_queried_object();
+    if ( $queried_object ) {
+        $post_id = $queried_object->ID;
+    }
+    // $post_id = 23342;           // for testing, fixed to the blogs-i-read page id
+    debug_echo($debug, $post_id);
+    $cache_key = '_blogs_i_read';
+    $cache = get_post_meta( $post_id, $cache_key, true );
+    $housekeeping = -1;
+    // $cache = [];
+    if ( empty( $cache ) || $cache['expires'] < time() ) {
+        debug_echo($debug, 'empty or expired');
+        if (empty($cache)) {
+            $list = [];
+            $housekeeping = 0;
+        } else {
+            debug_echo($debug, 'expired');
+            $housekeeping = $cache['housekeeping'] + 1;
+            debug_echo($debug, 'housekeeping:' . $housekeeping);
+            $list = $cache['data'];
+        }
+        $list = create_linklist($list, $housekeeping);
+        debug_echo($debug, 'after creating linklist');
+        $cache = array( 
+            'expires' => time() + $GLOBALS['blogs_i_read_min_time'],
+            'data' => $list,
+            'housekeeping' => $housekeeping );
+        update_post_meta( $post_id, $cache_key, $cache );
+        debug_echo($debug, 'after updating post meta');
+    } else {
+        debug_echo($debug, 'neither empty nor expired');
+        $housekeeping = $cache['housekeeping'];
+        create_linklist($cache['data'], $housekeeping);
+    }
+    debug_echo($debug, 'before printing');
+    return(print_list( $cache['data'], $time1 ));
+}
+
+function print_list ( $list, $time1 ) {
+    $list2 = array_msort($list, array('timestamp' => SORT_DESC));
+    $s = '';
+    $dayflag = $weekflag = $monthflag = $yearflag = false;
+    foreach ($list2 as $l) {
+        if ( ! $dayflag and ((time() - $l['timestamp']) > 24*3600) ) {
+            $s .= "<!-- " . (time() - $l['timestamp']) . " // " . 24*3600 . " -->\n";
+            $s .= "</ul>\n<li style='font-weight: bold;'>A day and older</li>\n<ul>\n";
+            $dayflag = true;
+        } elseif ( ! $weekflag and ((time() - $l['timestamp']) > 7*24*3600) ) {
+            $s .= "</ul>\n<li style='font-weight: bold;'>Less than a month</li>\n<ul>\n";
+            $weekflag = true;
+        } elseif ( ! $monthflag and ((time() - $l['timestamp']) > 30*24*3600) ) {
+            $s .= "</ul>\n<li style='font-weight: bold;'>Older</li>\n<ul>\n";
+            $monthflag = true;
+        } elseif ( ! $yearflag and ((time() - $l['timestamp']) > 365*24*3600) ) {
+            $s .= "</ul>\n<li style='font-weight: bold;'>From medieval times</li>\n<ul>\n";
+            $yearflag = true;
+        } 
+        $s .= '<li>';
+        // $s .= '<span style="color:green">' . (time() - $l['timestamp']) . '</span>; ';
+        // $s .= '<span style="color:blue">' . $l['housekeeping'] . '</span>; ';
+        $s .= '<a target="_blank" href="' . $l['url'] . '">' . $l['title'] . '</a> // <a target="_blank" href="'
+           . $l['lasturl'] . '">' . $l['lasttitle'] . "</a></li>\n";
+    }
+    $timespent = microtime(true) - $time1;
+    return $s . "<!-- Duration $timespent sec -->\n";
+}
+
+// function store_list($list) {
+//     // anpassen für wordpress, zum testen schreiben in Datei
+//     // $ser = serialize($list);
+//     // $file = fopen('/tmp/file.ser', 'wb');
+    
+//     // fwrite($file, $ser); 
+//     set_transient( $hurl + "_hp", $list, 600 );
+// }
+
+function array_msort($array, $cols) {
+    $colarr = array();
+    foreach ($cols as $col => $order) {
+        $colarr[$col] = array();
+        foreach ($array as $k => $row) { $colarr[$col]['_'.$k] = strtolower($row[$col]); }
+    }
+    $eval = 'array_multisort(';
+    foreach ($cols as $col => $order) {
+        $eval .= '$colarr[\''.$col.'\'],'.$order.',';
+    }
+    $eval = substr($eval,0,-1).');';
+    eval($eval);
+    $ret = array();
+    foreach ($colarr as $col => $arr) {
+        foreach ($arr as $k => $v) {
+            $k = substr($k,1);
+            if (!isset($ret[$k])) $ret[$k] = $array[$k];
+            $ret[$k][$col] = $array[$k][$col];
+        }
+    }
+    return $ret;
+}
+
+?>
+<?php get_header(); ?>
+<div id="content" class="site-content">
+  <div id="primary" class="content-area">
+    <main id="main" class="site-main" role="main">
+      <article id="post--31201" class="post--31201 post type-post status-publish format-image hentry category-vernacular post_format-post-format-image entry">
+        <header class="entry-header">
+	  <h2 class="entry-title default-max-width">Blogs I read</h2>
+	</header><!-- .entry-header -->
+        
+        <div id="content" class="site-content">
+          <div id="primary" class="content-area">
+            <main id="main" class="site-main" role="main">
+	
+	      <div class="entry-content">
+                <ul class="linktable">
+                  <li style="font-weight: bold;">Hot from the Sphere</li>
+                  <ul>
+                  <?php echo retrieve_list (); ?>
+                  </ul>
+                </ul>
+              </div><!-- .entry-content -->
+            </main>
+          </div>
+        </div>
+      </article><!-- #post-31164 -->
+    </main><!-- #main -->
+  </div><!-- #primary -->
+</div><!-- #content -->
+<?php get_footer(); ?>
+
+<?php
+// Local variables:
+// compile-command: "php linkpage5.php"
+// End:
+?>

+ 42 - 0
linkpage6.php

@@ -0,0 +1,42 @@
+<?php
+/*
+Template Name: Blogroll 6 Python-to-the-rescue
+ */
+?>
+
+<?php
+$text= file_get_contents('/var/www/html/wp-content/themes/twentytwentyone-child-spring2life/cronlinks.html');
+
+?>
+<?php get_header(); ?>
+<div id="content" class="site-content">
+  <div id="primary" class="content-area">
+    <main id="main" class="site-main" role="main">
+      <article id="post--31201" class="post--31201 post type-post status-publish format-image hentry category-vernacular post_format-post-format-image entry">
+        <header class="entry-header">
+	  <h2 class="entry-title default-max-width">Blogs I read</h2>
+	</header><!-- .entry-header -->
+        
+        <div id="content" class="site-content">
+          <div id="primary" class="content-area">
+            <main id="main" class="site-main" role="main">
+	
+	      <div class="entry-content">
+                <ul class="linktable">
+                  <?php echo $text; ?>
+                </ul>
+              </div><!-- .entry-content -->
+            </main>
+          </div>
+        </div>
+      </article><!-- #post-31164 -->
+    </main><!-- #main -->
+  </div><!-- #primary -->
+</div><!-- #content -->
+<?php get_footer(); ?>
+
+<?php
+// Local variables:
+// compile-command: "php linkpage5.php"
+// End:
+?>

+ 288 - 0
postie-helper.php

@@ -0,0 +1,288 @@
+<?php
+/*	$Id: postie-helper.php,v 1.2 2018/04/17 11:43:22 springm Exp springm $	*/
+
+/*	$Log: postie-helper.php,v $
+ *	Revision 1.2  2018/04/17 11:43:22  springm
+ *	Summary: Funktioniert
+ *	*/
+
+
+/* ------------------- postie helper function for leftover categories --- */
+/* postie removes categories given in the mail subject if it finds them in the
+*  wordpress categories.
+*  all other categories will be made tags of the created post
+
+for this to work, postie-settings->message->remove matched categories has to be set to no
+
+*/
+
+add_filter('postie_post_before', 'mws_auto_tag');
+
+function mws_auto_tag($post) {
+    DebugEcho('============================== mws_auto_tag ' . print_r($post, true));
+    // DebugEcho('    test for "common places" category');
+    // if (in_category( 'Common Places', $post )) {
+    //     DebugEcho('    post has "common places" category');
+    // }
+    $post = evaluate_image_exif($post, $post['post_category']);
+    $post['post_name'] = $post['post_title'];
+    DebugEcho('========================== end mws_auto_tag');
+    DebugEcho("========================== post_content before massage\n" . $post['post_content']);
+    $post['post_content'] = preg_replace('!<div class="postie-attachments">!','', $post['post_content']);
+    $post['post_content'] = preg_replace('!</div>!','', $post['post_content']);
+    $post['post_content'] = preg_replace('!<p></p>!','', $post['post_content']);
+    $post['post_content'] = preg_replace('!<br />!','', $post['post_content']);
+    $post['post_content'] = preg_replace('!\n!','', $post['post_content']);
+    $post['post_content'] = preg_replace('!&lt;!','<', $post['post_content']);
+    $post['post_content'] = preg_replace('!&gt;!','>', $post['post_content']);
+    DebugEcho("========================== post_content after massage\n" . $post['post_content']); 
+    $post = make_landscape_photos_large($post);
+    return $post;
+}
+
+/* extract information from the exif metadata of the first image in the post.
+*  if applicable create the title, categories and location information from this */ 
+function evaluate_image_exif( $post, $categories ) {
+    DebugEcho('MWS =====> begin  evaluate_image_exif');
+    $common_places_found = 0;
+    DebugEcho('    test for "common places" category');
+    if (in_category( 'common places', $post )) {
+        DebugEcho('    post has "common places" category');
+        $common_places_found = 1;
+    }
+    $iimgs = get_attached_media('image', $post['ID']);
+    $upload_dir = wp_upload_dir();
+    foreach ( $iimgs as $iimg ) {
+        $imagefile = $upload_dir['basedir'] . '/' .
+                     wp_get_attachment_metadata( get_post_thumbnail_id( $post['ID'] ) )['file'];
+        break;
+    }
+    $meta = miech_wp_read_image_metadata( get_post_meta($post['ID']), $imagefile, $sourceImageType );
+    if ( ! empty( $meta['title'] ) )
+        $post['post_title'] = $meta['title'];
+    DebugEcho('~~~~~~~~~~ ' . $post['post_title'] );
+    preg_match_all('/\[(.*?)\]/', $post['post_title'], $leftovercats);
+    print_r($leftovercats[1]); 
+    foreach ( array_merge( array( $meta['country'], $meta['state'], $meta['city'] ),
+                           explode(',', $meta['keywords']), $leftovercats[1] ) as $k) {
+        /* DebugEcho('     category/tag: ' . $k); */
+        $in_blacklist = 0;
+        foreach ( array('wp', 'blog', 'status', 'genre', 'published', 'printed', 'lens', 'treatment' ) as $b ) {
+            if ( strcasecmp( "$k", "$b" ) == 0 ) {
+                $in_blacklist = 1;
+            }
+        }
+        /* if ( $in_blacklist < 1 ) { */
+        if ( $in_blacklist < 1 and strlen($k) > 0) {
+            DebugEcho("     Examining '$k' " );
+            if ( strcasecmp('common places', "$k") == 0) {
+                DebugEcho("     '$k' GEFUNDEN!" );
+                $common_places_found = 1;
+            }
+            $cat = get_term_by('name', (string) "$k", 'category');
+            if ( isset($cat) ) {
+                if ( $cat->term_id > 1 ) {
+                    DebugEcho("     Category '$k' exists with id " . $cat->term_id );
+                    array_push( $categories, $cat->term_id );
+                } else {
+                    DebugEcho("     Category '$k' does not exist ==> '$k' becomes tag" );
+                    array_push($post['tags_input'], "$k");
+                }
+            }
+        }
+    }
+    DebugEcho("     \$common_places_found ist $common_places_found: " . print_r($categories, true) );
+    if ( $common_places_found == 0 ) {
+        array_push( $categories,  get_term_by('name', (string) "Vernacular", 'category')->term_id );
+    } else {
+        $c2 = \array_diff($categories, [1964]);
+        $categories = $c2;
+        DebugEcho("     'vernacular' removed: " . print_r($categories, true) );
+    }
+    $post['post_category'] = $categories;
+    if ( $meta['city'] )
+        $post['post_content'] = mws_add_caption( $post['post_content'], $meta );
+    /* remove leftover category strings from title */
+    $post['post_title'] = preg_replace('/\[.*\]\s*/', '', $post['post_title']);
+    DebugEcho( "MWS ===> end evaluate_image_exif " .  $imagefile);
+    return $post;
+}
+
+/* ------------------------------------------- exif related functions --- */
+function miech_wp_read_image_metadata( $meta, $file, $sourceImageType ) {
+    DebugEcho('MWS ===> beginning  miech_wp_read_image_metadata');
+    $newmeta = array();
+    
+    // read iptc first, since it might contain data not available in exif such
+    // as caption, description etc
+    getimagesize( $file, $info );
+    if ( ! empty( $info['APP13'] ) ) {
+        $iptc = iptcparse( $info['APP13'] );
+        $newmeta['title']    = trim( $iptc['2#105'][0] );
+        $newmeta['country']  = trim( $iptc['2#101'][0] );
+        $newmeta['state']    = trim( $iptc['2#095'][0] );
+        $newmeta['city']     = trim( $iptc['2#090'][0] );
+        $newmeta['location'] = trim( $iptc['2#092'][0] );
+        $keywordcount = count($iptc["2#025"]);
+        for ( $i = 0; $i < $keywordcount; $i++ ) {
+            if ( strlen($newmeta['keywords']) > 0 )
+                $newmeta['keywords'] .= ',' ;
+            $newmeta['keywords'] .= $iptc["2#025"][$i];
+        }
+    } 
+
+    $exif = @exif_read_data( $file );
+    /*     DebugEcho('Exif' . print_r($exif)); */
+    DebugEcho('GPSLatitude is ' . $exif['GPSLatitude']);
+    if ( is_numeric($exif['GPSLatitude']) )
+        DebugEcho('GPSLatitude is numeric ' );
+    else
+        DebugEcho('GPSLatitude is not numeric ' );
+        
+    if ( ! empty($exif['GPSLatitude'])) 
+        $newmeta['latitude'] = geo_single_fracs2dec($exif['GPSLatitude'] );
+    if ( ! empty($exif['GPSLongitude']))
+        $newmeta['longitude'] = geo_single_fracs2dec($exif['GPSLongitude']) ;
+    if ( ! empty($exif['GPSLatitudeRef']))
+        if ( $exif['GPSLatitudeRef'] == 'S' )
+            $newmeta['latitude'] = '-' . $newmeta['latitude'];
+    if ( ! empty($exif['GPSLongitudeRef']))
+        if ( $exif['GPSLongitudeRef'] == 'W' )
+            $newmeta['longitude'] = '-' . $newmeta['longitude'];
+
+    foreach ( array( 'city', 'location') as $key ) {
+        if ( $newmeta[ $key ] && ! seems_utf8( $newmeta[ $key ] ) )
+            $newmeta[ $key ] = utf8_encode( $newmeta[ $key ] );
+    }
+    
+    $meta = array_merge($meta, $newmeta);
+    DebugEcho('MWS ===> end miech_wp_read_image_metadata');
+    return $meta;
+}
+
+function geo_frac2dec($str) {
+  @list( $n, $d ) = explode( '/', $str );
+  if ( !empty($d) )
+    return $n / $d;
+  return $str;
+}
+
+function geo_single_fracs2dec($fracs) {
+	return	geo_frac2dec($fracs[0]) +
+		geo_frac2dec($fracs[1]) / 60 +
+		geo_frac2dec($fracs[2]) / 3600;
+}
+
+function mws_add_caption( $s, $meta ) {
+    DebugEcho('MWS ===> begin mws_add_caption');
+    $alt = $meta['title'];
+    $caption = "</div>\n<p class='mycaption'>";
+    if ( $meta['location'] ) {
+        $caption = $caption . $meta['location'] . ', ';
+        $alt     = $alt . ', ' . $meta['location'];
+    }
+    $caption = $caption . $meta['city'];
+    $alt = $alt . ', ' . $meta['city'];
+    if ( $meta['longitude'] ) {
+        $caption = $caption . ' (<a href="http://www.openstreetmap.org/?mlat=' . $meta['latitude'];
+        $caption = $caption . ';&mlon=' . $meta['longitude'] . '&zoom=14&q=mapquest" target="_blank">OSM</a>)'; 
+        $alt = $alt . ', geotagged';
+    }
+    $caption = $caption . "</p>\n";
+    $keywords = $meta['keywords'];
+    DebugEcho('Keywords: ' . $keywords);
+    $keywords = preg_replace('/(WP|Lens,|Status,|Blog,|Published,|Treatment,|)/s', '', $keywords);
+    $keywords = preg_replace('/"/s', "'", $keywords);
+    $keywords = preg_replace('/,/s', ', ', $keywords);
+    $keywords = preg_replace('/, $/', '', $keywords);
+    DebugEcho($keywords);
+    $alt = $alt . ', ' . $keywords;
+    DebugEcho($alt);
+    $s = preg_replace('/<br \/>\s*<\/div>/ims', $caption, $s, 1);
+    $s = preg_replace('/alt=""/ims', 'alt="' . $alt . '"', $s, 1);
+    DebugEcho($s); 
+    DebugEcho('MWS ===> end mws_add_caption');
+    return $s;
+}
+
+/* add the categories of the postie post to all attached images */
+add_filter('postie_post_after', 'mws_postie_add_cats_to_images'); /* MWS now */
+
+function mws_postie_add_cats_to_images( $post ) {
+    $cats = $post['post_category'];
+    $imgs = get_attached_media('image', $post['ID']);
+    $flag = 0;
+    foreach ($cats as $c) {
+        /* DebugEcho( $c ); */
+        $cat = get_category($c);
+        /* DebugEcho( print_r($cat) ); */
+        if ( $cat->cat_ID > 1 ) {
+            foreach ( $imgs as $img ) {
+                wp_set_post_categories( $img->ID, $cat->cat_ID, true );
+            }
+        }
+        $flag = 1;
+    }
+    if ( $flag > 0 ) {
+        wp_set_post_categories( $img->ID,  get_cat_ID('no_user'), true );
+    }
+    return $post;
+}
+
+function make_landscape_photos_large( $post ) {
+    DebugEcho("make_landscape_photos_large 1  +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n" . $post['post_content'] . "\n");
+    preg_match('/ postie_dunit (\d+)pxx(\d+)px /', $post['post_content'], $size);
+    DebugEcho( print_r($size) );
+    if ( $size[1] > $size[2] ) {
+        DebugEcho( "Landscape\n" );
+        #<!-- postie_dunit 750pxx422px --><!-- wp:image {"id":36954,"sizeSlug":"large","linkDestination":"media"} --><figure class="wp-block-image size-large"><a href="https://markus-spring.info/wp-content/uploads/sites/2/2021/03/Ripples-6.jpg"><img src="https://markus-spring.info/wp-content/uploads/sites/2/2021/03/Ripples-6-1200x675.jpg" alt="Ripples.jpg" class="wp-image-36954"/></a><figcaption>Saalachau, Bad Reichenhall</figcaption></figure><!-- /wp:image -->
+        #
+        # <!-- wp:image {"align":"wide","id":36936,"sizeSlug":"large","linkDestination":"media"} --><figure class="wp-block-image alignwide size-large">
+
+        $post['post_content'] = preg_replace('/{/', '{"align":"wide",', $post['post_content']);
+        $post['post_content'] = preg_replace('/wp-block-image /','wp-block-image alignwide ', $post['post_content']);
+        $post['post_content'] = preg_replace('/<!-- postie_dunit.*? -->\n*/', '', $post['post_content']);
+        DebugEcho($post['post_content']);
+    }
+    return $post;
+}
+
+
+/* add_filter('postie_post_after', 'mws_postie_rotate_ios_images');
+
+function mws_postie_rotate_ios_images ( $post ) {
+    $upload_dir = wp_upload_dir();
+    foreach ( $iimgs as $iimg ) {
+        $imagefile = $upload_dir['basedir'] . '/' .
+                     wp_get_attachment_metadata( get_post_thumbnail_id( $post['ID'] ) )['file'];
+        DebugEcho("1. Image to rotate: " .$imagefile);
+        correctImageOrientation($imagefile);
+    }
+   } */
+
+/* add_action('postie_file_added', 'mws_postie_fileadded', 10, 3); */ /* MWS now */
+
+/* function mws_postie_fileadded($postid, $attachmentid, $file_array) {
+   DebugEcho('MWS ========> begin mws_postie_fileadded');
+   $fileinfo = wp_check_filetype(get_attached_file($attachmentid));
+   $upload_dir = wp_upload_dir()['basedir'];
+   $meta = wp_get_attachment_metadata( $attachmentid );
+   $mimetype = $fileinfo['type'];
+   if (strpos($mimetype, 'image', 0) === 0) { //only if attachment is an image
+   $file = $upload_dir . '/' . $meta['file'];
+   set_title_from_exif_if_necessary($postid, $file, $meta);
+   $subdir = dirname($meta['file']);
+   $deg = correctImageOrientation($file);
+   foreach ( array_keys($meta['sizes']) as $size ) {
+   if ( $size != 'full' ) {
+   $file = $upload_dir . '/' . $subdir . '/' . $meta['sizes'][$size]['file'];
+   correctImageOrientation($file);
+   }
+   }
+   }
+   DebugEcho('MWS ========> end mws_postie_fileadded');
+   }
+ */
+
+
+?>

BIN
proxima_nova_alt_light-webfont.woff


BIN
proxima_nova_alt_light-webfont.woff2


BIN
proxima_nova_thin-webfont.woff


BIN
proxima_nova_thin-webfont.woff2


BIN
proximanova-regular-webfont.woff


BIN
proximanova-regular-webfont.woff2


+ 421 - 0
style.css

@@ -0,0 +1,421 @@
+/*
+Theme Name: Twenty Twenty One Child spring2life.
+Theme URI: https://example.com
+Description: spring2life child theme for Twenty Twenty One.
+Author: Markus Spring
+Author URI: https://markus-spring.de
+Template: twentytwentyone
+Version: 1.0
+License: GNU General Public License v2 or later
+License URI: https://www.gnu.org/licenses/gpl-2.0.html
+*/
+
+/* ----------------------------------------------------- proxima-nova --- */
+@font-face {
+    font-family: 'proxima_novaregular';
+    src: url('proximanova-regular-webfont.woff2') format('woff2'),
+         url('proximanova-regular-webfont.woff') format('woff');
+    font-weight: normal;
+    font-style: normal;
+}
+
+@font-face {
+    font-family: 'proxima_novathin';
+    src: url('proxima_nova_thin-webfont.woff2') format('woff2'),
+         url('proxima_nova_thin-webfont.woff') format('woff');
+    font-weight: normal;
+    font-style: normal;
+}
+@font-face {
+    font-family: 'proxima_nova_altlight';
+    src: url('proxima_nova_alt_light-webfont.woff2') format('woff2'),
+         url('proxima_nova_alt_light-webfont.woff') format('woff');
+    font-weight: normal;
+    font-style: normal;
+}
+
+/* raleway-300 - latin */
+@font-face {
+  font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+  font-family: 'Raleway';
+  font-style: normal;
+  font-weight: 300;
+  src: url('fonts/raleway-v29-latin-300.woff2') format('woff2'), /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+       url('fonts/raleway-v29-latin-300.ttf') format('truetype'); /* Chrome 4+, Firefox 3.5+, IE 9+, Safari 3.1+, iOS 4.2+, Android Browser 2.2+ */
+}
+
+/* raleway-300italic - latin */
+@font-face {
+  font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+  font-family: 'Raleway';
+  font-style: italic;
+  font-weight: 300;
+  src: url('fonts/raleway-v29-latin-300italic.woff2') format('woff2'), /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+       url('fonts/raleway-v29-latin-300italic.ttf') format('truetype'); /* Chrome 4+, Firefox 3.5+, IE 9+, Safari 3.1+, iOS 4.2+, Android Browser 2.2+ */
+}
+
+/* raleway-regular - latin */
+@font-face {
+  font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+  font-family: 'Raleway';
+  font-style: normal;
+  font-weight: 400;
+  src: url('fonts/raleway-v29-latin-regular.woff2') format('woff2'), /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+       url('fonts/raleway-v29-latin-regular.ttf') format('truetype'); /* Chrome 4+, Firefox 3.5+, IE 9+, Safari 3.1+, iOS 4.2+, Android Browser 2.2+ */
+}
+
+/* raleway-italic - latin */
+@font-face {
+  font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+  font-family: 'Raleway';
+  font-style: italic;
+  font-weight: 400;
+  src: url('fonts/raleway-v29-latin-italic.woff2') format('woff2'), /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+       url('fonts/raleway-v29-latin-italic.ttf') format('truetype'); /* Chrome 4+, Firefox 3.5+, IE 9+, Safari 3.1+, iOS 4.2+, Android Browser 2.2+ */
+}
+
+/* raleway-500 - latin */
+@font-face {
+  font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+  font-family: 'Raleway';
+  font-style: normal;
+  font-weight: 500;
+  src: url('fonts/raleway-v29-latin-500.woff2') format('woff2'), /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+       url('fonts/raleway-v29-latin-500.ttf') format('truetype'); /* Chrome 4+, Firefox 3.5+, IE 9+, Safari 3.1+, iOS 4.2+, Android Browser 2.2+ */
+}
+
+/* raleway-700 - latin */
+@font-face {
+  font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+  font-family: 'Raleway';
+  font-style: normal;
+  font-weight: 700;
+  src: url('fonts/raleway-v29-latin-700.woff2') format('woff2'), /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+       url('fonts/raleway-v29-latin-700.ttf') format('truetype'); /* Chrome 4+, Firefox 3.5+, IE 9+, Safari 3.1+, iOS 4.2+, Android Browser 2.2+ */
+}
+
+/* raleway-700italic - latin */
+@font-face {
+  font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
+  font-family: 'Raleway';
+  font-style: italic;
+  font-weight: 700;
+  src: url('fonts/raleway-v29-latin-700italic.woff2') format('woff2'), /* Chrome 36+, Opera 23+, Firefox 39+, Safari 12+, iOS 10+ */
+       url('fonts/raleway-v29-latin-700italic.ttf') format('truetype'); /* Chrome 4+, Firefox 3.5+, IE 9+, Safari 3.1+, iOS 4.2+, Android Browser 2.2+ */
+}
+
+
+/* --------------------------------------------------- terminal dosis --- */
+@font-face {
+    font-family: 'Terminal Dosis';
+    src: url('TerminalDosis-ExtraLight.woff2') format('woff2'),
+        url('TerminalDosis-ExtraLight.woff') format('woff');
+    font-weight: 200;
+    font-style: normal;
+    font-display: swap;
+}
+
+@font-face {
+    font-family: 'Terminal Dosis';
+    src: url('TerminalDosis-Bold.woff2') format('woff2'),
+        url('TerminalDosis-Bold.woff') format('woff');
+    font-weight: bold;
+    font-style: normal;
+    font-display: swap;
+}
+
+@font-face {
+    font-family: 'Terminal Dosis';
+    src: url('TerminalDosis-SemiBold.woff2') format('woff2'),
+        url('TerminalDosis-SemiBold.woff') format('woff');
+    font-weight: 600;
+    font-style: normal;
+    font-display: swap;
+}
+
+@font-face {
+    font-family: 'Terminal Dosis';
+    src: url('TerminalDosis-Light.woff2') format('woff2'),
+        url('TerminalDosis-Light.woff') format('woff');
+    font-weight: 300;
+    font-style: normal;
+    font-display: swap;
+}
+
+@font-face {
+    font-family: 'Terminal Dosis';
+    src: url('TerminalDosis-Regular.woff2') format('woff2'),
+        url('TerminalDosis-Regular.woff') format('woff');
+    font-weight: normal;
+    font-style: normal;
+    font-display: swap;
+}
+
+@font-face {
+    font-family: 'Terminal Dosis';
+    src: url('TerminalDosis-Medium.woff2') format('woff2'),
+        url('TerminalDosis-Medium.woff') format('woff');
+    font-weight: 500;
+    font-style: normal;
+    font-display: swap;
+}
+
+@font-face {
+    font-family: 'Terminal Dosis';
+    src: url('TerminalDosis-ExtraBold.woff2') format('woff2'),
+        url('TerminalDosis-ExtraBold.woff') format('woff');
+    font-weight: 800;
+    font-style: normal;
+    font-display: swap;
+}
+
+/* --------------------------------------------- end font definitions --- */
+:root {
+ /* --max--alignwide-width:1400px; */
+ /* --font-base:'proxima_novathin','Raleway',sans-serif; */
+ --font-base:'TerminalDosis-Regular','proxima_novathin','Raleway',sans-serif;
+ /* --font-base:'Raleway',sans-serif; */
+ --global--font-size-base:1.125rem;
+ /* --global--line-height-body:1.6; */
+ /* --font-headings:'proxima_nova_altlight','Raleway',sans-serif; */
+ --font-headings:'TerminalDosis-Regular','proxima_nova_altlight','Raleway',sans-serif;
+ /* --font-headings:'Raleway',sans-serif; */
+ /* --heading--font-weight:500; */
+ --heading--font-weight:700;
+ /* --heading--font-weight:400; */
+ --heading--font-weight-page-title:500;
+ --heading--font-weight-strong:500;
+ /* --heading--font-weight-page-title:700; */
+ /* --heading--font-weight-strong:700; */
+ /* --global--font-size-xxl:4rem; */
+ --global--font-size-xxl:2.8rem;
+ --global--font-size-xxl:3.7rem;
+ /* --primary-nav--font-size:1rem; */
+ /* --primary-nav--font-weight:400; */
+ --primary-nav--font-weight:500;
+ /* --primary-nav--font-weight:400; */
+ /* --button--border-width:1px; */
+ /* --form--border-width:1px */
+ --global--font-size-xs: max(calc(var(--global--font-size-base)*1),16px);
+}
+
+body {
+    /* font-weight: 500; */
+    font-weight: 400;
+}
+
+/* @media only screen and (max-width: 651px) :root { */
+/*     --global--font-size-page-title: min(1.5rem,var(--global--font-size-xxl)); */
+/*     --global--font-size-page-title: 0.5rem; */
+/* } */
+
+.singular .entry-title, .comment-reply-title {
+    /* font-size: calc( var(--global--font-size-page-title) / 3.5 ); */
+}
+
+
+.archive .content-area .format-aside .entry-content, .archive .content-area .format-link .entry-content, .archive .content-area .format-status .entry-content, .blog .content-area .format-aside .entry-content, .blog .content-area .format-link .entry-content, .blog .content-area .format-status .entry-content, .search .content-area .format-aside .entry-content, .search .content-area .format-link .entry-content, .search .content-area .format-status .entry-content {
+    font-size: calc( var(--global--font-size-lg) / 1.3 );
+}
+
+#masthead.site-header, .menu-button-container  {
+    padding-top: calc(var(--global--spacing-vertical)*.2);
+    padding-bottom: calc(var(--global--spacing-vertical)*.2);
+}
+
+.menu-button-container #primary-mobile-menu {
+    margin-top: -18px;
+}
+
+#submit.submit {
+    color: black;
+    background-color: transparent;
+    border-color: grey;
+}
+
+.site-title a {
+    /* font-weight: 500; */
+    font-weight: 400;
+}
+
+/* .linktable a:link { */
+/*     text-decoration: none; */
+/* } */
+
+.linktable .item-title:before {
+    content:": :";
+    /* white-space: pre; */
+}
+
+a:link {
+        text-decoration-color: #888 !important;
+}
+
+a:hover {
+    text-decoration: none !important;
+    color: red !important;
+    /* font-weight: bold; */
+    /* text-decoration-color: red !important; */
+}
+/* a:hover:after { */
+/*     content:"-->"; */
+/*     color: red; */
+/* } */
+
+a:visited {
+        text-decoration-color: #bbb !important;
+}
+
+/* ----------------------------------------------------------- iPad 2 --- */
+@media all and (device-width: 768px) and (device-height: 1024px) and (orientation:landscape) {
+    /* Landscape css rules */
+    #primary {
+        margin: 0 2em !important;
+    }
+    .site-branding {
+        margin-left: 2em;
+    }
+}
+@media all and (device-width: 768px) and (device-height: 1024px) and (orientation:portrait) {
+  /* Portrait css rules */
+    #primary {
+        margin: 0 2em !important;
+    }
+    .site-branding {
+        margin-left: 2em;
+    }
+}
+/* ------------------------------------------------------- end iPad 2 --- */
+
+.sub-menu-toggle {
+    display: none !important;
+}
+
+.box {
+    display: flex;
+    width: 268px;
+}
+
+@media all and (min-width: 1150px) {
+    /* h1.entry-title, h2.entry-title { */
+    /*     display: inline-block; */
+    /*     float: left; */
+    /*     margin-left: calc(50% - var(--responsive--alignwide-width)/2) !important; */
+    /* } */
+}
+
+#content { margin-top: 2rem;
+           padding-top: 0;
+         }
+.entry-header {
+        margin-bottom: 0 !important;
+}
+h1.entry-title, h2.entry-title, h2.comments-title, h2.comment-reply-title {
+    /* font-size: calc(var(--archive-heading-size,var(--heading--font-size-h2))/1.5) !important; */
+    font-size: calc(var(--archive-heading-size,var(--heading--font-size-h2))/1) !important; 
+    /* margin-top: -3px !important; */
+}
+h2.comment-reply-title {
+    font-size: calc(var(--archive-heading-size,var(--heading--font-size-h2))/2) !important;
+}
+.h4, h4 {
+    font-size: calc(var(--heading--font-size-h4)/1.2);
+}
+
+.wp-block-jetpack-tiled-gallery {
+    padding-top: 30px;
+}
+
+.site-name, .powered-by {
+    display: none;
+}
+
+.wpcf7-submit {
+    background: white !important;
+    color: black !important;
+}
+
+/* todo: https://www.cssscript.com/pure-css-expanding-link-underlines/ */
+
+.entry-footer {
+    margin-top: calc(var(--global--spacing-vertical)*1.4) !important;
+}
+
+img[class^="wp-image-"] {
+    padding: 4px;
+    background: white;
+    border: 1px solid #999;
+}
+
+/* --------------------------------------------------------- archives --- */
+.archive-wider {
+    max-width: calc(var(--responsive--aligndefault-width)*1.5);
+}
+
+.blocks-gallery-grid {
+    /* max-width: auto ; */
+    max-width: calc(var(--responsive--aligndefault-width)*1.5) !important;
+}
+
+.archive-slide {
+    width: 210px;
+    height: 210px;
+    margin: 7px;
+    border: solid 1px #a5a5a5;
+    border-radius: 8px;
+    -moz-border-radius: 8px;
+    -webkit-border-radius: 8px;
+    filter: alpha(opacity=85);
+    -moz-opacity: 0.85;
+    opacity: 0.85;
+    float: left;
+    position: relative;
+    padding: 40px;
+}
+
+.archive-slide-slide {
+    border: solid 1px #000000;
+}
+
+.archive-slide-titlebar a span {
+    display: block;
+    height: 40px;
+    width: 128px;
+    overflow: hidden;
+    font-size: calc(var(--global--font-size-xs) * 0.7);
+    text-align: center;
+    padding-left: -20px;
+    padding-right: -20px;
+}
+
+/* .pagination:pre { */
+/*     content:"<br style='clear: all; clear:both;'>";  */
+/* } */
+
+/* .single .site-main > article > .entry-footer { */
+.entry-footer {
+    display: grid;
+    grid-template-columns: 2fr 4fr;
+}
+
+.comments-title {
+    /* padding-top: 0 !important; */
+}
+
+#comment {
+    color: black;
+    opacity: revert;
+    font-family: 'proxima_novaregular' !important;
+    font-size: 18px;
+    /* background-blend-mode: unset; */
+    background-color: transparent;
+}
+
+#comment:focus, #comment:hover {
+    background-color:white !important;
+}
+
+/* remove wp mail smtp nags */
+div#setting-error-tgmpa, #update-nag, .update-nag, .updated.caldera_forms, wp-admin-bar-wp-mail-smtp-menu {
+    display: none;
+} 

+ 45 - 0
template-parts/header/site-branding.php

@@ -0,0 +1,45 @@
+<?php
+/**
+ * Displays header site branding
+ *
+ * @package WordPress
+ * @subpackage Twenty_Twenty_One
+ * @since Twenty Twenty-One 1.0
+ */
+
+$blog_info    = get_bloginfo( 'name' );
+$description  = get_bloginfo( 'description', 'display' );
+$show_title   = ( true === get_theme_mod( 'display_title_and_tagline', true ) );
+$header_class = $show_title ? 'site-title' : 'screen-reader-text';
+
+?>
+
+<?php if ( has_custom_logo() && $show_title ) : ?>
+	<div class="site-logo"><?php the_custom_logo(); ?></div>
+<?php endif; ?>
+
+<div class="site-branding">
+
+  <?php if ( has_custom_logo() && ! $show_title ) : ?>
+    <div class="site-logo"><?php the_custom_logo(); ?></div>
+  <?php endif; ?>
+  
+  <?php if ( $blog_info ) : ?>
+    <?php if ( is_front_page() && ! is_paged() ) : ?>
+      <!-- <h1 class="<?php echo esc_attr( $header_class ); ?>"><?php echo esc_html( $blog_info ); ?></h1> -->
+      <?php [$image_url, $post_url] = catch_that_image(); ?>
+      <!-- $post_url; <?php echo $post_url ?> -->
+      <h1 class="<?php echo esc_attr( $header_class ); ?>"><a href="<?php echo esc_url( $post_url ); ?>"><small>This post on</small> <?php echo esc_html( $blog_info ); ?></a></h1>
+    <?php elseif ( is_front_page() || is_home() ) : ?>
+      <h1 class="<?php echo esc_attr( $header_class ); ?>"><a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php echo esc_html( $blog_info ); ?></a></h1>
+    <?php else : ?>
+      <p class="<?php echo esc_attr( $header_class ); ?>"><a href="<?php echo esc_url( home_url( '/' ) ); ?>"><?php echo esc_html( $blog_info ); ?></a></p>
+    <?php endif; ?>
+  <?php endif; ?>
+  
+  <?php if ( $description && true === get_theme_mod( 'display_title_and_tagline', true ) ) : ?>
+    <p class="site-description">
+      <?php echo $description; // phpcs:ignore WordPress.Security.EscapeOutput ?>
+    </p>
+  <?php endif; ?>
+</div><!-- .site-branding -->

+ 30 - 0
template-parts/header/titlepage-header.php

@@ -0,0 +1,30 @@
+<?php
+/**
+ * Displays the site header.
+ *
+ * @package WordPress
+ * @subpackage Twenty_Twenty_One
+ * @since Twenty Twenty-One 1.0
+ */
+
+$wrapper_classes  = 'site-header';
+$wrapper_classes .= has_custom_logo() ? ' has-logo' : '';
+$wrapper_classes .= true === get_theme_mod( 'display_title_and_tagline', true ) ? ' has-title-and-tagline' : '';
+$wrapper_classes .= has_nav_menu( 'primary' ) ? ' has-menu' : '';
+?>
+
+<!-- https://www.cssscript.com/morphing-side-menu-with-pure-css-css3/ -->
+<input type="checkbox" id="menuTrigger"/>
+<div class="menu">
+  <label for="menuTrigger" class="trigger">
+    <div class="line"></div>
+    <div class="line"></div>
+    <div class="line"></div>
+  </label>
+</div>
+<header id="masthead" class="<?php echo esc_attr( $wrapper_classes ); ?>" role="banner">
+
+	<?php get_template_part( 'template-parts/header/site-branding' ); ?>
+	<?php get_template_part( 'template-parts/header/site-nav' ); ?>
+
+</header><!-- #masthead -->

+ 179 - 0
titlepage.css

@@ -0,0 +1,179 @@
+   /* --------------------------------------------- animated burger menu --- */
+   /* from  https://www.cssscript.com/morphing-side-menu-with-pure-css-css3/ */
+   
+   .menu {
+     position:fixed;
+     /* position: absolute; */
+     top: 0;
+     left: 0;
+     z-index: 1000;
+     height: 70px;
+     width: 70px;
+     overflow: hidden;
+     pointer-events: none;
+     -webkit-user-select: none;
+     -moz-user-select: none;
+     -ms-user-select: none;
+     user-select: none;
+   }
+   
+   .menu * {
+     -webkit-backface-visibility: hidden;
+     backface-visibility: hidden;
+   }
+   
+   #menuTrigger:checked ~ .menu { pointer-events: auto; }
+   
+   #menuTrigger:checked ~ .menu h3 {
+     -webkit-transform: translate3d(0, 0, 0);
+     transform: translate3d(0, 0, 0);
+     -webkit-transition-delay: 0.2s;
+     transition-delay: 0.2s;
+   }
+   
+   #menuTrigger:checked ~ header>.site-branding p {
+     color: green !important;
+     display: flex !important;
+   }
+   
+   .menu ~ header {
+     display: none !important;
+   }
+   
+   #menuTrigger:checked ~ header {
+     display: flex !important;
+   }
+   
+   #menuTrigger:checked ~ #masthead {
+     -webkit-transform: translate3d(0, 0, 0);
+     transform: translate3d(0, 0, 0);
+     -webkit-transition-delay: 0.2s;
+     transition-delay: 0.2s;
+   }
+   
+   
+   .menu .trigger {
+     position: absolute;
+     z-index: 0;
+     top: 10px;
+     left: 10px;
+     height: 56px;
+     width: 56px;
+     border-radius: 100%;
+     cursor: pointer;
+     pointer-events: auto;
+     -webkit-transition: all 0.4s ease-in-out;
+     transition: all 0.4s ease-in-out;
+     -webkit-transition-property: -webkit-transform, box-shadow;
+     transition-property: transform, box-shadow;
+     -webkit-transform: translate3d(0, 0, 0);
+     transform: translate3d(0, 0, 0);
+     box-shadow: 0 0 0 0px #424242;
+   }
+   
+   .menu .trigger:before {
+     content: '';
+     position: absolute;
+     top: 0;
+     left: 0;
+     height: 100%;
+     width: 100%;
+     border-radius: inherit;
+     overflow: hidden;
+     -webkit-transform: translate3d(0, 0, 0);
+     transform: translate3d(0, 0, 0);
+     -webkit-transition: box-shadow 0.2s 0.4s ease-in-out;
+     transition: box-shadow 0.2s 0.4s ease-in-out;
+     box-shadow: 0 0 0 28px #424242 inset, 0 0 0 28px #FF5722 inset;
+   }
+   
+   #menuTrigger:checked ~ .menu .trigger {
+     /* -webkit-transform: translate3d(94px, 0, 0); */
+     /* transform: translate3d(94px, 0, 0); */
+     /* box-shadow: 0 0 0 370px #424242; */
+   }
+   
+   #menuTrigger:checked ~ .menu .trigger:before {
+     -webkit-transition-delay: 0s;
+     transition-delay: 0s;
+     box-shadow: 0 0 0 0 #424242 inset, 0 0 0 28px #FF5722 inset;
+   }
+   
+   #menuTrigger:checked ~ .menu .trigger .line:nth-child(1) {
+     -webkit-transform: translateY(0) translate3d(-50%, -50%, 0);
+     transform: translateY(0) translate3d(-50%, -50%, 0);
+   }
+   
+   #menuTrigger:checked ~ .menu .trigger .line:nth-child(3) {
+     -webkit-transform: translateY(0) translate3d(-50%, -50%, 0);
+     transform: translateY(0) translate3d(-50%, -50%, 0);
+   }
+   
+   .menu .trigger .line {
+     position: absolute;
+     top: 50%;
+     left: 50%;
+     background: white;
+     height: 2px;
+     width: 18.66667px;
+     -webkit-transform: translate3d(-50%, -50%, 0);
+     transform: translate3d(-50%, -50%, 0);
+     -webkit-transition: -webkit-transform 0.4s ease-in-out;
+     transition: transform 0.4s ease-in-out;
+   }
+   
+   .menu .trigger .line:nth-child(1) {
+     -webkit-transform: translateY(-5px) translate3d(-50%, -50%, 0);
+     transform: translateY(-5px) translate3d(-50%, -50%, 0);
+   }
+   
+   .menu .trigger .line:nth-child(3) {
+     -webkit-transform: translateY(5px) translate3d(-50%, -50%, 0);
+     transform: translateY(5px) translate3d(-50%, -50%, 0);
+   }
+   
+   #menuTrigger {
+     position: fixed;
+     top: 0;
+     left: -60px;
+   }
+   /* ----------------------------------------- end animated burger menu --- */
+   
+   /* ------------------------------------------------------ hide footer --- */
+   .site-info {
+     display: none !important;
+   }
+
+   /* -------------------------------------------------- full size image --- */
+   * {
+     margin: 0;
+     padding: 0;
+   }
+   .imgbox {
+     display: grid;
+     height: 100%;
+     /* -webkit-animation: sk-bouncedelay 3s infinite ease-in-out both;
+        animation: sk-bouncedelay 3s infinite ease-in-out both; */
+   }
+   .center-fit {
+     max-width: 100%;
+     max-height: 100vh;
+     /* max-width: 99%;
+        max-height: 99vh; */
+     margin: auto;
+   }
+   @media all and (device-width: 768px) and (device-height: 1024px) {
+     .imgbox {
+       /* height: 100vh;  */
+       height: 100%;
+       display: flex;
+       /* background-color: red; */
+     }
+     .center-fit {
+       position: relative;
+       display:block;
+       /* top: 50%;
+          left: 50%;
+          transform: translate(-50%, -50%); */
+       ;
+     }

+ 273 - 0
titlepage.php

@@ -0,0 +1,273 @@
+<?php
+/*
+Template Name: Titlepage
+ */
+function catch_that_image() {
+    // echo "<!-- catch_that_image! -->\n";
+    $custom_query = new WP_Query( array( 'post_type' => 'post',
+                                         'posts_per_page' => 1,
+                                         'post_status' => 'publish',
+    ) );
+    if ( $custom_query->have_posts() ) {
+        // echo "<!-- if have_posts -->\n";
+        while ( $custom_query->have_posts() ) {
+            // echo "<!-- while have_posts -->\n";
+            $custom_query->the_post();
+            $post = get_post();
+            /*             echo "<!-- post: ", print_r($post, true), " -->\n"; */
+            // $url = get_permalink($post->ID);
+            $url = get_permalink();
+            $title = get_the_title($post->ID);
+            // echo "<!-- url: $url -->\n";
+            $content =  wp_seo_get_description($post);
+            // echo "<!-- content: $content -->\n";
+            $keys = wp_seo_get_keywords($post);
+            echo "<!-- keys: $keys -->\n";
+            
+            $image = false;
+            if ( get_attached_media('image') ) {
+                $image = array_shift(get_attached_media('image'));
+                $image = $image->ID;
+            }
+            if (! $image) {
+                $image = get_post_thumbnail_id();
+            }
+            if ( $image ) {
+                $full =  wp_get_attachment_image_src($image,'full');
+                return [$full, $url, $title, $content, $keys];
+            }
+        }
+    }
+    wp_reset_postdata();
+    return [$image, $url, $title, $content, $keys];
+}
+
+/* get_header(); */
+?>
+<!doctype html>
+<html <?php language_attributes(); ?> <?php twentytwentyone_the_html_classes(); ?>>
+<head>
+  <meta charset="<?php bloginfo( 'charset' ); ?>" />
+  <meta name="viewport" content="width=device-width, initial-scale=1" />
+  <?php wp_head(); 
+  [$image_url, $post_url, $post_title, $post_content, $post_keywords] = catch_that_image(); ?>
+  <!-- after wp_head -->
+  <meta name="description" content="<?php echo $post_content ?>">
+  <meta name="keywords" content="<?php echo $post_keywords ?>">
+  <!-- <meta name="robots" content="index,follow"> -->
+  <title><?php echo $post_title ?> // Markus Spring Photography</title>
+  <meta property="og:locale" content="en_GB" />
+  <meta property='og:url' content='<?php echo get_site_url() ?>'>
+  <meta property='og:type' content='article'> 
+  <meta property='og:title' content='<?php echo $post_title ?>'> 
+  <meta property='og:site_name' content='Markus Spring Photography // spring2life'> 
+  <meta property='og:description' content='<?php echo $post_content ?>'>
+  <meta property='og:image' content='<?php echo $image_url[0] ?>'> 
+  <style>
+   /* --------------------------------------------- animated burger menu --- */
+   /* from  https://www.cssscript.com/morphing-side-menu-with-pure-css-css3/ */
+   
+   .menu {
+     position:fixed;
+     /* position: absolute; */
+     top: 0;
+     left: 0;
+     z-index: 1000;
+     height: 70px;
+     width: 70px;
+     overflow: hidden;
+     pointer-events: none;
+     -webkit-user-select: none;
+     -moz-user-select: none;
+     -ms-user-select: none;
+     user-select: none;
+   }
+   
+   .menu * {
+     -webkit-backface-visibility: hidden;
+     backface-visibility: hidden;
+   }
+   
+   #menuTrigger:checked ~ .menu { pointer-events: auto; }
+   
+   #menuTrigger:checked ~ .menu h3 {
+     -webkit-transform: translate3d(0, 0, 0);
+     transform: translate3d(0, 0, 0);
+     -webkit-transition-delay: 0.2s;
+     transition-delay: 0.2s;
+   }
+   
+   #menuTrigger:checked ~ header>.site-branding p {
+     color: green !important;
+     display: flex !important;
+   }
+   
+   .menu ~ header {
+     display: none !important;
+   }
+   
+   #menuTrigger:checked ~ header {
+     display: flex !important;
+   }
+   
+   #menuTrigger:checked ~ #masthead {
+     -webkit-transform: translate3d(0, 0, 0);
+     transform: translate3d(0, 0, 0);
+     -webkit-transition-delay: 0.2s;
+     transition-delay: 0.2s;
+   }
+   
+   
+   .menu .trigger {
+     position: absolute;
+     z-index: 0;
+     top: 10px;
+     left: 10px;
+     height: 56px;
+     width: 56px;
+     border-radius: 100%;
+     cursor: pointer;
+     pointer-events: auto;
+     -webkit-transition: all 0.4s ease-in-out;
+     transition: all 0.4s ease-in-out;
+     -webkit-transition-property: -webkit-transform, box-shadow;
+     transition-property: transform, box-shadow;
+     -webkit-transform: translate3d(0, 0, 0);
+     transform: translate3d(0, 0, 0);
+     box-shadow: 0 0 0 0px #424242;
+   }
+   
+   .menu .trigger:before {
+     content: '';
+     position: absolute;
+     top: 0;
+     left: 0;
+     height: 100%;
+     width: 100%;
+     border-radius: inherit;
+     overflow: hidden;
+     -webkit-transform: translate3d(0, 0, 0);
+     transform: translate3d(0, 0, 0);
+     -webkit-transition: box-shadow 0.2s 0.4s ease-in-out;
+     transition: box-shadow 0.2s 0.4s ease-in-out;
+     box-shadow: 0 0 0 28px #424242 inset, 0 0 0 28px #FF5722 inset;
+   }
+   
+   #menuTrigger:checked ~ .menu .trigger {
+     /* -webkit-transform: translate3d(94px, 0, 0); */
+     /* transform: translate3d(94px, 0, 0); */
+     /* box-shadow: 0 0 0 370px #424242; */
+   }
+   
+   #menuTrigger:checked ~ .menu .trigger:before {
+     -webkit-transition-delay: 0s;
+     transition-delay: 0s;
+     box-shadow: 0 0 0 0 #424242 inset, 0 0 0 28px #FF5722 inset;
+   }
+   
+   #menuTrigger:checked ~ .menu .trigger .line:nth-child(1) {
+     -webkit-transform: translateY(0) translate3d(-50%, -50%, 0);
+     transform: translateY(0) translate3d(-50%, -50%, 0);
+   }
+   
+   #menuTrigger:checked ~ .menu .trigger .line:nth-child(3) {
+     -webkit-transform: translateY(0) translate3d(-50%, -50%, 0);
+     transform: translateY(0) translate3d(-50%, -50%, 0);
+   }
+   
+   .menu .trigger .line {
+     position: absolute;
+     top: 50%;
+     left: 50%;
+     background: white;
+     height: 2px;
+     width: 18.66667px;
+     -webkit-transform: translate3d(-50%, -50%, 0);
+     transform: translate3d(-50%, -50%, 0);
+     -webkit-transition: -webkit-transform 0.4s ease-in-out;
+     transition: transform 0.4s ease-in-out;
+   }
+   
+   .menu .trigger .line:nth-child(1) {
+     -webkit-transform: translateY(-5px) translate3d(-50%, -50%, 0);
+     transform: translateY(-5px) translate3d(-50%, -50%, 0);
+   }
+   
+   .menu .trigger .line:nth-child(3) {
+     -webkit-transform: translateY(5px) translate3d(-50%, -50%, 0);
+     transform: translateY(5px) translate3d(-50%, -50%, 0);
+   }
+   
+   #menuTrigger {
+     position: fixed;
+     top: 0;
+     left: -60px;
+   }
+   /* ----------------------------------------- end animated burger menu --- */
+   
+   /* ------------------------------------------------------ hide footer --- */
+   .site-info {
+     display: none !important;
+   }
+
+   /* -------------------------------------------------- full size image --- */
+   * {
+     margin: 0;
+     padding: 0;
+   }
+   .imgbox {
+     display: grid;
+     height: 100%;
+     /* -webkit-animation: sk-bouncedelay 3s infinite ease-in-out both;
+        animation: sk-bouncedelay 3s infinite ease-in-out both; */
+   }
+   .center-fit {
+     max-width: 100%;
+     max-height: 100vh;
+     /* max-width: 99%;
+        max-height: 99vh; */
+     margin: auto;
+   }
+   @media all and (device-width: 768px) and (device-height: 1024px) {
+     .imgbox {
+       /* height: 100vh;  */
+       height: 100%;
+       display: flex;
+       /* background-color: red; */
+     }
+     .center-fit {
+       position: relative;
+       display:block;
+       /* top: 50%;
+          left: 50%;
+          transform: translate(-50%, -50%); */
+       ;
+     }
+
+  </style>
+  <!-- <link rel="stylesheet" href="/wp-content/themes/twentytwentyone-child-spring2life/titlepage.css.min"> -->
+  <!-- <link rel="stylesheet" href="https://tobiasahlin.com/css/spinkit.css"> -->
+</head>
+
+<body <?php body_class(); ?>>
+    <!-- <div class="cr cr-top cr-right cr-sticky cr-black">#SupportUkraine</div> -->
+    
+<div class="cr cr-top cr-right cr-sticky cr-black">Нет войне!</div>
+    <?php wp_body_open(); ?>
+  <div id="page" class="site" style="height: 100vh; ">
+    <a class="skip-link screen-reader-text" href="#content"><?php esc_html_e( 'Skip to content', 'twentytwentyone' ); ?></a>
+    <?php /* [$image_url, $post_url, $post_title, $post_content, $post_keywords] = catch_that_image(); */
+    get_template_part( 'template-parts/header/titlepage-header' ); ?>
+    <a href='<?php echo $post_url ?>'>
+      <div class="imgbox">
+        <!-- <div class="sk-bounce skauto">
+        <div class="sk-bounce-dot"></div>
+        <div class="sk-bounce-dot"></div>
+        </div> -->
+        <img class="center-fit" src='<?php echo $image_url[0] ?>'>
+      </div>
+    </a>
+  </div>
+  <?php get_footer(); ?>
+</body>
+