Skip to content

Commit 6cc8c45

Browse files
authored
Merge pull request #1 from ginger-tek/v4
v4
2 parents fd691bc + fdebbdc commit 6cc8c45

File tree

14 files changed

+165
-160
lines changed

14 files changed

+165
-160
lines changed

.gitignore

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
1-
config.json
2-
.vscode
1+
.vscode
2+
vendor
3+
4+
assets/
5+
content/
6+
plugins/
7+
config.php

.htaccess

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,5 @@
7575
ExpiresByType image/png "access 1 year"
7676
ExpiresByType application/pdf "access 1 month"
7777
ExpiresByType image/x-icon "access 1 year"
78-
ExpiresDefault "access 1 month"
78+
ExpiresDefault "access 1 hour"
7979
</IfModule>

README.md

Lines changed: 79 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,32 @@
1-
# jerpy
1+
<div align=center>
2+
<h1>jerpy</h1>
3+
<i>"The little CMS that could!"</i>
4+
</div>
5+
<hr>
26

3-
## The smallest, flat-file CMS around!
4-
Jerpy is a flat-file PHP CMS built for control and simplicity that is easy to install, customize, and maintain.
5-
**The whole templating engine is under 1700 characters of PHP code, and the data structure is only 4 directories and 2 files.**
7+
Jerpy is one of the smallest, flat-file PHP content management systems (CMS) built for control and simplicity that is easy to installs, customize, and maintain.
68

7-
This was built to be as streamlined and stripped-down as possible, so it's meant to be administered directly via the files and there's no admin web panel.
9+
**This was built to be as streamlined and stripped-down as possible, so it's meant to be administered directly via the files and there's no admin web panel.**
810

911
# Getting Started
1012
## Composer
11-
Jerpy is super easy to get setup. Simply run the following to download and extract, then copy or rename `config.sample.json` to `config.json`.
13+
Jerpy is super easy to get setup. Simply run the following to get started:
1214
```
1315
composer create-project ginger-tek/jerpy <directory>
1416
```
1517

16-
# File Structure
17-
There are 3 directories for content, one directory for plugins, and one file for configuration. The `pages`, `layouts`, and `assets` directories will hold page contents, layout templates, and site assets, respectively.
18-
19-
## Pages
20-
The `pages` directory stores the page contents for the site, and can be referenced as a file path on the `file` property of a route.
21-
```
22-
🗀 pages
23-
🗋 home.php
24-
```
25-
```json
26-
{
27-
"routes": {
28-
"/": {
29-
"title": "Home",
30-
"file": "pages/home.php"
31-
}
32-
}
33-
}
34-
```
18+
# File/Folder Structure
19+
## `config.php`
20+
All site settings are set in the `config.php` file, including timezone, selected layout, enabled plugins, and page routes.
3521

3622
## Layouts
37-
The `layouts` directory stores layout templates, each their own `.php` file. The default global theme is set in `config.json` on the `layout` property.
23+
The `layouts` directory stores layout templates, each their own `.php` file. The default global theme is set in `config.php` via the `$layout` property.
3824
```
3925
🗀 layouts
4026
🗋 default.php
4127
```
42-
```json
43-
{
44-
"layout": "default"
45-
}
28+
```php
29+
$layout = 'default';
4630
```
4731

4832
## Assets
@@ -53,110 +37,96 @@ This is the global assets directory, in which you can organize your CSS, JavaScr
5337
🗋 styles.css
5438
```
5539
```html
56-
<link href="/assets/css/styles.css" rel="stylesheet">
40+
<head>
41+
...
42+
<link href="/assets/css/styles.css" rel="stylesheet">
43+
...
44+
</head>
5745
```
5846

59-
# Routes
60-
Routes are defined separately from pages to easily manage the content and access of each route.
61-
62-
## Route Properties
63-
Each route is defined as a key on the `routes` property in `config.json` whose value is an object with properties that define the route's page title and content.
47+
## Pages & Routes
48+
The `pages` directory stores the page contents for the site, and are configured for each route in `config.php`.
49+
```
50+
🗀 pages
51+
🗋 home.php
52+
```
53+
```php
54+
$routes = [
55+
'/' => 'pages/home.php'
56+
];
57+
```
58+
You can define a route as a key with either a string pointing to the file, or an associative array with a `page` key and other options to change how the page is rendered.
6459

