Rebuild article system

main
Bill Ross 8 months ago
parent 2ffa1b2267
commit 6d996abe27
  1. 16
      composer.json
  2. 81
      index.php
  3. 4
      lang.md
  4. 0
      lib/front.php
  5. 36
      lib/render_markdown.php
  6. 30
      lib/render_php.php
  7. 282
      template.inc
  8. 13
      template.inc.simple

@ -0,0 +1,16 @@
{
"name": "gwhc/blog",
"description": "Simple blog management",
"type": "project",
"license": "ISC",
"authors": [
{
"name": "Bill Ross",
"email": "wnross@gwhc.net"
}
],
"require": {
"league/commonmark": "^2.7",
"symfony/yaml": "^6.0"
}
}

@ -1,57 +1,62 @@
<?php <?php
$debug = 5; #$debug = 5;
require '_debug.php'; require __DIR__ . '/vendor/autoload.php';
require __DIR__ . '/lib/debug.php';
require __DIR__ . '/lib/render_markdown.php';
require __DIR__ . '/lib/render_php.php';
# Pattern begins '/' followed by 1 or more characters that are not '/' or '.'
# Pattern begins '/' foloowed by 1 or more characters that are not '/' or '.'
# In particular this blocks attempts to hack into system # In particular this blocks attempts to hack into system
# #
# Example path '/article/market' will result in 'market' which we can try to # Example path '/article/market' will result in 'market' which we can try to
# match with 'market.php' or 'market.md' # match with 'market.php' or 'market.md'
if (preg_match('#/([^/.]+)#',$_SERVER['PATH_INFO'], $m) === false) { # Nullish ?? is used to set default page for article summaries
if (!preg_match('#/([^/.]+)#',$_SERVER['PATH_INFO']??'/index', $m)) {
http_response_code('400'); http_response_code('400');
echo "Request {$_SERVER['PATH_INFO']} malformed"; echo "Request Path info malformed";
exit; exit;
} }
$page = $m[1];
# Identify type of file as PHP or Markdown $page = $m[1];
if (file_exists($page . '.php')) { if ($page !== 'index') {
$file = $page . '.php'; # Identify type of file as PHP or Markdown
$type = 'php'; if (file_exists($page . '.php')) {
} else if (file_exists($page . '.md')) { $file = $page . '.php';
$file = $page . '.md'; $type = 'php';
$type = 'markdown'; $article = render_php($file);
} else if (file_exists($page . '.md')) {
$file = $page . '.md';
$type = 'markdown';
$article = render_markdown($file);
} else {
# Unknown or invalid path
http_response_code('404');
echo "File '$page' not found";
exit;
}
} else { } else {
# Unknown or invalid path $article = [
http_response_code('404'); 'meta' => [ 'title' => 'articles' ],
echo "File '$page' not found"; 'html' => <<<HTML
exit; <h1>Placeholder for article listings</h1>
HTML,
];
} }
$template = file_get_contents('template.inc');
$result = preg_replace_callback('/\[(\w+)\]/', function ($matches) use ($article) {
$key = $matches[1];
return isset($article['meta'][$key]) ? $article['meta'][$key] : $matches[0]; // fallback to original if key not found
}, $template);
$rendered= preg_replace('/\[contents?\]/', $article['html'], $result);
debug("PAGE: $page\n" debug("PAGE: $page\n"
."TYPE: $type\n" ."TYPE: $type\n"
."FILE: $file\n"
."PATH: {$_SERVER['PATH_INFO']}\n"); ."PATH: {$_SERVER['PATH_INFO']}\n");
# Load file, we do include rather than file_get_contents so PHP can be echo $rendered;
# executed if needed
ob_start();
include __DIR__ . '/' . $file;
$contents = ob_get_clean();
# Split off head matter
#
# this pattern uses the 'ms' modifier to treat multiline strings as a
# single string, and let '\s', '.' etc treat newlines as whitespace
# I match an _optional_ HTML ( '<!-- nnnn -->') comment if we want to wrap
# the headmatter in a comment.
#
# The headmatter is delimited by either '----' or '++++' as per
# Markdown/yaml standards.
# Technical note that '+' is a regex character so \+{3,} instead of ++++
if (preg_match('/^(<!--\s*)?(-{3,}|\+{3,})(.*)(-{3,}|\+{3,})(-->)?(.*)/ms',$contents, $parts) === true) {
$var_dump($parts);
}

