23 Commits
1.0.0 ... 1.0.4

Author SHA1 Message Date
7e877465a6 Ready to release 1.0.4 2025-04-22 19:48:30 +00:00
7360c279ae fixed logo size 2025-03-20 20:55:50 -07:00
641fdb17c5 updated logo 2025-03-20 18:49:52 -07:00
45e10dcacd updated logo 2025-03-20 18:49:52 -07:00
28513d367d functions and classes added. 2025-03-20 18:27:17 -07:00
0c41ca9b65 1.0.3
release with blank db working
2025-03-14 01:54:52 +00:00
d183c4c1e0 Database allowed empty, twig grabs global vars 2025-03-03 12:23:02 -08:00
f76bbfb27c docs for quick install 2025-02-07 16:17:55 -08:00
aca652c22e bumped version 2024-11-13 07:19:43 +00:00
0d4b62ffb9 updated defaults from examples 2024-09-27 12:58:19 -07:00
7cd3071905 router tweak 2024-09-17 22:21:02 -07:00
77b60d34f6 fixed router typos 2024-09-16 06:54:02 -07:00
b858af3b55 updated routes for get and post 2024-09-16 06:47:00 -07:00
937e4581ba added session, moved twig, updated base 2024-09-12 16:28:33 -07:00
f19f59d53a fixed homepage 2024-09-06 12:53:25 -07:00
0c96ba6c90 fixed up router 2024-09-06 12:45:37 -07:00
713a44ad98 fixed some bugs 2024-09-02 17:10:24 -07:00
ea40fc8e38 Moved bootstrap to novaconium 2024-09-01 17:17:12 -07:00
8190b5ed71 updated 404 page 2024-08-31 15:52:59 -07:00
dca2556bca bumped version 2024-08-31 15:30:16 -07:00
90fd87d042 added urls 2024-08-31 15:28:13 -07:00
9447e76815 working for a parked page 2024-08-31 14:02:51 -07:00
e64fbc0678 twig override tweaks 2024-08-30 01:18:08 -07:00
31 changed files with 651 additions and 124 deletions

View File