65-
|Name|Data Type|Required?|Note|
66-
|---|---|---|---|
67-
|`title`|`string`|Yes|Page title|
68-
|`file`|`string`|Conditional|Required if `body` not set. Overwrites `body` value with rendered content|
69-
|`body`|`string`|Conditional|Required if `file` not set. Throws error if neither `file` and `body` set|
70-
|`layout`|`string`|No|If set to valid path, will override default `layout`. If set to false, no layout is used and page body is echoed as is|
60+
To use a different layout than the default, set the `layout` option:
61+
```php
62+
$routes = [
63+
'/about' => [
64+
'page' => 'pages/about.php',
65+
'layout' => 'layouts/layout2.php'
66+
]
67+
];
68+
```
69+
If you don't want any layout to be used at all, set the `layout` option to `false`, which will just render the page by itself.
7170

72-
Additional arbitrary properties can be set for metadata/SEO purposes, but the title and file/body properties are the only necessary properties:
73-
```json
74-
{
75-
"routes": {
76-
"/": {
77-
"title": "Page Title",
78-
"file": "pages/page.php",
79-
"description": "This is a description of the page for SEO",
80-
"thumbnail": "/assets/img/seo.jpg"
81-
}
82-
}
83-
}
71+
Additional arbitrary properties can also be set for metadata/SEO purposes:
72+
```php
73+
$routes = [
74+
'/about' => [
75+
'page' => 'pages/about.php',
76+
'title' => 'About',
77+
'thumbnail' => '/assets/my_thumbnail.png'
78+
]
79+
];
8480
```
8581
You can then implement your additional properties in your layout, such as for social media SEO tags. Use the `@` warning suppressing syntax for when some routes don't have the property specified:
8682
```html
8783
<head>
88-
<title><?= $config->siteName ?> - <?= $page->title ?></title>
89-
<meta name="og:title" content="<?= $page->title ?>">
90-
<meta name="og:description" content="<?= @$page->description ?>">
91-
<meta name="og:image" content="<?= @$page->thumbnail ?>">
84+
...
85+
<meta name="og:title" content="<?= $title ?>">
86+
<meta name="og:description" content="<?= @$description ?>">
87+
<meta name="og:image" content="<?= @$thumbnail ?>">
88+
...
9289
</head>
9390
```
9491

95-
## Dynamic Routes
92+
### Dynamic Routes
9693
You can also specify non-static matching routes for the key string. Use the `:param` syntax to dynamically match a route and have its parameters set to the parsed values from the incoming URI:
97-
```json
98-
{
99-
"routes": {
100-
"/products/:id": {
101-
"file": "pages/product.php"
102-
}
103-
}
104-
}
105-
```
10694
```php
107-
<p>ID: <?= $req->params['id'] ?></p>
95+
$routes = [
96+
'/products/:id' => 'pages/product.php'
97+
];
10898
```
109-
110-
# Templating
111-
Page files are included, rendered on the buffer, and their output is assigned to `$page->body`. To include the page content in a template, simply echo the value of `$page-body`:
11299
```php
113-
<body>
114-
<?= $page->body ?>
115-
</body>
100+
<p>ID: <?= $req->params->id ?></p>
116101
```
117102

118-
Aside from page content, Jerpy relies on the built-in templating functionality of PHP, so use `include` and `require` as you would normally for everything else, parsing content as needed (see [plugins](#plugins) below).
103+
# Templating
104+
PHP's built-in templating is still sufficient for most user-cases nowadays. As such, just use `include` and `require` as you would normally for templating your site, parsing content as needed (see [plugins](#plugins) below).
119105

120106
## Global Variables
121-
There are 4 global variables you can use in a layout or page file: `$config`, `$req`, `$page`, and `$assets`.
107+
There are a couple of global variables you can always reference in a layout or page file: `$req` and `$page`
122108
|Name|Data Type|Note|
123109
|---|---|---|
124-
|`$config`|`object`|The stdClass object of `config.json`|
125-
|`$req`|`object`|The current request, contains properties `path` (string of URI), `method` (string of HTTP method), `query` (object of URL query parameters), and `params` (object of dynamic URI parameters)|
126-
|`$page`|`object`|Contains the `body` content property, as well as all the properties defined by the route object|
127-
128-
# Config.json
129-
```json
130-
{
131-
"siteName": "My Site",
132-
"maintenance": false,
133-
"layout": "default",
134-
"routes": {}
135-
}
136-
```
137-
|Name|Data Type|Note|
138-
|---|---|---|
139-
|`siteName`|`string`|Name for site|
140-
|`maintenance`|`boolean`|Toggle site-wide maintenance mode. When true, returns HTTP 503 for all routes|
141-
|`layout`|`string`|The default layout to use for routes|
142-
|`routes`|`object`|Key:value object of all defined routes|
110+
|`$req`|`object`|The current request, contains properties `uri`, `method` (HTTP Method), `query` (object of URL query parameters), and `params` (object of dynamic route parameters)|
111+
|`$page`|`string`|Path to the page file being rendered|
143112

144113
# Plugins
145-
Plugins can be made for Jerpy, but they do not follow any specific framework or design pattern. This is left up to the developer to ensure that the plugin works and tests succesfully with all the existing features of Jerpy.
146-
147-
The only requirements for plugins are that the entrypoint that is included globally at runtime must be a `.php` file with the same name as the plugin's folder:
114+
Plugins can be made to extend or add functionality to Jerpy. They do not require any specific framework nor follow any particular design pattern. The only requirement for plugins is that the entrypoint is a `.php` file with the same name as the plugin's folder. From there, you can use whatever preferred tools and package managers to create the plugin code.
148115
```
149116
🗀 plugins
150117
🗀 myPlugin <-- plugin dir
118+
🗋 composer.json
151119
🗋 myPlugin.php <-- entrypoint (same as plugin dir)
152120
🗀 vendor
153121
🗋 someSupportingFile.php
154122
```
155123

156-
Plugins are loaded globally and their top-level objects, functions, and/or classes are made accessible in templates and pages.
124+
Plugins are loaded globally, and their top-level objects, functions, and/or classes are accessible from all layouts and pages.
157125

158126
To add a plugin, simply copy/upload the plugin's folder to the `plugins` directory.
159127

128+
To enable a plugin, add it's folder name to the `$plugins` array in `config.php`.
129+
160130
Below is an example plugin for using Parsedown via a wrapper method:
161131

162132
`plugins/md/md.php`
@@ -165,13 +135,19 @@ Below is an example plugin for using Parsedown via a wrapper method:
165135

166136
require 'vendor/Parsedown.php';
167137

168-
function md($p)
138+
function md(string $path): string
169139
{
170-
$pd = new \Parsedown();
171-
return $pd->text(file_get_contents($p));
140+
return (new Parsedown)->text(file_get_contents($path));
172141
}
173142
```
174143