@ -1,4 +1,4 @@
---- ---
# Markdown Friendly Headmatter # Markdown Friendly Headmatter
date: 2025-05-08 date: 2025-05-08
title: Why is translation important title: Why is translation important
@ -9,7 +9,7 @@ tags:
- Multilingual websites - Multilingual websites
- Customer trust - Customer trust
- SEO optimization - SEO optimization
---- ---
In today’s global marketplace, businesses of all sizes are reaching out to customers beyond their local borders. For small to medium-sized enterprises (SMEs), having a corporate website that speaks the language of potential customers is no longer just a nice-to-have; it’s essential. Here’s why translation is important for your corporate website. In today’s global marketplace, businesses of all sizes are reaching out to customers beyond their local borders. For small to medium-sized enterprises (SMEs), having a corporate website that speaks the language of potential customers is no longer just a nice-to-have; it’s essential. Here’s why translation is important for your corporate website.

@ -0,0 +1,36 @@
<?php
use League\CommonMark\Environment\Environment;
use League\CommonMark\MarkdownConverter;
use League\CommonMark\Extension\CommonMark\CommonMarkCoreExtension;
use League\CommonMark\Extension\GithubFlavoredMarkdownExtension;
use League\CommonMark\Extension\FrontMatter\FrontMatterExtension;
use League\CommonMark\Extension\FrontMatter\Output\RenderedContentWithFrontMatter;
use Symfony\Component\Yaml\Yaml;
function render_markdown($file) {
// Set up the environment with FrontMatter and GFM support
$environment = new Environment([]);
$environment->addExtension(new CommonMarkCoreExtension());
$environment->addExtension(new GithubFlavoredMarkdownExtension());
$environment->addExtension(new FrontMatterExtension());
$converter = new MarkdownConverter($environment);
$markdownText = file_get_contents($file);
// Convert markdown and extract front matter
/** @var RenderedContentWithFrontMatter $result */
$result = $converter->convert($markdownText);
// Parse YAML front matter
if ($result instanceof RenderedContentWithFrontMatter) {
$frontMatter = $result->getFrontMatter();
}
$html = $result->getContent();
// return result
return [
'meta' => $frontMatter,
'html' => $html,
];
}

@ -0,0 +1,30 @@
<?php
use Symfony\Component\Yaml\Yaml;
function render_php($file) {
ob_start();
#include __DIR__ . '/' . $file;
include $file;
$html = ob_get_clean();
$meta = [];
# Split off head matter
#
# this pattern uses the 'ms' modifier to treat multiline strings as a
# single string, and let '\s', '.' etc treat newlines as whitespace
# I match an _optional_ HTML ( '<!-- nnnn -->') comment if we want to wrap
# the headmatter in a comment.
#
# The headmatter is delimited by either '----' or '++++' as per
# Markdown/yaml standards.
# Technical note that '+' is a regex character so \+{3,} instead of ++++
if (preg_match('/^(<!--\s*)?(-{3,}|\+{3,})\s*(.*?)(-{3,}|\+{3,})\s*(-->)?\s*(.*)/ms',$html, $parts) === 1) {
$html = $parts[6];
$meta = array_merge($meta,Yaml::parse($parts[3]));
}
return [
'html' => $html,
'meta' => $meta,
];
}