@@ -1,4 +1,4 @@
![Novaconium PHP](/_assets/header.svg) ![Novaconium PHP](/_assets/novaconium-logo.png)
# Novaconium PHP: A PHP Framework Built from the Past # Novaconium PHP: A PHP Framework Built from the Past
@@ -6,6 +6,9 @@ NovaconiumPHP is a high-performance PHP framework designed with inspiration from
Pronounced: Noh-vah-koh-nee-um Pronounced: Noh-vah-koh-nee-um
Packagist: https://packagist.org/packages/4lt/novaconium
Master Repo: https://git.4lt.ca/4lt/novaconium
## Getting Started ## Getting Started
### Installation ### Installation
@@ -13,8 +16,23 @@ Pronounced: Noh-vah-koh-nee-um
```bash ```bash
mkdir project_name; mkdir project_name;
cd project_name; cd project_name;
mkdir -p App/controllers App/templates App/views public # Native
touch App/controllers/404.php App/controllers/index.php App/views/index.html.twig public/index.php public/.htaccess App/routes.php
composer require 4lt/novaconium composer require 4lt/novaconium
# Composer
docker run --rm --interactive --tty --volume $PWD:/app composer require 4lt/novaconium
cp -R vendor/4lt/novaconium/defaults/App/ .
cp -R vendor/4lt/novaconium/defaults/public/ .
``` ```
#### Compose install (debian)
```bash
sudo nala install curl php-cli php-mbstring git unzip
curl -sS https://getcomposer.org/installer -o composer-setup.php
sudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer
rm composer-setup.php
```
## Documentation
* [Docker Setup](https://git.4lt.ca/4lt/novaconium)

View File

@@ -1,39 +0,0 @@
<svg width="100%" height="200" xmlns="http://www.w3.org/2000/svg">
<rect width="100%" height="100%" fill="black"/>
<defs>
<radialGradient id="star-gradient" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
<stop offset="0%" style="stop-color: white; stop-opacity: 1" />
<stop offset="100%" style="stop-color: white; stop-opacity: 0" />
</radialGradient>
<g id="star">
<circle cx="0" cy="0" r="2" fill="white" />
</g>
</defs>
<!-- Lots of stars moving outward slower -->
<g>
<use href="#star" x="50%" y="50%" transform="translate(-300,-150) scale(1)" />
<use href="#star" x="50%" y="50%" transform="translate(300,-150) scale(1)" />
<use href="#star" x="50%" y="50%" transform="translate(-300,150) scale(1)" />
<use href="#star" x="50%" y="50%" transform="translate(300,150) scale(1)" />
<use href="#star" x="50%" y="50%" transform="translate(-150,-75) scale(0.5)" />
<use href="#star" x="50%" y="50%" transform="translate(150,-75) scale(0.5)" />
<use href="#star" x="50%" y="50%" transform="translate(-150,75) scale(0.5)" />
<use href="#star" x="50%" y="50%" transform="translate(150,75) scale(0.5)" />
<use href="#star" x="50%" y="50%" transform="translate(-75,-37) scale(0.7)" />
<use href="#star" x="50%" y="50%" transform="translate(75,-37) scale(0.7)" />
<use href="#star" x="50%" y="50%" transform="translate(-75,37) scale(0.7)" />
<use href="#star" x="50%" y="50%" transform="translate(75,37) scale(0.7)" />
<use href="#star" x="50%" y="50%" transform="translate(-350,-175) scale(0.4)" />
<use href="#star" x="50%" y="50%" transform="translate(350,-175) scale(0.4)" />
<use href="#star" x="50%" y="50%" transform="translate(-350,175) scale(0.4)" />
<use href="#star" x="50%" y="50%" transform="translate(350,175) scale(0.4)" />
<animateTransform attributeName="transform" type="scale" from="1" to="10" dur="2s" repeatCount="indefinite"/>
<animate attributeName="opacity" from="1" to="0" dur="2s" repeatCount="indefinite" />
</g>
<!-- Centered Title -->
<text x="50%" y="50%" fill="white" font-size="40" text-anchor="middle" font-family="Arial" dy=".3em">
Novaconium PHP
</text>
</svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

BIN
_assets/novaconium-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -1,7 +1,7 @@
{ {
"name": "4lt/novaconium", "name": "4lt/novaconium",
"description": "A high-performance PHP framework built from the past.", "description": "A high-performance PHP framework built from the past.",
"version": "1.0.0", "version": "1.0.4",
"license": "MIT", "license": "MIT",
"authors": [ "authors": [
{ {

11
defaults/App/config.php Normal file
View File

@@ -0,0 +1,11 @@
<?php
$config = [
'database' => [
'host' => '',
'name' => '',
'user' => '',
'pass' => '',
'port' => 3306
],
'base_url' => 'http://localhost:8000'
];

View File

@@ -0,0 +1,15 @@
<?php
// Define our status code and message
$status_code = 404;
$status_message = 'The requested resource could not be found.';
// Set the HTTP response code and message
http_response_code($status_code);
header("Content-Type: text/html");
?>
<h1>Error 404 Resource Not found</h1>
<p><?php echo $status_message; ?></p>
<p style="font-size:10px; margin-top:60px">Novaconium Default 404 page.</p>

View File

@@ -0,0 +1,2 @@
<?php
view('index');

View File

@@ -1,9 +1,9 @@
<?php <?php
$routes = [ $routes = [
'/about' => [ '/about' => [
'file' => 'about' 'get' => 'about'
], ],
'/' => [ '/' => [
'file' => 'index' 'get' => 'index'
] ]
]; ];

View File

@@ -0,0 +1 @@
{# Overrides go here #}

View File

@@ -1,4 +1,4 @@
{% extends '@nytwig/master.html.twig' %} {% extends '@novaconium/master.html.twig' %}
{% block content %} {% block content %}
<h1>This is twig</h1> <h1>This is twig</h1>

View File

@@ -1,6 +1,4 @@
RewriteEngine On RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?_uri=$1 [QSA,L] RewriteRule ^(.*)$ index.php?_uri=$1 [QSA,L]

View File

@@ -0,0 +1,6 @@
<?php
// error_reporting(E_ALL);
// ini_set('display_errors', 1);
define('BASEPATH', dirname(__DIR__, 1));
require_once(BASEPATH . '/vendor/4lt/novaconium/src/novaconium.php');
?>

72
docs/docker.md Normal file
View File

@@ -0,0 +1,72 @@
# Getting Started With Docker
## Clone Docker Cookbooks
[Github Docker Compose Cookbooks](https://github.com/nickyeoman/docker-compose-cookbooks)
```bash
git clone git@github.com:nickyeoman/docker-compose-cookbooks.git /docker-compose-cookbooks
```
## Setup Docker Compose File
Read the sample extends file of /docker-compose-cookbooks/phpcontainer/sample-extends.yml
```bash
# ensure docker-compose exists
[[ -f docker-compose.yml ]] || echo "services:" > docker-compose.yml
# PHP container
tail -n+2 /docker-compose-cookbooks/phpcontainer/sample-extends.yml >> docker-compose.yml
# PHP settings
cp -r /docker-compose-cookbooks/phpcontainer/config .
# Set project directory
sed -i 's|- "./project:/data"|- "./:/data"|' docker-compose.yml
# Mariadb container
tail -n +2 /docker-compose-cookbooks/mariadb/sample-extends.yml >> docker-compose.yml
```
## ENV File
Then setup the .env file, which should look something like this:
```
COOKBOOK=/docker-compose-cookbooks
COMPOSE_PROJECT_NAME=myProject
TZ=America/Vancouver
VOL_CONFIG_PATH=/data/myProject/config
VOL_PATH=/data/myProject/data
# PHP Container
PHPCONTAINER_IMAGE=4lights/phpcontainer:latest
# MariaDB
MARIADB_IMAGE=mariadb:latest
MARIADB_MARIADB_DATABASE=mydb
MARIADB_MARIADB_ROOT_PASSWORD=ChangeThisPassword0123456789ABCD
MARIADB_MARIADB_PASSWORD=AlsoChangeThisPassword0123456789
MARIADB_MARIADB_USER=dbuser
```
## APP Database config
Open the /App/config.php file and change the database section to match the above:
```php
'database' => [
'host' => 'mariadb',
'name' => 'mydb',
'user' => 'dbuser',
'pass' => 'AlsoChangeThisPassword0123456789',
'port' => 3306
],
```
## Start Docker
```docker compose up -d```

3
docs/twig-overrides.md Normal file
View File

@@ -0,0 +1,3 @@
# Twig Overrides
You can override twig templates by creating the same file in the templates directory.

View File

@@ -1 +0,0 @@
<h1>This is 404</h1>

View File

@@ -1,2 +0,0 @@
<?php
echo $twig->render('index.html.twig');

View File

@@ -1,6 +0,0 @@
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
define('BASEPATH', dirname(__DIR__, 1));
require_once(BASEPATH . '/vendor/4lt/novaconium/src/bootstrap.php');
?>

78
src/Database.php Normal file
View File

@@ -0,0 +1,78 @@
<?php
class Database {
private $conn;
public function __construct($dbinfo) {
$this->conn = new mysqli($dbinfo['host'], $dbinfo['user'], $dbinfo['pass'], $dbinfo['name']);
if ($this->conn->connect_error) {
die("Connection failed: " . $this->conn->connect_error);
}
}
public function query($query, $params = []) {
// Prepare the SQL query
if ($stmt = $this->conn->prepare($query)) {
// Bind parameters to the prepared statement (if any)
if (!empty($params)) {
$types = str_repeat('s', count($params)); // Assuming all params are strings
$stmt->bind_param($types, ...$params);
}
// Execute the statement
if (!$stmt->execute()) {
throw new Exception("Query execution failed: " . $stmt->error);
}
// Return the statement result
return $stmt;
} else {
throw new Exception("Query preparation failed: " . $this->conn->error);
}
}
public function getRow($query, $params = []) {
try {
// Perform the query using prepared statement
$stmt = $this->query($query, $params);
// Get the result of the query
$result = $stmt->get_result();
// Fetch the first row from the result
return $result->fetch_assoc();
} catch (Exception $e) {
// Handle the exception (log it, display a message, etc.)
echo "An error occurred: " . $e->getMessage();
return null;
}
}
public function getRows($query, $params = []) {
$stmt = $this->conn->prepare($query);
if (!$stmt) {
die("Query preparation failed: " . $this->conn->error);
}
// Bind parameters if provided
if (!empty($params)) {
$types = str_repeat('s', count($params)); // Assuming all are strings, adjust as needed
$stmt->bind_param($types, ...$params);
}
$stmt->execute();
$result = $stmt->get_result(); // Requires MySQL Native Driver (mysqlnd)
if ($result) {
return $result->fetch_all(MYSQLI_ASSOC);
} else {
return [];
}
}
public function close() {
$this->conn->close();
}
}

62
src/MessageHandler.php Normal file
View File

@@ -0,0 +1,62 @@
<?php
class MessageHandler {
private $messages = [
'error' => [],
'warning' => [],
'notice' => [],
'success' => []
];
// Add a message of a specific type
public function addMessage($type, $message) {
if (!isset($this->messages[$type])) {
throw new Exception("Invalid message type: $type");
}
$this->messages[$type][] = $message;
}
// Get all messages of a specific type
public function getMessages($type) {
return $this->messages[$type] ?? [];
}
// Get all messages of all types
public function getAllMessages() {
return $this->messages;
}
// Get the count of messages for a specific type
public function count($type) {
return isset($this->messages[$type]) ? count($this->messages[$type]) : 0;
}
// Get the total count of all messages
public function totalCount() {
return array_sum(array_map('count', $this->messages));
}
// Check if there are any messages of a specific type
public function hasMessages($type) {
return !empty($this->messages[$type]);
}
// Check if there are any messages at all
public function hasAnyMessages() {
return $this->totalCount() > 0;
}
// Clear messages of a specific type
public function clear($type) {
if (isset($this->messages[$type])) {
$this->messages[$type] = [];
}
}
// Clear all messages
public function clearAll() {
foreach ($this->messages as $type => $list) {
$this->messages[$type] = [];
}
}
}

25
src/Post.php Normal file
View File

@@ -0,0 +1,25 @@
<?php
class Post {
private $data = [];
public function __construct($post) {
$this->sanitize($post);
}
private function sanitize($post) {
foreach ($post as $key => $value) {
$this->data[$key] = is_array($value)
? filter_var_array($value, FILTER_SANITIZE_FULL_SPECIAL_CHARS)
: filter_var($value, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
}
}
public function get($key, $default = null) {
return $this->data[$key] ?? $default;
}
public function all() {
return $this->data;
}
}

40
src/Redirect.php Normal file
View File

@@ -0,0 +1,40 @@
<?php
/**
* Use
* $redirect->to('/login');
* to trigger a redirect
*/
class Redirect {
private ?string $url = null;
private int $statusCode = 303;
public function url(string $relativeUrl, int $statusCode = 303): void {
$this->statusCode = $statusCode;
// Detect HTTPS
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https" : "http";
// Get Hostname
$host = $_SERVER['HTTP_HOST'];
// Get Base Directory
$basePath = rtrim(dirname($_SERVER['SCRIPT_NAME']), '/\\');
// Construct Absolute URL
$this->url = "$protocol://$host$basePath/" . ltrim($relativeUrl, '/');
}
public function isset(): bool {
return !is_null($this->url);
}
public function execute(): void {
if ($this->url) {
header("Location: " . $this->url, true, $this->statusCode);
exit();
}
}
}

View File

@@ -4,22 +4,45 @@ class Router {
public $routes = []; public $routes = [];
public $query = []; public $query = [];
public $path; public $path;
public $controllerPath = BASEPATH . '/App/controllers/404.php'; public $controller;
public $controllerPath;
public $parameters = [];
public $requestType = 'get';
public function __construct() { public function __construct() {
$this->loadRoutes(); $this->routes = $this->loadRoutes();
$this->preparePath(); $this->path = $this->preparePath();
$this->prepareQuery(); $this->query = $this->prepareQuery();
$this->setRouteFile(); $this->requestType = $this->getRequestType();
$this->controller = $this->findController();
$this->controllerPath = $this->setRouteFile();
} }
private function loadRoutes() { private function loadRoutes() {
require_once( BASEPATH . '/App/routes.php'); // Check if Path exists
$this->routes = $routes; if (file_exists(BASEPATH . '/App/routes.php')) {
require_once( BASEPATH . '/App/routes.php');
} else {
require_once(FRAMEWORKPATH . '/defaults/App/routes.php');
}
return $routes;
} }
private function preparePath() { private function preparePath() {
$this->path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH); $path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
//homepage
if ($path === '/') {
return $path;
}
// remove empty directory path
$path = rtrim($path, '/'); // remove trailing slash
//remove anything after and including ampersand
$path = preg_replace('/&.+$/', '', $path);
return $path;
} }
private function prepareQuery() { private function prepareQuery() {
@@ -28,16 +51,84 @@ class Router {
if (isset($parsedUri['query'])) { if (isset($parsedUri['query'])) {
parse_str($parsedUri['query'], $queryArray); parse_str($parsedUri['query'], $queryArray);
} }
$this->query = $queryArray; return $queryArray;
} }
private function setRouteFile() { private function getRequestType() {
// is the requewst a get or post?
if (empty($_POST)) {
return 'get';
} else {
return 'post';
}
}
private function findController() {
// one to one match
if (array_key_exists($this->path, $this->routes)) {
return $this->routes[$this->path][$this->requestType];
}
foreach ($this->routes as $key => $value) { foreach ($this->routes as $key => $value) {
if ( $this->path == $key) { // Check if key contains a curly bracket, if not continue. We already checked above.
$this->controllerPath = BASEPATH . '/App/controllers/' . $value['file'] . '.php'; if (!strpos($key, '{')) continue;
break;
// Remove everything after the curly bracket, from key
$keyPath = substr($key, 0, strpos($key, '{'));
//see if keyPath matches the first characters of $this->path, only the first characters have to match
if (strpos($this->path, $keyPath) === 0) {
// We have a potential match. Now check if the parameter count is equal
$keyParams = explode('/', $key);
$pathParams = explode('/', $this->path);
$keyParamCount = count($keyParams);
$pathParamCount = count($pathParams);
if ($keyParamCount === $pathParamCount) {
for ($i=0; $i < $pathParamCount; $i++) {
if (strpos($keyParams[$i], '{') !== false) {
$keyParams[$i] = substr($keyParams[$i], 1, -1);
$this->parameters[$keyParams[$i]] = $pathParams[$i];
return $this->routes[$key][$this->requestType];
}
}
}
}
}
return '404';
}
// checks if the file exists, sets file path
private function setRouteFile() {
$cp = BASEPATH . '/App/controllers/' . $this->controller . '.php';
if (file_exists($cp)) {
return $cp;
} else {
//Check if 404 exits
if (file_exists(BASEPATH . '/App/controllers/404.php')) {
return BASEPATH . '/App/controllers/404.php';
} else {
return FRAMEWORKPATH . '/defaults/App/controllers/404.php';
} }
} }
} }
public function debug() {
echo '<div id="router-debug-container" class="debug">';
echo '<table border="1" cellpadding="10" cellspacing="0">';
echo '<tr><th>Url Path</th><td>' . htmlspecialchars($this->path) . '</td></tr>';
echo '<tr><th>Controller Path</th><td>' . htmlspecialchars($this->controllerPath) . '</td></tr>';
echo '<tr><th>Parameters</th><td><pre>' . print_r($this->parameters, true) . '</pre></td></tr>';
echo '<tr><th>Routes</th><td><pre>' . print_r($this->routes, true) . '</pre></td></tr>';
echo '</table></div>';
die();
}
} }

57
src/Session.php Normal file
View File

@@ -0,0 +1,57 @@
<?php
class Session {
private $session;
public function __construct() {
session_start();
if (!isset($_SESSION)) {
$this->session = $_SESSION;
$this->setToken();
$this->session['messages'] = [];
} else {
$this->session = $_SESSION;
}
}
public function setToken() {
if (!isset($this->session['token'])) {
$this->session['token'] = bin2hex(random_bytes(32));
}
}
public function set($key, $value) {
$this->session[$key] = $value;
}
public function get($key) {
return isset($this->session[$key]) ? $this->session[$key] : null;
}
public function flash($key) {
$return = $this->get($key);
$this->delete($key);
return $return;
}
public function debug() {
return $this->session;
}
public function delete($key) {
if (isset($this->session[$key])) {
unset($this->session[$key]);
}
}
public function write() {
$_SESSION = $this->session;
session_write_close();
}
public function kill() {
session_destroy();
}
}

View File

@@ -1,13 +0,0 @@
<?php
require_once(BASEPATH . '/vendor/autoload.php');
//Twig
$loader = new Twig\Loader\FilesystemLoader(BASEPATH . '/App/views/');
$loader->addPath(BASEPATH . '/vendor/4lt/novaconium/twig', 'novaconium');
$loader->addPath(BASEPATH . '/App/templates', 'override');
$twig = new Twig\Environment($loader);
// Load a controller
require_once('Router.php');
$router = new Router();
require_once($router->controllerPath);

29
src/functions.php Normal file
View File

@@ -0,0 +1,29 @@
<?php
/**
* Dump and Die
*/
function dd(...$vars) {
echo "<pre style='background:#222;color:#0f0;padding:10px;border-radius:5px;'>";
foreach ($vars as $var) {
var_dump($var);
echo "\n";
}
echo "</pre>";
die();
}
function makeitso() {
global $session, $db, $redirect, $config, $messages;
if (!empty($config['database']['host'])) {
$db->close();
}
$session->set('messages', $messages->getAllMessages());
$session->write();
$redirect->execute();
exit();
}

49
src/novaconium.php Normal file
View File

@@ -0,0 +1,49 @@
<?php
define('FRAMEWORKPATH', BASEPATH . '/vendor/4lt/novaconium');
require_once(BASEPATH . '/vendor/autoload.php');
//Check if config file exists
if (file_exists(BASEPATH . '/App/config.php')) {
require_once(BASEPATH . '/App/config.php');
} else {
require_once(FRAMEWORKPATH . '/defaults/App/config.php');
}
// Global Functions
require_once(FRAMEWORKPATH . '/src/functions.php');
// Creates the view() function using twig
require_once(FRAMEWORKPATH . '/src/twig.php');
// Messages
require_once(FRAMEWORKPATH . '/src/MessageHandler.php');
$messages = new MessageHandler;
// Start a Session
require_once(FRAMEWORKPATH . '/src/Session.php');
$session = new Session();
// Load Database Class
if (!empty($config['database']['host'])) {
require_once(FRAMEWORKPATH . '/src/Database.php');
$db = new Database($config['database']);
}
// Sanatize POST Data
if (!empty($_POST)) {
require_once(FRAMEWORKPATH . '/src/Post.php');
$post = new POST($_POST);
}
// Start a Redirect
require_once(FRAMEWORKPATH . '/src/Redirect.php');
$redirect = new Redirect();
// Load a controller
require_once(FRAMEWORKPATH . '/src/Router.php');
$router = new Router();
//$router->debug();
require_once($router->controllerPath);
makeitso();

24
src/twig.php Normal file
View File

@@ -0,0 +1,24 @@
<?php
//Twig
function view($name = '', $data = []) {
global $config; // Use the globally included $config
$loader = new Twig\Loader\FilesystemLoader(BASEPATH . '/App/views/');
$loader->addPath(BASEPATH . '/vendor/4lt/novaconium/twig', 'novaconium');
$loader->addPath(BASEPATH . '/App/templates', 'override');
$twig = new Twig\Environment($loader);
// Add config to Twig globally
$twig->addGlobal('config', $config);
// Check if the template exists
if (file_exists(BASEPATH . '/App/views/' . $name . '.html.twig')) {
echo $twig->render("$name.html.twig", $data);
return true;
} else {
echo "Error: Twig Template ($name) Not Found.";
return false;
}
}

6
twig/foot.html.twig Normal file
View File

@@ -0,0 +1,6 @@
<!--
What goes very last on the page.
right before the /body
like javascript
or analytics
-->

3
twig/footer.html.twig Normal file
View File

@@ -0,0 +1,3 @@
<!--
What goes in the footer html tag
-->

View File

@@ -1,6 +1,6 @@
<meta charset="utf-8"> <meta charset="utf-8">
<title>{{ title | default('Welcome') }}</title> <title>{{ title | default('Welcome') }}</title>
<meta name="generator" content="nickyeoman/phpframework" /> <meta name="generator" content="Novaconium" />
<meta name="description" content="{{ description | default('No description given') }}"> <meta name="description" content="{{ description | default('No description given') }}">
<meta name="keywords" content="{{ keywords | default('website') }}"> <meta name="keywords" content="{{ keywords | default('website') }}">

View File

@@ -1,54 +1,52 @@
<!doctype html> <!doctype html>
<html class="no-js" lang="en"> <html class="no-js" lang="en">
{% include '@override/mod_above_head.html.twig' ignore missing %} {% include '@override/above_head.html.twig' ignore missing %}
<head> <head>
{% include ['@override/mod_head.html.twig', '@novaconium/head.html.twig'] %} {% include ['@override/head.html.twig', '@novaconium/head.html.twig'] %}
</head> </head>
<body id="{{ pageid | default('pageid') }}"> <body id="{{ pageid | default('pageid') }}">
{# Page Header #} {# Page Header #}
<header> <header>
{% block headerbefore %}{% endblock %} {% block headerbefore %}{% endblock %}
{% include ['@override/mod_nav.html.twig', '@novaconium/nav.html.twig'] %} {% include ['@override/nav.html.twig', '@novaconium/nav.html.twig'] %}
{% block headerafter %}{% endblock %} {% block headerafter %}{% endblock %}
</header> </header>
<!-- Main Content Of The Page --> <!-- Main Content Of The Page -->
<div id="page"> <div id="page">
<div class="container"> <div class="container">
<div class="middle"> <div class="middle">
{% if error|default is not empty %} {% if error|default is not empty %}
{% for key, val in error %} {% for key, val in error %}
<div class="error">{{ val }}</div> <div class="error">{{ val }}</div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
{% if notice|default is not empty %} {% if notice|default is not empty %}
{% for key, val in notice %} {% for key, val in notice %}
<div class="notice">{{ val }}</div> <div class="notice">{{ val }}</div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
<article>
{% block content %}{% endblock %}
</article>
</div>
<article>
{% include 'cms/mod_alex.html.twig' ignore missing %}
{% block content %}{% endblock %}
{% include 'cms/mod_simon.html.twig' ignore missing %}
</article>
</div> </div>
</div> </div>
</div>
{# Page Footer #} {# Page Footer #}
<footer> <footer>
{% block footerbefore %}{% endblock %} {% block footerbefore %}{% endblock %}
{% include ['@override/mod_footer.html.twig', '@novaconium/footer.html.twig'] %} {% include ['@override/footer.html.twig', '@novaconium/footer.html.twig'] %}
{% block footerafter %}{% endblock %} {% block footerafter %}{% endblock %}
</footer> </footer>
{% include ['@override/mod_foot.html.twig', '@novaconium/foot.html.twig'] %} {% include ['@override/foot.html.twig', '@novaconium/foot.html.twig'] %}
</body></html> </body></html>