Initial commit

master
eater 4 years ago
commit 195ea5508b
Signed by: eater
GPG Key ID: AD2560A0F84F0759

2
.gitignore vendored

@ -0,0 +1,2 @@
vendor
var/cache

@ -0,0 +1,23 @@
{
"name": "eater/blog-eater",
"type": "project",
"require": {
"slim/slim": "^4.1",
"slim/psr7": "^1.1",
"league/commonmark": "^1.4",
"yosymfony/toml": "^1.0",
"twig/twig": "^3.0",
"ext-json": "*"
},
"authors": [
{
"name": "eater",
"email": "=@eater.me"
}
],
"autoload": {
"psr-4": {
"Eater\\": "src"
}
}
}

982
composer.lock generated

@ -0,0 +1,982 @@
{
"_readme": [
"This file locks the dependencies of your project to a known state",
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "cb1bcd865d190652150546ba6be7fcf6",
"packages": [
{
"name": "fig/http-message-util",
"version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message-util.git",
"reference": "3242caa9da7221a304b8f84eb9eaddae0a7cf422"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message-util/zipball/3242caa9da7221a304b8f84eb9eaddae0a7cf422",
"reference": "3242caa9da7221a304b8f84eb9eaddae0a7cf422",
"shasum": ""
},
"require": {
"php": "^5.3 || ^7.0"
},
"suggest": {
"psr/http-message": "The package containing the PSR-7 interfaces"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Fig\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Utility classes and constants for use with PSR-7 (psr/http-message)",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2020-02-05T20:36:27+00:00"
},
{
"name": "league/commonmark",
"version": "1.4.3",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "412639f7cfbc0b31ad2455b2fe965095f66ae505"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/412639f7cfbc0b31ad2455b2fe965095f66ae505",
"reference": "412639f7cfbc0b31ad2455b2fe965095f66ae505",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": "^7.1"
},
"conflict": {
"scrutinizer/ocular": "1.7.*"
},
"require-dev": {
"cebe/markdown": "~1.0",
"commonmark/commonmark.js": "0.29.1",
"erusev/parsedown": "~1.0",
"ext-json": "*",
"github/gfm": "0.29.0",
"michelf/php-markdown": "~1.4",
"mikehaertl/php-shellcommand": "^1.4",
"phpstan/phpstan": "^0.12",
"phpunit/phpunit": "^7.5",
"scrutinizer/ocular": "^1.5",
"symfony/finder": "^4.2"
},
"bin": [
"bin/commonmark"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.4-dev"
}
},
"autoload": {
"psr-4": {
"League\\CommonMark\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com",
"role": "Lead Developer"
}
],
"description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and Github-Flavored Markdown (GFM)",
"homepage": "https://commonmark.thephpleague.com",
"keywords": [
"commonmark",
"flavored",
"gfm",
"github",
"github-flavored",
"markdown",
"md",
"parser"
],
"time": "2020-05-04T22:15:21+00:00"
},
{
"name": "nikic/fast-route",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/FastRoute.git",
"reference": "181d480e08d9476e61381e04a71b34dc0432e812"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812",
"reference": "181d480e08d9476e61381e04a71b34dc0432e812",
"shasum": ""
},
"require": {
"php": ">=5.4.0"
},
"require-dev": {
"phpunit/phpunit": "^4.8.35|~5.7"
},
"type": "library",
"autoload": {
"psr-4": {
"FastRoute\\": "src/"
},
"files": [
"src/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Nikita Popov",
"email": "nikic@php.net"
}
],
"description": "Fast request router for PHP",
"keywords": [
"router",
"routing"
],
"time": "2018-02-13T20:26:39+00:00"
},
{
"name": "psr/container",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
"homepage": "https://github.com/php-fig/container",
"keywords": [
"PSR-11",
"container",
"container-interface",
"container-interop",
"psr"
],
"time": "2017-02-14T16:28:37+00:00"
},
{
"name": "psr/http-factory",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-factory.git",
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
"reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be",
"shasum": ""
},
"require": {
"php": ">=7.0.0",
"psr/http-message": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interfaces for PSR-7 HTTP message factories",
"keywords": [
"factory",
"http",
"message",
"psr",
"psr-17",
"psr-7",
"request",
"response"
],
"time": "2019-04-30T12:38:16+00:00"
},
{
"name": "psr/http-message",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-message.git",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Message\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP messages",
"homepage": "https://github.com/php-fig/http-message",
"keywords": [
"http",
"http-message",
"psr",
"psr-7",
"request",
"response"
],
"time": "2016-08-06T14:39:51+00:00"
},
{
"name": "psr/http-server-handler",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-server-handler.git",
"reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-server-handler/zipball/aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
"reference": "aff2f80e33b7f026ec96bb42f63242dc50ffcae7",
"shasum": ""
},
"require": {
"php": ">=7.0",
"psr/http-message": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Server\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP server-side request handler",
"keywords": [
"handler",
"http",
"http-interop",
"psr",
"psr-15",
"psr-7",
"request",
"response",
"server"
],
"time": "2018-10-30T16:46:14+00:00"
},
{
"name": "psr/http-server-middleware",
"version": "1.0.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/http-server-middleware.git",
"reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/http-server-middleware/zipball/2296f45510945530b9dceb8bcedb5cb84d40c5f5",
"reference": "2296f45510945530b9dceb8bcedb5cb84d40c5f5",
"shasum": ""
},
"require": {
"php": ">=7.0",
"psr/http-message": "^1.0",
"psr/http-server-handler": "^1.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Http\\Server\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for HTTP server-side middleware",
"keywords": [
"http",
"http-interop",
"middleware",
"psr",
"psr-15",
"psr-7",
"request",
"response"
],
"time": "2018-10-30T17:12:04+00:00"
},
{
"name": "psr/log",
"version": "1.1.3",
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc",
"reference": "0f73288fd15629204f9d42b7055f72dacbe811fc",
"shasum": ""
},
"require": {
"php": ">=5.3.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.1.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\Log\\": "Psr/Log/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Common interface for logging libraries",
"homepage": "https://github.com/php-fig/log",
"keywords": [
"log",
"psr",
"psr-3"
],
"time": "2020-03-23T09:12:05+00:00"
},
{
"name": "ralouphie/getallheaders",
"version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/ralouphie/getallheaders.git",
"reference": "120b605dfeb996808c31b6477290a714d356e822"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822",
"reference": "120b605dfeb996808c31b6477290a714d356e822",
"shasum": ""
},
"require": {
"php": ">=5.6"
},
"require-dev": {
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^5 || ^6.5"
},
"type": "library",
"autoload": {
"files": [
"src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ralph Khattar",
"email": "ralph.khattar@gmail.com"
}
],
"description": "A polyfill for getallheaders.",
"time": "2019-03-08T08:55:37+00:00"
},
{
"name": "slim/psr7",
"version": "1.1.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim-Psr7.git",
"reference": "3c76899e707910779f13d7af95fde12310b0a5ae"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim-Psr7/zipball/3c76899e707910779f13d7af95fde12310b0a5ae",
"reference": "3c76899e707910779f13d7af95fde12310b0a5ae",
"shasum": ""
},
"require": {
"fig/http-message-util": "^1.1.2",
"php": "^7.2",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0",
"ralouphie/getallheaders": "^3"
},
"provide": {
"psr/http-message-implementation": "1.0"
},
"require-dev": {
"adriansuter/php-autoload-override": "^1.0",
"ext-json": "*",
"http-interop/http-factory-tests": "^0.6.0",
"php-http/psr7-integration-tests": "dev-master",
"phpstan/phpstan": "^0.12",
"phpunit/phpunit": "^8.5",
"squizlabs/php_codesniffer": "^3.5"
},
"type": "library",
"autoload": {
"psr-4": {
"Slim\\Psr7\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Josh Lockhart",
"email": "hello@joshlockhart.com",
"homepage": "http://joshlockhart.com"
},
{
"name": "Andrew Smith",
"email": "a.smith@silentworks.co.uk",
"homepage": "http://silentworks.co.uk"
},
{
"name": "Rob Allen",
"email": "rob@akrabat.com",
"homepage": "http://akrabat.com"
},
{
"name": "Pierre Berube",
"email": "pierre@lgse.com",
"homepage": "http://www.lgse.com"
}
],
"description": "Strict PSR-7 implementation",
"homepage": "https://www.slimframework.com",
"keywords": [
"http",
"psr-7",
"psr7"
],
"time": "2020-05-01T14:24:20+00:00"
},
{
"name": "slim/slim",
"version": "4.5.0",
"source": {
"type": "git",
"url": "https://github.com/slimphp/Slim.git",
"reference": "5613cbb521081ed676d5d7eb3e44f2b80a818c24"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/slimphp/Slim/zipball/5613cbb521081ed676d5d7eb3e44f2b80a818c24",
"reference": "5613cbb521081ed676d5d7eb3e44f2b80a818c24",
"shasum": ""
},
"require": {
"ext-json": "*",
"nikic/fast-route": "^1.3",
"php": "^7.2",
"psr/container": "^1.0",
"psr/http-factory": "^1.0",
"psr/http-message": "^1.0",
"psr/http-server-handler": "^1.0",
"psr/http-server-middleware": "^1.0",
"psr/log": "^1.1"
},
"require-dev": {
"adriansuter/php-autoload-override": "^1.0",
"ext-simplexml": "*",
"guzzlehttp/psr7": "^1.5",
"http-interop/http-factory-guzzle": "^1.0",
"laminas/laminas-diactoros": "^2.1",
"nyholm/psr7": "^1.1",
"nyholm/psr7-server": "^0.3.0",
"phpspec/prophecy": "^1.10",
"phpstan/phpstan": "^0.11.5",
"phpunit/phpunit": "^8.5",
"slim/http": "^1.0",
"slim/psr7": "^1.0",
"squizlabs/php_codesniffer": "^3.5"
},
"suggest": {
"ext-simplexml": "Needed to support XML format in BodyParsingMiddleware",
"ext-xml": "Needed to support XML format in BodyParsingMiddleware",
"php-di/php-di": "PHP-DI is the recommended container library to be used with Slim",
"slim/psr7": "Slim PSR-7 implementation. See https://www.slimframework.com/docs/v4/start/installation.html for more information."
},
"type": "library",
"autoload": {
"psr-4": {
"Slim\\": "Slim"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Josh Lockhart",
"email": "hello@joshlockhart.com",
"homepage": "https://joshlockhart.com"
},
{
"name": "Andrew Smith",
"email": "a.smith@silentworks.co.uk",
"homepage": "http://silentworks.co.uk"
},
{
"name": "Rob Allen",
"email": "rob@akrabat.com",
"homepage": "http://akrabat.com"
},
{
"name": "Pierre Berube",
"email": "pierre@lgse.com",
"homepage": "http://www.lgse.com"
},
{
"name": "Gabriel Manricks",
"email": "gmanricks@me.com",
"homepage": "http://gabrielmanricks.com"
}
],
"description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs",
"homepage": "https://www.slimframework.com",
"keywords": [
"api",
"framework",
"micro",
"router"
],
"time": "2020-04-14T20:49:48+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9",
"reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.17-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Ctype\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for ctype functions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"ctype",
"polyfill",
"portable"
],
"time": "2020-05-12T16:14:59+00:00"
},
{
"name": "symfony/polyfill-mbstring",
"version": "v1.17.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "fa79b11539418b02fc5e1897267673ba2c19419c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c",
"reference": "fa79b11539418b02fc5e1897267673ba2c19419c",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"suggest": {
"ext-mbstring": "For best performance"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.17-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Polyfill\\Mbstring\\": ""
},
"files": [
"bootstrap.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill for the Mbstring extension",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"mbstring",
"polyfill",
"portable",
"shim"
],
"time": "2020-05-12T16:47:27+00:00"
},
{
"name": "twig/twig",
"version": "v3.0.3",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
"reference": "3b88ccd180a6b61ebb517aea3b1a8906762a1dc2"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/Twig/zipball/3b88ccd180a6b61ebb517aea3b1a8906762a1dc2",
"reference": "3b88ccd180a6b61ebb517aea3b1a8906762a1dc2",
"shasum": ""
},
"require": {
"php": "^7.2.5",
"symfony/polyfill-ctype": "^1.8",
"symfony/polyfill-mbstring": "^1.3"
},
"require-dev": {
"psr/container": "^1.0",
"symfony/phpunit-bridge": "^4.4|^5.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"Twig\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Twig Team",
"role": "Contributors"
},
{
"name": "Armin Ronacher",
"email": "armin.ronacher@active-4.com",
"role": "Project Founder"
}
],
"description": "Twig, the flexible, fast, and secure template language for PHP",
"homepage": "https://twig.symfony.com",
"keywords": [
"templating"
],
"time": "2020-02-11T15:33:47+00:00"
},
{
"name": "yosymfony/parser-utils",
"version": "v2.0.0",
"source": {
"type": "git",
"url": "https://github.com/yosymfony/parser-utils.git",
"reference": "00bec9a12722b21f2baf7f9db35f127e90c162c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yosymfony/parser-utils/zipball/00bec9a12722b21f2baf7f9db35f127e90c162c9",
"reference": "00bec9a12722b21f2baf7f9db35f127e90c162c9",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"require-dev": {
"phpunit/phpunit": "^6"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
},
"autoload": {
"psr-4": {
"Yosymfony\\ParserUtils\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Victor Puertas",
"email": "vpgugr@gmail.com",
"homepage": "http://yosymfony.com"
}
],
"description": "Parser utilities",
"homepage": "http://github.com/yosymfony/toml",
"keywords": [
"lexer",
"parser"
],
"time": "2018-06-29T15:31:11+00:00"
},
{
"name": "yosymfony/toml",
"version": "v1.0.4",
"source": {
"type": "git",
"url": "https://github.com/yosymfony/toml.git",
"reference": "bdab92ad920d0e36810a3a3e4a998d23f3498f8e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/yosymfony/toml/zipball/bdab92ad920d0e36810a3a3e4a998d23f3498f8e",
"reference": "bdab92ad920d0e36810a3a3e4a998d23f3498f8e",
"shasum": ""
},
"require": {
"php": ">=7.1",
"yosymfony/parser-utils": "^2.0"
},
"require-dev": {
"phpunit/phpunit": "^7.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
}
},
"autoload": {
"psr-4": {
"Yosymfony\\Toml\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Victor Puertas",
"email": "vpgugr@gmail.com",
"homepage": "http://yosymfony.com"
}
],
"description": "A PHP parser for TOML compatible with specification 0.4.0",
"homepage": "http://github.com/yosymfony/toml",
"keywords": [
"mojombo",
"parser",
"toml"
],
"time": "2018-08-08T15:08:14+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"prefer-stable": false,
"prefer-lowest": false,
"platform": [],
"platform-dev": []
}