@ -0,0 +1,282 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>[title]</title>
<meta name="description" content="[description]">
<meta name="keywords" content="[keywords]">
<meta property="og:type" content="website">
<meta property="og:title" content="Contact Us - Enter Chat">
<meta property="og:description" content="Get in touch with us for any inquiries, support, or feedback. We're here to help you with seamless messaging solutions.">
<meta property="og:image" content="">
<meta property="og:url" content="https://dev3.jit-tr.com/contact.php">
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="Contact Us - Enter Chat">
<meta name="twitter:description" content="Get in touch with us for any inquiries, support, or feedback. We're here to help you with seamless messaging solutions.">
<meta name="twitter:image" content="">
<meta name="twitter:site" content="https://dev3.jit-tr.com/contact.php">
<meta name="author" content="[author]">
<meta name="google-site-verification" content="ruoLJ__fx72vnjayjwZZ7aUVmKHCHGQWq98899JCWCA">
<meta name="google-site-verification" content="XKIBolRewxihYBCtX_IYrVMzM0L90Xb8W86zLhP8usw" data-owner="Bill">
<link rel="icon" href="/icons/favicon.ico">
<link rel="apple-touch-icon" href="/icons/apple-icon-precomposed.png">
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&family=Raleway:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap">
<!-- Vendor CSS Files -->
<link rel="stylesheet" href="/assets/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="/assets/bootstrap-icons/bootstrap-icons.css">
<link rel="stylesheet" href="/assets/aos/aos.css">
<link rel="stylesheet" href="/assets/glightbox/css/glightbox.min.css">
<link rel="stylesheet" href="/assets/swiper/swiper-bundle.min.css">
<!-- Main CSS File -->
<link rel="stylesheet" href="/assets/css/main.css">
<!-- JITTR CSS File -->
<link rel="stylesheet" href="/assets/css/main2.css">
<link rel="stylesheet" href="/css/flaticon.css">
<!-- Carousel File -->
<link rel="stylesheet" href="/css/carousel.css">
<!-- =======================================================
* Template Name: Bootslander
* Template URL: https://bootstrapmade.com/bootslander-free-bootstrap-landing-page-template/
* Updated: Aug 07 2024 with Bootstrap v5.3.3
* Author: BootstrapMade.com
* License: https://bootstrapmade.com/license/
======================================================== -->
<script src="/js/jquery-3.7.0.min.js"></script>
<script src="/js/jquery-ui.min.js"></script>
<script src="/js/jittr.js"></script>
<style>
.faq code i { font-size: x-large; font-weight: bold; color: red;}
.hero { min-height: 1px; padding: 180px 0 12px 0; }
.tab-pane { padding: 2rem; background-color: #f2f2f2 ;}
.SBimg { border: 1px solid #278714; border-radius: 5%; width: 75% }
</style>
</head>
<body class="index-page">
<header id="header" class="header d-flex align-items-center fixed-top">
<div class="container-fluid container-xl position-relative d-flex align-items-center justify-content-between">
<a href="/" class="logo d-flex align-items-center">
<img src="https://1l2m.sfo3.digitaloceanspaces.com/1l2m_imgs/logoTree0.png" alt="logo"
style="max-height: 150px!important; max-width: 150px!important;"
class="rounded-circle border border-3 border-dark">
<h1 class='sitename'><!-- NOtr -->Just In Time Translations<!-- NOtrEND -->
<img style="width: 5%;" src='https://1l2m.sfo3.digitaloceanspaces.com/flags/EN-CA.30x20.gif'></h1> </a>
<nav id="navmenu" class="navmenu">
<ul>
<li class="dropdown"><a href="#">
<span>Options</span> <i class="bi bi-chevron-down toggle-dropdown"></i></a>
<ul>
<li><a href="index.php">Home</a></li>
<li><a href="pricing.php">Basic Pricing</a></li>
<li><a href="faqs.php">FAQs</a></li>
<li><a href="contact.php">Contact</a></li>
<li><a href="https://onelinetomarket.com">MORE</a></li>
</ul>
</li>
<li><a href="pif.php">
<span style="background-color: #1acc8d; color: black; padding: 5px; border-radius: 25%;">
PIF
</span>
</a>
</li>
<li><a href="ourBO.php">Our BackOffice</a></li>
<li><a href="login.php">Log In</a></li>
</ul>
<i class="mobile-nav-toggle d-xl-none bi bi-list"></i>
</nav>
</div>
</header>
<main class="main">
<!-- Hero Section -->
<section id="hero" class="hero section dark-background">
<img src="https://1l2m.sfo3.digitaloceanspaces.com/1l2m_imgs/hero-bg-2.jpg" alt="" class="hero-bg">
<svg class="hero-waves" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 24 150 28 " preserveAspectRatio="none">
<defs> <path id="wave-path" d="M-160 44c30 0 58-18 88-18s 58 18 88 18 58-18 88-18 58 18 88 18 v44h-352z"></path> </defs>
<g class="wave1"> <use xlink:href="#wave-path" x="50" y="3"></use> </g>
<g class="wave2"> <use xlink:href="#wave-path" x="50" y="0"></use> </g>
<g class="wave3"> <use xlink:href="#wave-path" x="50" y="9"></use> </g>
</svg>
</section>
<!-- /Hero Section -->
<!-- Article Section -->
<section class="article section">
<div class="container section-title" data-aos="fade-up">
<h2>[title]</h2>
</div>
<div class="container" data-aos="fade" data-aos-delay="100">
<div class="row gy-4">
[content]
</div>
</div>
</section>
<!-- /Contact Section -->
</main>
<footer id="footer" class="footer dark-background">
<div class="container footer-top">
<div class="row gy-4">
<div class="col-lg-4 col-md-6 footer-about">
<a href="https://onelinetomarket.com" class="logo d-flex align-items-center">
<span class="sitename"><!-- NOtr -->One Line to Market<!-- NOtrEND --></span>
</a>
<div class="footer-info">
<img src="https://1l2m.sfo3.digitaloceanspaces.com/1l2m_imgs/1logoG-1.gif" style="width: 15%; background-color: white;" class="rounded-circle border border-3 border-dark">
Translate <b>and MARKET</b><br>your WHOLE Website Instantly
</div>
<div class="footer-contact pt-3">
</div>
<div class="social-links d-flex mt-4">
<a href="https://www.facebook.com/JustInTime.Translations"><i class="bi bi-facebook"> </i></a>
</div>
</div>
<div class="col-lg-2 col-md-3 footer-links">
<h4>Useful Links</h4>
<ul>
<li class="dropdown"><a href="#">
<span>Options</span> <i class="bi bi-chevron-down toggle-dropdown"></i></a>
<ul>
<li><a href="index.php">Home</a></li>
<li><a href="pricing.php">Basic Pricing</a></li>
<li><a href="faqs.php">FAQs</a></li>
<li><a href="contact.php">Contact</a></li>
<li><a href="https://onelinetomarket.com">MORE</a></li>
</ul>
</li>
<li><a href="pif.php">
<span style="background-color: #1acc8d; color: black; padding: 5px; border-radius: 25%;">
PIF
</span>
</a>
</li>
<li><a href="ourBO.php">Our BackOffice</a></li>
<li><a href="login.php">Log In</a></li>
</ul>
</div>
<div class="col-lg-2 col-md-3 footer-links">
<h4>Our Policies</h4>
<ul>
<li><a href="/terms.php">Terms of service</a></li>
<li><a href="/privacy.php">Privacy policy</a></li>
<li><a href="/cookies.php">Cookie policy</a></li>
</ul>
<hr>
<ul>
<li><a href="/policies/standards.php">Ethical software development</a></li>
<li><a href="/policies/commercial.php">Commercial Schedule for Public Release</a></li>
<li><a href="/policies/health.php">Health and Safety</a></li>
<li><a href="/policies/skills.php">Skills and Apprenticeships</a></li>
<li><a href="/policies/social.php">Sustainability and Social Value</a></li>
<li><a href="/policies/cyber.php">Data Protection and Cyber Security Policy</a></li>
<li><a href="/policies/financial.php">Financial Assessment</a></li>
<li><a href="/policies/slavery.php">Tackling Modern Slavery in Supply Chains</a></li>
<li><a href="/policies/details.php">Ensuring Ethical Use of Our Software - Detailed Series</a></li>
</ul>
</div>
<div class="col-lg-4 col-md-12 footer-newsletter">
<a href="//promote.trustbyreviews.com/one-line-to-market" target="_blank">
<img src="https://1l2m.sfo3.digitaloceanspaces.com/1l2m_imgs/reviews-tr.png" alt="a-reviews" style="width: 80%">
</a>
</div> </div>
</div>
<div class="footer-copyright">
<div style="float: left; margin-left: 3rem;">
<a href="https://training.kuzik.com/" target="_blank" style="text-decoration: none;">
created by ...
<img class="flg" src="https://1l2m.sfo3.digitaloceanspaces.com/1l2m_imgs/ttt.gif" style="width: 10%">
</a>
<a href="https://www.greatwesthosting.com/" target="_blank">
<img class="flg" src="https://1l2m.sfo3.digitaloceanspaces.com/1l2m_imgs/ross.png" style="width: 10%">
</a>
<img src="https://1l2m.sfo3.digitaloceanspaces.com/1l2m_imgs/uptime.png">
</div>
</div>
<!-- NOtr -->
<div class="container copyright text-center mt-4">
<p>
<span>Website Copyright</span>
<strong class="px-1 sitename">Bootslander</strong>
<span>All Rights Reserved</span>
</p>
<div class="credits">
<!-- All the links in the footer should remain intact. -->
<!-- You can delete the links only if you've purchased the pro version. -->
<!-- Licensing information: https://bootstrapmade.com/license/ -->
Designed by <a href="https://bootstrapmade.com/">BootstrapMade</a>
</div>
</div>
<!-- NOtrEND -->
</footer>
<!-- Scroll Top -->
<a href="#" id="scroll-top" class="scroll-top d-flex align-items-center justify-content-center">
<i class="bi bi-arrow-up-short"> </i>
</a>
<!-- Vendor JS Files -->
<script src="/assets/bootstrap/js/bootstrap.bundle.min.js"></script>
<!--script src="/assets/php-email-form/validate.js"></script-->
<script src="/assets/aos/aos.js"></script>
<script src="/assets/glightbox/js/glightbox.min.js"></script>
<script src="/assets/purecounter/purecounter_vanilla.js"></script>
<script src="/assets/swiper/swiper-bundle.min.js"></script>
<!-- Carousel -->
<script src="/js/jittr_carousel.js"></script>
<!-- Main JS File -->
<script src="/assets/js/main.js"></script>
<script>
$(document).ready(function(){
$('[data-bs-toggle="tooltip"]').tooltip();
});
</script>
<script src='https://dev.api.jit-tr.com/?seo=onelinetomarket.com'></script>
</body>
</html>

@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<title>[title]</title>
</head>
<body>
<h1>[title]</h1>
<p>Description: [description]
[contents]
</body>
</html>
Loading…
Cancel
Save