144+
`config.php`
145+
```php
146+
$plugins = [
147+
'md'
148+
];
149+
```
150+
175151
`pages/some-page.php`
176152
```php
177153
<?= md('path/to/markdown-file.md') ?>

assets/delete

Lines changed: 0 additions & 1 deletion
This file was deleted.

composer.json

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,33 @@
22
"name": "ginger-tek/jerpy",
33
"type": "project",
44
"description": "Small, flat-file PHP CMS",
5-
"keywords": ["cms","website"],
5+
"version": "4.0.0",
66
"homepage": "https://github.com/ginger-tek/jerpy",
7-
"license": "MIT",
7+
"license": "ISC",
88
"authors": [
99
{
1010
"name": "GingerTek",
1111
"homepage": "https://github.com/ginger-tek"
1212
}
1313
],
14+
"scripts": {
15+
"post-create-project-cmd": [
16+
"php -r \"array_map('mkdir', ['assets', 'content', 'plugins']);\"",
17+
"php -r \"copy('example.config.php', 'config.php');\""
18+
]
19+
},
20+
"keywords": [
21+
"php",
22+
"cms",
23+
"flat-file",
24+
"website",
25+
"webapp"
26+
],
1427
"require": {
15-
"php": ">=8.1.0"
28+
"php": ">=8.2.0"
1629
},
1730
"support": {
1831
"issues": "https://github.com/ginger-tek/jerpy/issues",
1932
"source": "https://github.com/ginger-tek/jerpy"
2033
}
21-
}
34+
}

config.sample.json

Lines changed: 0 additions & 19 deletions
This file was deleted.

content/delete

Whitespace-only changes.

example.config.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
$timezone = 'America/New_York';
4+
5+
$layout = 'default';
6+
7+
$plugins = [];
8+
9+
$routes = [
10+
'/' => 'pages/home.php',
11+
'/about' => [
12+
'page' => 'pages/about.php',
13+
'title' => 'About'
14+
],
15+
'404' => 'pages/notFound.php'
16+
];

0 commit comments

Comments
 (0)