@ -0,0 +1,44 @@
[blog]
title = "eater"
description = "it's normal i swear"
link = "https://blog.eater.me/"
[[nav]]
name = "Posts"
link = "/"
before = true
[[nav]]
type = "divider"
before = true
# pages
[[nav]]
type = "divider"
[[nav]]
name = "Games"
link = "/games"
[[nav]]
type = "divider"
[[nav]]
name = "Monster"
link = "/tag/monster"
[[nav]]
name = "Eroge"
link = "/tag/eroge"
[[nav]]
name = "VR"
link = "/tag/VR"
[[nav]]
type = "divider"
[[nav]]
name = "RSS"
link = "/rss.xml"

@ -0,0 +1,9 @@
title = "About"
---
Hey, I am eater
and I write blog posts
[Twitter](https://twitter.com/__eater__)

@ -0,0 +1,35 @@
title = "Blog speedrun any%"
description = "Writing a blog in like 4 hours"
date = 2020-05-19T23:11:00Z
tags = ["dev"]
---
This is it, this is the start.
My very own blog, with blog software written by myself, because of course I want features that's not in any other software.
This whole blog is a single PHP class (300 lines of code!), which reads a `config.toml`, `games/*.md`, `posts/*.md`, and `pages/*.md`
and builds the whole "database" of this blog in-memory. and this all in _\*checks notes\*_ 22ms.
Of course this won't scale, so for that reason I have added "cache", if no `listing.json` is found,
it will write this whole in-memory database to disk in JSON, and when it exists it will use this
instead of reading all markdown files.
The markdown files are split in 2 parts, split by `---`, the top part contains the metadata in toml,
and the bottom part is Just Markdown™, see the following example:
```markdown
title = "Lorem ipsum"
description = "I know about 2 latin"
date = 1997-02-01T13:37:00
tags = ["latin", "why"]
---
Hey click [here](https://blog.eater.me/)
```
Outside that, all pages are rendered in Twig, because twig is nice.
Well, see ya soon for as [Turtle](https://twitter.com/Threetle) coined it, *eater's Ero Evaluations* aka, *E3*.
Also might review all the monster I bought, idk. just see this as me tweeting, but it's way over the 280 character limit.
All the source, including the blog posts, are available at: [git.cijber.net/eater/blog](https://git.cijber.net/eater/blog)

@ -0,0 +1,187 @@
:root {
--color: #F5EDF0;
--background: #424C55;
--accent: #886F68;
--max-width: 800px;
}
* {
box-sizing: border-box;
}
html, body {
padding: 0;
margin: 0;
min-height: 100%;
font-family: sans-serif;
background-color: var(--background);
color: var(--color);
font-weight: 100;
}
a {
color: var(--color);
}
a:hover {
text-decoration: underline var(--accent) !important;
}
* {
margin: 0;
padding: 0;
}
header {
padding-top: 1em;
}
header > .title {
max-width: var(--max-width);
margin: 0 auto;
}
header > .title > h1 {
display: inline-block;
font-weight: 100;
margin-left: 1rem;
margin-bottom: 1rem;
}
header > .title > span {
vertical-align: bottom;
text-align: left;
display: inline-block;
margin-bottom: 1rem;
}
header > nav {
width: 100%;
background-color: var(--color);
}
header > nav > ul {
list-style: none;
padding: 0;
max-width: var(--max-width);
margin: 0 auto;
}
header > nav > ul > li:first-child {
margin-left: -.5em;
}
header > nav > ul > li {
margin: 0;
display: inline-block;
color: var(--background);
}
header > nav > ul > li.divider + li {
border-left: 1px solid var(--accent);
}
header > nav > ul > li > a {
color: var(--background);
text-decoration: none;
display: inline-block;
padding: .5em;
}
header > nav > ul > li:hover,
header > nav > ul > li a:hover {
color: var(--color);
background-color: var(--accent);
}
main {
max-width: var(--max-width);
margin: 0 auto;
padding-top: 1em;
}
.meta {
font-size: 0.9em;
padding: 0.5em 0;
}
.post-listing {
margin-bottom: 1em;
}
.post-listing .title a {
text-decoration: none;
}
.meta .tag {
border-left: 1px var(--color) solid;
padding: 0 0.4em;
}
@media (max-width: 799px) {
main {
margin: 0 1rem;
}
header > nav > ul > li:first-child {
margin-left: 0.5rem;
}
}
iframe {
width: 100%;
height: 200px;
border: none;
}
iframe.itch-widget {
height: 175px;
}
.content {
margin: 1em 0;
}
.content pre {
margin: 1em 0;
}
.tag-title {
margin-bottom: 1rem;
font-size: 2em;
}
main > h2, hr {
margin-bottom: .5em;
}
.post-game {
margin-top: 1em;
}
.post-game > h4 {
margin-bottom: 0.5em;
}
.game-listing {
display: flex;
align-items: center;
margin-bottom: 1em;
}
.game-listing > *:nth-child(2) {
margin-left: 1em;
}
@media (min-width: 800px) {
header > .title > h1 {
margin-left: 0;
}
}
p {
margin: inherit;
}

@ -0,0 +1,11 @@
<?php
include(__DIR__."/../vendor/autoload.php");
$file = __DIR__."/".ltrim(parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH), '/');
if (is_file($file)) {
return false;
}
(new Eater\Blog())->run();

@ -0,0 +1,297 @@
<?php
namespace Eater;
use DateTime;
use League\CommonMark\CommonMarkConverter;
use Slim\Factory\AppFactory;
use Slim\Psr7\Request;
use Slim\Psr7\Response;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Yosymfony\Toml\Toml;
class Blog
{
private $app;
private $twig;
private $debug = false;
private $posts = [];
private $tags = [];
private $pages = [];
private $config = [];
private $games = [];
public function __construct()
{
$this->app = AppFactory::create();
$this->twig = new Environment(
new FilesystemLoader([__DIR__."/../views"]), [
'cache' => __DIR__."/../var/cache/twig",
'debug' => $this->debug,
]
);
$this->routes();
$this->makeListing();
}
public function run()
{
$this->app->run();
}
public function routes()
{
$app = $this->app;
$app->get(
'/',
function (Request $request, Response $response, $args) {
$response->getBody()->write(
$this->twig->render(
"main.html.twig",
$this->context()
)
);
return $response;
}
);
$app->get(
'/tag/{tag}',
function (Request $request, Response $response, $args) {
$tag = $args['tag'];
$posts = array_filter(
$this->posts,
function ($post) use ($tag) {
return in_array($tag, $post['meta']['tags'] ?: []);
}
);
$response->getBody()->write(
$this->twig->render(
"tag.html.twig",
$this->context(
[
'tag' => $tag,
'posts' => $posts,
]
)
)
);
return $response;
}
);
$app->get(
'/game/{game}',
function (Request $request, Response $response, $args) {
$game = $this->games[$args['game']] ?? false;
if ( ! $game) {
return $response->withStatus(404);
}
$posts = array_filter(
$this->posts,
function ($post) use ($game) {
return in_array($game['slug'], $post['meta']['games'] ?: []);
}
);
$response->getBody()->write(
$this->twig->render(
"game.html.twig",
$this->context(
[
'posts' => $posts,
'game' => $game,
'game_body' => $this->parseMarkdown($game['markdown']),
]
)
)
);
return $response;
}
);
$app->get(
'/post/{post}',
function (Request $request, Response $response, $args) {
$post = $this->posts[$args['post']] ?? false;
if ( ! $post) {
return $response->withStatus(404);
}
$response->getBody()->write(
$this->twig->render(
"post.html.twig",
$this->context(
[
'post' => $post,
'post_body' => $this->parseMarkdown($post['markdown']),
]
)
)
);
return $response;
}
);
$app->get(
'/rss.xml',
function (Request $request, Response $response) {
$response->getBody()->write(
$this->twig->render(
"rss.xml.twig",
$this->context()
)
);
return $response->withHeader("Content-Type", "application/rss+xml");
}
);
$app->get(
'/games',
function (Request $request, Response $response) {
$response->getBody()->write(
$this->twig->render(
"games.html.twig",
$this->context()
)
);
return $response;
}
);
$app->get(
'/{page}',
function (Request $request, Response $response, $args) {
$page = $this->pages[$args['page']] ?? false;
if ( ! $page) {
return $response->withStatus(404);
}
$response->getBody()->write(
$this->twig->render(
"page.html.twig",
$this->context(
[
'page' => $page,
'page_body' => $this->parseMarkdown($page['markdown']),
]
)
)
);
return $response;
}
);
}
private function context($context = [])
{
return array_merge(
[
'pages' => $this->pages,
'posts' => $this->posts,
'config' => $this->config,
'games' => $this->games,
'tags' => $this->tags,
],
$context
);
}
private function parseObjects($path, $registerTags = false)
{
$objectBase = realpath($path);
$objects = glob($objectBase."/*.md");
$objectsColl = [];
foreach ($objects as $object) {
$objectSource = file_get_contents($object);
$parts = explode('---', $objectSource, 2);
if (count($parts) !== 2) {
continue;
}
$meta = Toml::parse($parts[0]);
$md = $parts[1];
$slug = ltrim(substr($object, strlen($objectBase)), '/');
$objectsColl[$slug] = [
"markdown" => $md,
"meta" => $meta,
"slug" => $slug,
];
if ($registerTags) {
$this->tags = array_merge($meta['tags'] ?: [], $this->tags);
}
}
return $objectsColl;
}
private function makeListing()
{
$cacheFile = __DIR__."/../var/cache/listing.json";
if (file_exists($cacheFile) && ! $this->debug) {
$data = json_decode(file_get_contents($cacheFile), true);
$this->posts = $data['posts'];
$this->pages = $data['pages'];
$this->tags = $data['tags'];
$this->config = $data['config'];
$this->games = $data['games'];
foreach ($this->posts as &$post) {
if (isset($post['meta']['date'])) {
$post['meta']['date'] = new DateTime($post['meta']['date']['date']);
}
}
return;
}
$this->posts = $this->parseObjects(__DIR__."/../data/posts", true);
$this->pages = $this->parseObjects(__DIR__."/../data/pages");
$this->games = $this->parseObjects(__DIR__."/../data/games");
$this->config = Toml::parse(file_get_contents(__DIR__."/../data/config.toml"));
$this->tags = array_unique($this->tags);
$cacheDir = __DIR__."/../var/cache/";
if ( ! is_dir($cacheDir)) {
mkdir($cacheDir, 0777, true);
}
file_put_contents(
__DIR__."/../var/cache/listing.json",
json_encode(
[
"pages" => $this->pages,
"posts" => $this->posts,
"tags" => $this->tags,
"games" => $this->games,
"config" => $this->config,
]
)
);
}
private function parseMarkdown($markdown)
{
$converter = new CommonMarkConverter();
return $converter->convertToHtml($markdown);
}
}

@ -0,0 +1,44 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="/css/main.css">
<title>{% block title %}{{ config.blog.title }}{% endblock %}</title>
</head>
<body>
<header>
<div class="title">
<h1>{{ config.blog.title }}</h1>
<span>{{ config.blog.description }}</span>
</div>
<nav>
<ul>
{%- for nav in config.nav|filter(n => n.before) -%}
{%- if nav.type == 'divider' -%}
<li class="divider"></li>
{%- else -%}
<li><a href="{{ nav.link }}">{{ nav.name }}</a></li>
{%- endif -%}
{%- endfor -%}
{%- for page in pages -%}
<li><a href="/{{ page.slug }}">{{ page.meta.title }}</a></li>
{%- endfor -%}
{%- for nav in config.nav|filter(n => not n.before) -%}
{%- if nav.type == 'divider' -%}
<li class="divider"></li>
{%- else -%}
<li><a href="{{ nav.link }}">{{ nav.name }}</a></li>
{%- endif -%}
{%- endfor -%}
</ul>
</nav>
</header>
<main>
{% block body %}{% endblock %}
</main>
</body>
</html>

@ -0,0 +1,16 @@
{% extends "base.html.twig" %}
{% import "macros.html.twig" as macros %}
{% block title %}{{ parent() }} — game: {{ game.meta.title }}{% endblock %}
{% block body %}
<h2>{{ game.meta.title }}</h2>
<div class="content">
{{ game_body|raw }}
</div>
<hr>
{{ macros.embed(game) }}
<hr>
{% for post in posts %}
{{ macros.post_listing(post) }}
{% endfor %}
{% endblock %}

@ -0,0 +1,17 @@
{% extends "base.html.twig" %}
{% import "macros.html.twig" as macros %}
{% block title %}{{ parent() }} — games{% endblock %}
{% block body %}
<h2>games</h2>
{% for game in games %}
<a href="/game/{{ game.slug }}" class="game-listing">
{% if game.meta.icon %}
<img src="{{ game.meta.icon }}">
{% elseif game.meta.steam %}
<img src="https://steamcdn-a.akamaihd.net/steam/apps/{{ game.meta.steam }}/capsule_184x69.jpg">
{% endif %}
<h3 class="game-title">{{ game.meta.title }}</h3>
</a>
{% endfor %}
{% endblock %}

@ -0,0 +1,35 @@
{% macro post_listing(post) %}
<div class="post-listing">
<h2 class="title"><a href="/post/{{ post.slug }}">{{ post.meta.title }}</a></h2>
{{ _self.meta(post) }}
<div class="description">{{ post.meta.description }}</div>
</div>
{% endmacro %}
{% macro meta(post) -%}
<div class="meta">
<span class="time">{{ post.meta.date.format("Y-m-d") }}</span>
<span class="tags">
{% for tag in post.meta.tags -%}
<a href="/tag/{{ tag|url_encode }}" class="tag">{{ tag }}</a>
{%- endfor %}
</span>
</div>
{%- endmacro %}
{% macro embed(game) %}
{% if game.meta.steam %}
{{ _self.steamwidget(game.meta.steam) }}
{% endif %}
{% if game.meta.itch %}
{{ _self.itchwidget(game.meta.itch) }}
{% endif %}
{% endmacro %}
{% macro steamwidget(steam_id) %}
<iframe rel="noreferrer noopener" src="https://store.steampowered.com/widget/{{ steam_id }}"></iframe>
{% endmacro %}
{% macro itchwidget(itch_id) %}
<iframe class="itch-widget" src="https://itch.io/embed/{{ itch_id }}?dark=true"></iframe>
{% endmacro %}

@ -0,0 +1,9 @@
{% extends "base.html.twig" %}
{% import "macros.html.twig" as macros %}
{% block body %}
{% for post in posts %}
{{ macros.post_listing(post) }}
{% endfor %}
{% endblock %}

@ -0,0 +1,12 @@
{% extends "base.html.twig" %}
{% block title %}{{ parent() }} — {{ page.meta.title }}{% endblock %}
{% block body %}
<main>
<h1>{{ page.meta.title }}</h1>
<div class="content">
{{ page_body|raw }}
</div>
</main>
{% endblock %}

@ -0,0 +1,26 @@
{% extends "base.html.twig" %}
{% import "macros.html.twig" as macros %}
{% block title %}{{ parent() }} — {{ post.meta.title }}{% endblock %}
{% block body %}
<h1>{{ post.meta.title }}</h1>
{{ macros.meta(post) }}
<div class="content">
{{ post_body|raw }}
</div>
{% if post.meta.games %}
{% set games = post.meta.games|filter(g => games[g])|map(g => games[g]) %}
{% if games|length > 0 %}
<h3>games</h3>
{% for game in games %}
<div class="post-game">
<h4><a href="/game/{{ game.slug }}">{{ game.meta.title }}</a></h4>
{{ macros.embed(game) }}
</div>
{% endfor %}
{% endif %}
{% endif %}
{% endblock %}

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title>{{ config.blog.title }}</title>
<description>{{ config.blog.description }}</description>
<link>{{ config.blog.link }}</link>
<ttl>1800</ttl>
{% for post in posts %}
<item>
<title>{{ post.meta.title }}</title>
<description>{{ post.meta.description }}</description>
<link>{{ config.blog.link }}/post/{{ post.slug }}</link>
<guid isPermaLink="false">{{ post.slug }}</guid>
<pubDate>{{ post.meta.date.format('r') }}</pubDate>
</item>
{% endfor %}
</channel>
</rss>

@ -0,0 +1,11 @@
{% extends "base.html.twig" %}
{% import "macros.html.twig" as macros %}
{% block title %}{{ parent() }} — tag: {{ tag }}{% endblock %}
{% block body %}
<h2 class="tag-title">tag: {{ tag }}</h2>
{% for post in posts %}
{{ macros.post_listing(post) }}
{% endfor %}
{% endblock %}
Loading…
Cancel
Save