Compare commits

..

3 Commits

Author SHA1 Message Date
dba2e26c93
fix issue 2020-04-28 16:02:54 +00:00
347e14c1c8
fixed typo 2020-04-28 14:37:45 +00:00
cdd5a3e0b6
nickserv help 2020-04-28 14:35:33 +00:00
31 changed files with 456 additions and 1650 deletions

View File

@ -22,7 +22,5 @@ steps:
- name: deploy
commands:
- cd /var/www/tilde.chat
- sudo -Hu www-data git fetch
- sudo -Hu www-data git reset --hard origin/master
- sudo -Hu www-data composer install
- sudo -Hu www-data git pull origin master

View File

@ -1,10 +1,11 @@
<?php
include 'shieldsio.php';
if (!isset($_GET["channel"])) {
$badge = get_badge();
} else {
$badge = get_badge($_GET["channel"]);
}
header("Location: $badge");
die();
include 'shieldsio.php';
if (!isset($_GET["channel"])) {
$badge = get_badge();
header("Location: {$badge}");
} else {
$badge = get_badge($_GET["channel"]);
header("Location: {$badge}");
}
die();
?>

View File

@ -12,13 +12,13 @@
</tr>
</thead>
<tr>
<td>Network user count</td><td>https://tilde.chat/badges/badge.php</td><td><img src="badge.php" alt="user count badge"></td>
<td>Network user count</td><td>https://tilde.chat/badges/badge.php</td><td><img src="badge.php"></td>
</tr>
<tr>
<td>User count for #meta</td><td>https://tilde.chat/badges/badge.php?channel=%23meta</td><td><img src="badge.php?channel=%23meta" alt="#meta badge"></td>
<td>User count for #meta</td><td>https://tilde.chat/badges/badge.php?channel=%23meta</td><td><img src="badge.php?channel=%23meta"></td>
</tr>
<tr>
<td>Invalid channel name (error handling)</td><td>https://tilde.chat/badges/badge.php?channel=invalid</td><td><img src="badge.php?channel=invalid" alt="invalid badge"></td>
<td>Invalid channel name (error handling)</td><td>https://tilde.chat/badges/badge.php?channel=invalid</td><td><img src="badge.php?channel=invalid"></td>
</tr>
</table>
<?php include '../footer.php'; ?>

View File

@ -1,17 +1,16 @@
<?php
function get_badge($channel_name=FALSE): string
{
function get_badge($channel_name=FALSE) {
if ($channel_name==FALSE) {
return "https://img.shields.io/badge/dynamic/json.svg?url=https://tilde.chat/stats.json&label=~chat&query=$.usercount&suffix=%20online&link=https:%2F%2Ftilde.chat&link=https:%2F%2Ftilde.chat%2Fkiwi%2F&colorB=%2300cc00";
return "https://img.shields.io/badge/dynamic/json.svg?url=https://tilde.chat/stats.json&label=~chat&query=$.usercount&suffix=%20online&link=https:%2F%2Ftilde.chat&link=https:%2F%2Fweb.tilde.chat&colorB=%2300cc00";
}
$name_url = urlencode($channel_name);
$name_link = urlencode(substr($channel_name,1));
$stats = json_decode(file_get_contents("https://tilde.chat/stats.json")) ?? array("channels"=>[]);
foreach ($stats->channels as $key=>$channel) {
if ($channel->name==$channel_name) {
return "https://img.shields.io/badge/dynamic/json.svg?url=https://tilde.chat/stats.json&label=~chat&query=$.channels[$key].usercount&suffix=%20online%20on%20$name_url&link=https:%2F%2Ftilde.chat&link=https:%2F%2Ftilde.chat%2Fkiwi%2F$name_link&colorB=%2300cc00";
return "https://img.shields.io/badge/dynamic/json.svg?url=https://tilde.chat/stats.json&label=~chat&query=$.channels[$key].usercount&suffix=%20online%20on%20{$name_url}&link=https:%2F%2Ftilde.chat&link=https:%2F%2Fweb.tilde.chat%2F%3Fjoin%3D{$name_link}&colorB=%2300cc00";
}
}
return "https://img.shields.io/badge/~chat-invalid%20channel-red.svg";
}
?>

View File

@ -1,6 +1,11 @@
{
"require": {
"tildeteam/wiki": "^2.0",
"ext-json": "*"
}
"require": {
"tildeverse/wiki": "dev-master"
},
"repositories": [
{
"type": "vcs",
"url": "https://tildegit.org/ben/tildewiki"
}
]
}

761
composer.lock generated
View File

@ -4,41 +4,33 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "cbfe4e230864ce455fb4e62a47e4a7fc",
"content-hash": "3ab3df15c4e40417f427b37691e83088",
"packages": [
{
"name": "dflydev/dot-access-data",
"version": "v3.0.2",
"name": "erusev/parsedown",
"version": "1.7.3",
"source": {
"type": "git",
"url": "https://github.com/dflydev/dflydev-dot-access-data.git",
"reference": "f41715465d65213d644d3141a6a93081be5d3549"
"url": "https://github.com/erusev/parsedown.git",
"reference": "6d893938171a817f4e9bc9e86f2da1e370b7bcd7"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/f41715465d65213d644d3141a6a93081be5d3549",
"reference": "f41715465d65213d644d3141a6a93081be5d3549",
"url": "https://api.github.com/repos/erusev/parsedown/zipball/6d893938171a817f4e9bc9e86f2da1e370b7bcd7",
"reference": "6d893938171a817f4e9bc9e86f2da1e370b7bcd7",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
"ext-mbstring": "*",
"php": ">=5.3.0"
},
"require-dev": {
"phpstan/phpstan": "^0.12.42",
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.3",
"scrutinizer/ocular": "1.6.0",
"squizlabs/php_codesniffer": "^3.5",
"vimeo/psalm": "^4.0.0"
"phpunit/phpunit": "^4.8.35"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Dflydev\\DotAccessData\\": "src/"
"psr-0": {
"Parsedown": ""
}
},
"notification-url": "https://packagist.org/downloads/",
@ -47,249 +39,85 @@
],
"authors": [
{
"name": "Dragonfly Development Inc.",
"email": "info@dflydev.com",
"homepage": "http://dflydev.com"
},
{
"name": "Beau Simensen",
"email": "beau@dflydev.com",
"homepage": "http://beausimensen.com"
},
{
"name": "Carlos Frutos",
"email": "carlos@kiwing.it",
"homepage": "https://github.com/cfrutos"
},
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com"
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "Given a deep data structure, access data by dot notation.",
"homepage": "https://github.com/dflydev/dflydev-dot-access-data",
"description": "Parser for Markdown.",
"homepage": "http://parsedown.org",
"keywords": [
"access",
"data",
"dot",
"notation"
],
"support": {
"issues": "https://github.com/dflydev/dflydev-dot-access-data/issues",
"source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.2"
},
"time": "2022-10-27T11:44:00+00:00"
},
{
"name": "league/commonmark",
"version": "2.4.2",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/commonmark.git",
"reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/91c24291965bd6d7c46c46a12ba7492f83b1cadf",
"reference": "91c24291965bd6d7c46c46a12ba7492f83b1cadf",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"league/config": "^1.1.1",
"php": "^7.4 || ^8.0",
"psr/event-dispatcher": "^1.0",
"symfony/deprecation-contracts": "^2.1 || ^3.0",
"symfony/polyfill-php80": "^1.16"
},
"require-dev": {
"cebe/markdown": "^1.0",
"commonmark/cmark": "0.30.3",
"commonmark/commonmark.js": "0.30.0",
"composer/package-versions-deprecated": "^1.8",
"embed/embed": "^4.4",
"erusev/parsedown": "^1.0",
"ext-json": "*",
"github/gfm": "0.29.0",
"michelf/php-markdown": "^1.4 || ^2.0",
"nyholm/psr7": "^1.5",
"phpstan/phpstan": "^1.8.2",
"phpunit/phpunit": "^9.5.21 || ^10.5.9 || ^11.0.0",
"scrutinizer/ocular": "^1.8.1",
"symfony/finder": "^5.3 | ^6.0 || ^7.0",
"symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0 || ^7.0",
"unleashedtech/php-coding-standard": "^3.1.1",
"vimeo/psalm": "^4.24.0 || ^5.0.0"
},
"suggest": {
"symfony/yaml": "v2.3+ required if using the Front Matter extension"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "2.5-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"
],
"support": {
"docs": "https://commonmark.thephpleague.com/",
"forum": "https://github.com/thephpleague/commonmark/discussions",
"issues": "https://github.com/thephpleague/commonmark/issues",
"rss": "https://github.com/thephpleague/commonmark/releases.atom",
"source": "https://github.com/thephpleague/commonmark"
},
"funding": [
{
"url": "https://www.colinodell.com/sponsor",
"type": "custom"
},
{
"url": "https://www.paypal.me/colinpodell/10.00",
"type": "custom"
},
{
"url": "https://github.com/colinodell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/league/commonmark",
"type": "tidelift"
}
],
"time": "2024-02-02T11:59:32+00:00"
"time": "2019-03-17T18:48:37+00:00"
},
{
"name": "league/config",
"version": "v1.2.0",
"name": "erusev/parsedown-extra",
"version": "0.7.1",
"source": {
"type": "git",
"url": "https://github.com/thephpleague/config.git",
"reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3"
"url": "https://github.com/erusev/parsedown-extra.git",
"reference": "0db5cce7354e4b76f155d092ab5eb3981c21258c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/thephpleague/config/zipball/754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
"reference": "754b3604fb2984c71f4af4a9cbe7b57f346ec1f3",
"url": "https://api.github.com/repos/erusev/parsedown-extra/zipball/0db5cce7354e4b76f155d092ab5eb3981c21258c",
"reference": "0db5cce7354e4b76f155d092ab5eb3981c21258c",
"shasum": ""
},
"require": {
"dflydev/dot-access-data": "^3.0.1",
"nette/schema": "^1.2",
"php": "^7.4 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^1.8.2",
"phpunit/phpunit": "^9.5.5",
"scrutinizer/ocular": "^1.8.1",
"unleashedtech/php-coding-standard": "^3.1",
"vimeo/psalm": "^4.7.3"
"erusev/parsedown": "~1.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "1.2-dev"
}
},
"autoload": {
"psr-4": {
"League\\Config\\": "src"
"psr-0": {
"ParsedownExtra": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
"MIT"
],
"authors": [
{
"name": "Colin O'Dell",
"email": "colinodell@gmail.com",
"homepage": "https://www.colinodell.com",
"role": "Lead Developer"
"name": "Emanuil Rusev",
"email": "hello@erusev.com",
"homepage": "http://erusev.com"
}
],
"description": "Define configuration arrays with strict schemas and access values with dot notation",
"homepage": "https://config.thephpleague.com",
"description": "An extension of Parsedown that adds support for Markdown Extra.",
"homepage": "https://github.com/erusev/parsedown-extra",
"keywords": [
"array",
"config",
"configuration",
"dot",
"dot-access",
"nested",
"schema"
"markdown",
"markdown extra",
"parsedown",
"parser"
],
"support": {
"docs": "https://config.thephpleague.com/",
"issues": "https://github.com/thephpleague/config/issues",
"rss": "https://github.com/thephpleague/config/releases.atom",
"source": "https://github.com/thephpleague/config"
},
"funding": [
{
"url": "https://www.colinodell.com/sponsor",
"type": "custom"
},
{
"url": "https://www.paypal.me/colinpodell/10.00",
"type": "custom"
},
{
"url": "https://github.com/colinodell",
"type": "github"
}
],
"time": "2022-12-11T20:36:23+00:00"
"time": "2015-11-01T10:19:22+00:00"
},
{
"name": "mnapoli/front-yaml",
"version": "2.0.3",
"version": "1.6.0",
"source": {
"type": "git",
"url": "https://github.com/mnapoli/FrontYAML.git",
"reference": "d42d84159f3725d50f7bda953ed90185b3c41cc4"
"reference": "24070ace8b741247bb3161cbb38ecc541268b296"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mnapoli/FrontYAML/zipball/d42d84159f3725d50f7bda953ed90185b3c41cc4",
"reference": "d42d84159f3725d50f7bda953ed90185b3c41cc4",
"url": "https://api.github.com/repos/mnapoli/FrontYAML/zipball/24070ace8b741247bb3161cbb38ecc541268b296",
"reference": "24070ace8b741247bb3161cbb38ecc541268b296",
"shasum": ""
},
"require": {
"league/commonmark": "^2.0",
"php": "^7.4|^8.0",
"symfony/yaml": "^4.0|^5.0|^6.0|^7.0"
"erusev/parsedown": "~1.0",
"php": ">=5.4.0",
"symfony/yaml": "~2.1|^3.0|^4.0"
},
"require-dev": {
"phpunit/phpunit": "^9.0"
"league/commonmark": "~0.7",
"phpunit/phpunit": "~4.5"
},
"type": "library",
"autoload": {
@ -301,326 +129,54 @@
"license": [
"MIT"
],
"support": {
"source": "https://github.com/mnapoli/FrontYAML/tree/2.0.3"
},
"time": "2024-02-07T14:42:22+00:00"
},
{
"name": "nette/schema",
"version": "v1.3.0",
"source": {
"type": "git",
"url": "https://github.com/nette/schema.git",
"reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/schema/zipball/a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
"reference": "a6d3a6d1f545f01ef38e60f375d1cf1f4de98188",
"shasum": ""
},
"require": {
"nette/utils": "^4.0",
"php": "8.1 - 8.3"
},
"require-dev": {
"nette/tester": "^2.4",
"phpstan/phpstan-nette": "^1.0",
"tracy/tracy": "^2.8"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.3-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause",
"GPL-2.0-only",
"GPL-3.0-only"
],
"authors": [
{
"name": "David Grudl",
"homepage": "https://davidgrudl.com"
},
{
"name": "Nette Community",
"homepage": "https://nette.org/contributors"
}
],
"description": "📐 Nette Schema: validating data structures against a given Schema.",
"homepage": "https://nette.org",
"keywords": [
"config",
"nette"
],
"support": {
"issues": "https://github.com/nette/schema/issues",
"source": "https://github.com/nette/schema/tree/v1.3.0"
},
"time": "2023-12-11T11:54:22+00:00"
},
{
"name": "nette/utils",
"version": "v4.0.4",
"source": {
"type": "git",
"url": "https://github.com/nette/utils.git",
"reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nette/utils/zipball/d3ad0aa3b9f934602cb3e3902ebccf10be34d218",
"reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218",
"shasum": ""
},
"require": {
"php": ">=8.0 <8.4"
},
"conflict": {
"nette/finder": "<3",
"nette/schema": "<1.2.2"
},
"require-dev": {
"jetbrains/phpstorm-attributes": "dev-master",
"nette/tester": "^2.5",
"phpstan/phpstan": "^1.0",
"tracy/tracy": "^2.9"
},
"suggest": {
"ext-gd": "to use Image",
"ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()",
"ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()",
"ext-json": "to use Nette\\Utils\\Json",
"ext-mbstring": "to use Strings::lower() etc...",
"ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.0-dev"
}
},
"autoload": {
"classmap": [
"src/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause",
"GPL-2.0-only",
"GPL-3.0-only"
],
"authors": [
{
"name": "David Grudl",
"homepage": "https://davidgrudl.com"
},
{
"name": "Nette Community",
"homepage": "https://nette.org/contributors"
}
],
"description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.",
"homepage": "https://nette.org",
"keywords": [
"array",
"core",
"datetime",
"images",
"json",
"nette",
"paginator",
"password",
"slugify",
"string",
"unicode",
"utf-8",
"utility",
"validation"
],
"support": {
"issues": "https://github.com/nette/utils/issues",
"source": "https://github.com/nette/utils/tree/v4.0.4"
},
"time": "2024-01-17T16:50:36+00:00"
},
{
"name": "psr/event-dispatcher",
"version": "1.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/event-dispatcher.git",
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0",
"reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0",
"shasum": ""
},
"require": {
"php": ">=7.2.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Psr\\EventDispatcher\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "http://www.php-fig.org/"
}
],
"description": "Standard interfaces for event handling.",
"keywords": [
"events",
"psr",
"psr-14"
],
"support": {
"issues": "https://github.com/php-fig/event-dispatcher/issues",
"source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0"
},
"time": "2019-01-08T18:20:26+00:00"
},
{
"name": "symfony/deprecation-contracts",
"version": "v3.4.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/deprecation-contracts.git",
"reference": "7c3aff79d10325257a001fcf92d991f24fc967cf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf",
"reference": "7c3aff79d10325257a001fcf92d991f24fc967cf",
"shasum": ""
},
"require": {
"php": ">=8.1"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.4-dev"
},
"thanks": {
"name": "symfony/contracts",
"url": "https://github.com/symfony/contracts"
}
},
"autoload": {
"files": [
"function.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": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-05-23T14:45:45+00:00"
"time": "2017-10-29T19:29:55+00:00"
},
{
"name": "symfony/polyfill-ctype",
"version": "v1.29.0",
"version": "v1.11.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4"
"reference": "82ebae02209c21113908c229e9883c419720738a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4",
"reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/82ebae02209c21113908c229e9883c419720738a",
"reference": "82ebae02209c21113908c229e9883c419720738a",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"provide": {
"ext-ctype": "*"
"php": ">=5.3.3"
},
"suggest": {
"ext-ctype": "For best performance"
},
"type": "library",
"extra": {
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
"branch-alias": {
"dev-master": "1.11-dev"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"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"
},
{
"name": "Gert de Pagter",
"email": "BackEndTea@gmail.com"
}
],
"description": "Symfony polyfill for ctype functions",
@ -631,133 +187,41 @@
"polyfill",
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
},
{
"name": "symfony/polyfill-php80",
"version": "v1.29.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b",
"shasum": ""
},
"require": {
"php": ">=7.1"
},
"type": "library",
"extra": {
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php80\\": ""
},
"classmap": [
"Resources/stubs"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ion Bazan",
"email": "ion.bazan@gmail.com"
},
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-01-29T20:11:03+00:00"
"time": "2019-02-06T07:57:58+00:00"
},
{
"name": "symfony/yaml",
"version": "v7.0.3",
"version": "v4.3.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/yaml.git",
"reference": "2d4fca631c00700597e9442a0b2451ce234513d3"
"reference": "c60ecf5ba842324433b46f58dc7afc4487dbab99"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/yaml/zipball/2d4fca631c00700597e9442a0b2451ce234513d3",
"reference": "2d4fca631c00700597e9442a0b2451ce234513d3",
"url": "https://api.github.com/repos/symfony/yaml/zipball/c60ecf5ba842324433b46f58dc7afc4487dbab99",
"reference": "c60ecf5ba842324433b46f58dc7afc4487dbab99",
"shasum": ""
},
"require": {
"php": ">=8.2",
"symfony/polyfill-ctype": "^1.8"
"php": "^7.1.3",
"symfony/polyfill-ctype": "~1.8"
},
"conflict": {
"symfony/console": "<6.4"
"symfony/console": "<3.4"
},
"require-dev": {
"symfony/console": "^6.4|^7.0"
"symfony/console": "~3.4|~4.0"
},
"suggest": {
"symfony/console": "For validating YAML files using the lint command"
},
"bin": [
"Resources/bin/yaml-lint"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "4.3-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\Yaml\\": ""
@ -780,78 +244,49 @@
"homepage": "https://symfony.com/contributors"
}
],
"description": "Loads and dumps YAML files",
"description": "Symfony Yaml Component",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/yaml/tree/v7.0.3"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2024-01-23T15:02:46+00:00"
"time": "2019-04-06T14:04:46+00:00"
},
{
"name": "tildeteam/wiki",
"version": "2.0.8",
"name": "tildeverse/wiki",
"version": "dev-master",
"source": {
"type": "git",
"url": "https://tildegit.org/team/tildewiki",
"reference": "dcbb9740225768c74cfd0002a150549cd6df4bc4"
"url": "https://tildegit.org/ben/tildewiki",
"reference": "751eb64c383cb7c6ec643eaf683b88aa1de351ea"
},
"require": {
"mnapoli/front-yaml": "^2.0.0",
"php": "^7.4|^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5"
"erusev/parsedown-extra": "^0.7.1",
"mnapoli/front-yaml": "^1.6"
},
"type": "library",
"autoload": {
"psr-4": {
"tildeteam\\": "src/"
"Tildeverse\\Wiki\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"GPL-3.0-or-later"
"GPLv3"
],
"authors": [
{
"name": "Ben Harris",
"email": "ben@tilde.team",
"homepage": "https://tilde.team/~ben/",
"role": "Developer"
"email": "ben@tilde.team"
}
],
"description": "unified extensions for tilde wikis",
"homepage": "https://tildegit.org/team/tildewiki",
"keywords": [
"markdown",
"wiki"
],
"time": "2022-02-16T18:31:48+00:00"
"description": "parsedown extensions for tilde wikis",
"time": "2019-07-03T05:06:34+00:00"
}
],
"packages-dev": [],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": [],
"stability-flags": {
"tildeverse/wiki": 20
},
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
"ext-json": "*"
},
"platform-dev": [],
"plugin-api-version": "2.3.0"
"platform": [],
"platform-dev": []
}

View File

@ -1,65 +1,54 @@
#!/usr/bin/env python3
import base64
import json
from lxml import etree
import requests, json
import xml.etree.ElementTree as xml
WORK_DIR = "/var/www/tilde.chat"
r = requests.get("http://localhost:8081/stats")
r.raise_for_status()
out = {}
parser = etree.XMLParser(strip_cdata=False)
root = etree.parse("http://localhost:8081/stats", parser)
assert root.getroot().tag == "inspircdstats"
d = xml.fromstring(r.text)
assert d.tag == "inspircdstats"
with open(f"{WORK_DIR}/blacklist", "r") as f:
BLACKLIST = f.read().splitlines()
def unsanitize(node, default=""):
# workaround for weird behavior in insp's xml output
# https://github.com/inspircd/inspircd/blob/v3.7.0/src/modules/m_httpd_stats.cpp#L55
if node.text is None or node.text == "":
return default
elif str(etree.tostring(node)).startswith(f"b'<{node.tag}><![CDATA["):
missing_padding = len(node.text) % 4
if missing_padding:
v = node.text + "=" * (4 - missing_padding)
else:
v = node.text
try:
return base64.b64decode(v).decode("utf-8")
except:
return "failed to read topic as utf-8"
return node.text
def define(name, xps, vfilter=lambda x: x):
global out
out[name] = vfilter(d.findall(xps)[0].text)
out["usercount"] = int(root.find("./general/usercount").text)
out["channelcount"] = int(root.find("./general/channelcount").text)
define("usercount", "./general/usercount", int)
define("channelcount", "./general/channelcount", int)
schannels = d.findall("./channellist/channel")
out["channels"] = []
for c in root.findall("./channellist/channel"):
name = unsanitize(c.find("channelname"))
channels = []
for schannel in schannels:
channel = dict(
name=schannel.findall("channelname")[0].text,
usercount=int(schannel.findall("usercount")[0].text),
)
channel["topic"] = (
schannel.findall("./channeltopic/topictext")[0].text
if schannel.findall("./channeltopic/topictext")[0].text is not None
else "No topic set"
)
modes = c.find("./channelmodes").text
if (
# skip channels in the blacklist or with mode +s
name in BLACKLIST
or modes is None
or "s" in modes.split()[0]
"s" in schannel.findall("./channelmodes")[0].text.split()[0]
or channel["name"] in BLACKLIST
):
continue
out["channels"].append(
dict(
name=name,
topic=unsanitize(c.find("./channeltopic/topictext"), "no topic set"),
usercount=int(c.find("usercount").text),
webchatlink="https://tilde.chat/kiwi/" + name,
)
channel["webchatlink"] = "https://web.tilde.chat/?join=" + channel["name"].lstrip(
"#"
)
channels.append(channel)
out["channels"].sort(key=lambda x: x["name"].lower())
channels.sort(key=lambda x: x["name"].lower())
out["channels"] = channels
# print([x.text for x in d.findall("./channellist/channel/channeltopic/topictext")])
with open(f"{WORK_DIR}/stats.json", "w") as f:
json.dump(out, f)

View File

@ -14,15 +14,7 @@
<meta property="og:image" content="https://tilde.chat/apple-icon.png">
<meta property="og:site_name" content="tilde.chat">
<meta property="og:type" content="website">
<style>
/* offset #fragments */
:target:before {
content: "";
display: block;
height: 70px;
margin: -70px 0 0;
}
</style>
</head>
<body style="padding-top: 70px;">
<div class="container">

107
index.php
View File

@ -1,51 +1,80 @@
<?php include 'header.php'; ?>
<h1>tilde.chat <img src="/badges/badge.php" alt="tilde user badge"></h1>
<hr>
<h1>tilde.chat <img src="/badges/badge.php"></h1>
<hr>
<p>hey hi</p>
<p>tilde.chat is the irc network of the <a href="https://tildeverse.org">tildeverse</a>, an association of social unix servers built as an intentional community for teaching, learning, and sharing.</p>
<p>tilde.chat is a place for tilde-folk and friends to gather and communicate.</p>
<p>hey hi</p>
<p>tilde.chat is the irc network of the <a href="https://tildeverse.org">tildeverse</a>, an association of social unix servers built as an intentional community for teaching, learning, and sharing.</p>
<p>tilde.chat is meant to be a space for all tilde members to hang out, share, teach, and learn.</p>
<p><a rel="me" href="https://tilde.zone/@tildeverse">!toot goes here: mastodon</a></p>
<h3>connection info</h3>
<p>point your client to <a href="ircs://irc.tilde.chat:6697"><em>irc.</em>tilde.chat</a> on port 6697 with ssl/tls</p>
<!--
<p>feel free to contact a tilde.team admin (<?php
$members = json_decode(file_get_contents("https://tildeverse.org/members.json"))->members;
foreach ($members as $member)
if ($member->name == "tilde.team")
$team = $member;
$count = count($team->sysadmins);
foreach($team->sysadmins as $sysadmin) {
echo "<a href='{$sysadmin[1]}'>{$sysadmin[0]}</a>";
if ($count>1) {
echo ", ";
$count--;
}
}?>) for more info as we flesh out this site</p>
-->
<h3>connection info</h3>
<p>you can connect to <em>irc.</em>tilde.chat on port 6697 with ssl</p>
<p>irc.tilde.chat is a round-robin host that will return any of the <a href="wiki/?page=servers">available servers</a></p>
<p>
if you're getting a higher ping than you'd like, try one of the geo-round-robins:
<em>na</em>.tilde.chat, <em>eu</em>.tilde.chat, and <em>au</em>.tilde.chat on port 6697 with ssl/tls.
</p>
<p>plaintext <a href="irc://localhost:6667">on localhost port 6667</a> is available at a shell on <a href="wiki/servers">tildes that run chat nodes</a> (port 7766 on ~town)</p>
<p>if you don't have a client ready to go, try using our <a href="https://tilde.chat/kiwi/">kiwiirc webchat</a> or our <a href="https://tilde.chat/gamja/">gamja webchat</a>.</p>
<p>
you can also connect from any xmpp client with our <a href="https://biboumi.louiz.org">biboumi gateway</a>.
it runs on <a href="https://tilde.team/wiki/xmpp#biboumi">tilde.team</a>'s xmpp server.
channels can be joined with this room-format: <a href="xmpp:#helpdesk@biboumi.tilde.team?join">#helpdesk@biboumi.tilde.team</a>
<em>na</em>.tilde.chat, <em>eu</em>.tilde.chat, and <em>au</em>.tilde.chat on port 6697 with ssl.
</p>
<p>or localhost 6667 from a shell on any of the member tildes :) (port 7766 on ~town)</p>
<h3>how to irc?</h3>
<p>if you have never used irc before, you might find <a href="wiki/intro">our intro to irc guide</a> useful.
<h3>mumble server</h3>
<p>connect to mumble.tilde.chat on the default port using "tilde.chat" as the password and talk!</p>
<p>might not be anyone there. shout about it on irc first!</p>
<h3>channel novelties</h3>
<p>there are some fun things on tilde.chat run by <a href="wiki/bots">robots</a>, such as:<p>
<ul>
<li><p>in channels with <em>tooter</em> in them, <a rel="me" href="https://tilde.zone/@tildeverse">!toot goes here: mastodon</a></p></li>
<li><p><em>badger</em> is a bot that gives you badges for participating in channels it is in</p></li>
</ul>
<h3>member tildes</h3>
<ul>
<h3>mumble server</h3>
<p>we also have non-irc voice chat!</p>
<p>use a <a href="https://mumble.info">mumble client</a> to connect to tilde.chat on the default port using "tilde.chat" as the password and talk!</p>
<p>might not be anyone there. shout about it on irc first!</p>
<?php
foreach($members as $member) {
echo "\t\t<li><a href='{$member->link}'>{$member->name}</a> (sysadmin";
if (count($member->sysadmins) != 1) {
echo "s"; // plural
}
echo ": ";
$count = count($member->sysadmins);
foreach ($member->sysadmins as $sysadmin) {
echo "<a href='{$sysadmin[1]}'>{$sysadmin[0]}</a>";
if ($count > 1) {
echo ", ";
$count--;
}
}
echo ", channel: {$member->channel})</li>&nbsp;&nbsp;{$member->description}<br><br>\n";
}
?>
<hr>
<h3>rules/guidelines</h3>
<p>please see the <a href="wiki/etiquette">etiquette guide</a></p>
<p>chatting/using tilde.chat irc servers implies agreement with the <a href="https://tilde.wiki/code-of-conduct">code of conduct</a>. the <a href="https://tilde.town/wiki/conduct.html">tilde.town code of conduct</a> applies as well.</p>
<p>it is recommended that you read the guide and codes of conduct, and try to abide by them even if you disagree</p>
<ul>
<li><p>failing to do so may result in your removal from individual channels, or the whole tilde.chat network.</p></li>
<li><p>bad behaviour may, on rare occasions, also result in tilde admins reconsidering your membership.</p></li>
<li><p>warnings before removal are usually given but are not guaranteed.</p></li>
</ul>
<p>if you have anything that needs oper attention, please send a mail to opers at tilde dot chat, or ask in #helpdesk</p>
<p>incidents will be handled according to the CoC as well as by admins of your home tilde</p>
</ul>
<hr>
<!-- misc channel info -->
<h3><a href="/stats/">channel info and stats</a></h3>
<!-- closed. see: https://tilde.chat/discord/
<p>* = bridged to discord: tilde.chat private discord invites for tilde members <a href="/discord">here</a>. join and confirm that you're a tilde member to get access to the channels (including a private Discord channel for your tilde). bridging configuration can be adjusted per request.</p>
-->
<hr>
<h3>rules/guidelines</h3>
<p>please see the <a href="wiki/etiquette">etiquette guide</a></p>
<p>chatting/using tilde.chat irc servers implies agreement with the <a href="https://tilde.wiki/code-of-conduct">code of conduct</a>. the <a href="https://tilde.town/wiki/conduct.html">tilde.town code of conduct</a> applies as well.</p>
<p>if you have anything that needs oper attention, please send a mail to opers at tilde dot chat.</p>
<p>incidents will be handled according to the CoC as well as by admins of your home tilde</p>
<?php include 'footer.php'; ?>

View File

@ -1,33 +0,0 @@
<?php
header("Content-Type: text/plain");
$node = $_GET["node"] ?? "hub";
echo shell_exec("figlet -w120 -f slant -- " . escapeshellarg($node) . ".tilde.chat");
echo "welcome to tilde.chat\n";
echo "this is the irc network for the tildeverse (https://tildeverse.org)\n";
echo "\n";
echo "check out the appropriate channel for your tilde:\n";
echo "\n";
$members = json_decode(file_get_contents("https://tildeverse.org/members.json", false, stream_context_create(['socket' => ['bindto' => '0:0']])))->members;
foreach ($members as $member) {
echo " - " . str_pad($member->name, 17) . "~> " . $member->channel . "\n";
}
echo "\n";
echo "the main lobby channel is #meta. you must log in with nickserv to speak there.\n";
echo "to get registered, run /quote ns help register or read our wiki: https://tilde.chat/wiki/nicks\n";
echo "check out https://tilde.chat/stats/ or run /list to find other channels\n";
echo "/join #helpdesk if you need assistance\n";
echo "\n";
echo "check out #tilderadio for our internet radio station!\n";
echo "\n";
echo "please see our etiquette guidelines: https://tilde.chat/wiki/etiquette\n";
echo "\n";
echo " ~~ be excellent to each other ~~";

View File

@ -1,30 +1,22 @@
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">~chat</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="/wiki/"><i class="fa fa-edit"></i> wiki</a></li>
<li><a href="https://quotes.tilde.chat/"><i class="fa fa-comment"></i> qdb</a></li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">
<i class="fa fa-comments-o"></i> webchat <span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li><a href="/kiwi/">kiwiirc</a></li>
<li><a href="/gamja/">gamja</a></li>
</ul>
</li>
<li><a href="/stats/"><i class="fa fa-bar-chart"></i> channels</a></li>
<li><a href="/badges/"><i class="fa fa-shield"></i> badges</a></li>
</ul>
</div>
</div>
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">~chat</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li><a href="/wiki/"><i class="fa fa-edit"></i> wiki</a></li>
<li><a href="https://quotes.tilde.chat/"><i class="fa fa-comment"></i> qdb</a></li>
<li><a href="https://web.tilde.chat/"><i class="fa fa-comments-o"></i> webchat</a></li>
<li><a href="/stats/"><i class="fa fa-bar-chart"></i> stats</a></li>
<li><a href="/badges/"><i class="fa fa-shield"></i> badges</a></li>
</ul>
</div>
</div>
</nav>

View File

@ -1,8 +1,7 @@
welcome!
hey hi
please see
https://tilde.chat/wiki/etiquette
https://tilde.chat/wiki/?page=etiquette
for more information on the rules for tilde.chat

View File

@ -2,28 +2,13 @@
$title="stats page";
$desc="stats about tilde.chat and its channels";
$stats = json_decode(file_get_contents("../stats.json"));
$members = json_decode(file_get_contents("https://tildeverse.org/members.json", false, stream_context_create(['socket' => ['bindto' => '0:0']])))->members;
include __DIR__."/../header.php";
?>
<h1>channels</h1>
<h3><a href="https://tildeverse.org/members/">member tildes</a></h3>
<?php foreach($members as $member) {
$chans = explode(", ", $member->channel); ?>
<div class="btn-group">
<a class="btn btn-default" href="<?=htmlspecialchars($member->link)?>"><?=htmlspecialchars($member->name)?></a>
<?php foreach ($chans as $chan) { ?>
<a class="btn btn-primary" href="https://tilde.chat/kiwi/<?=htmlspecialchars($chan)?>"><?=htmlspecialchars($chan)?></a>
<?php } ?>
</div>
<?php } ?>
<h1>stats</h1>
<hr>
<h3>full channel stats</h3>
<p>there are <?=htmlspecialchars($stats->usercount)?> users across <?=htmlspecialchars($stats->channelcount)?> channels.</p>
<p>if the channel is set with <a href="https://docs.inspircd.org/3/modes/#channel-modes">chanmode +s</a> it will be omitted from this list.</p>
<p>the table is sortable by clicking on the column headers</p>
<p>there are <?=$stats->usercount?> users across <?=$stats->channelcount?> channels.</p>
<p>if the channel is set with <a href="https://wiki.inspircd.org/Channel_Modes">chanmode +s</a> it will be omitted from this list.</p>
<div class="table-responsive">
<table class="table table-striped table-bordered table-hover">
<thead>
@ -37,9 +22,9 @@ include __DIR__."/../header.php";
<tbody data-link="row" class="rowlink">
<?php foreach($stats->channels as $channel): ?>
<tr>
<td><a href="<?=htmlspecialchars($channel->webchatlink)?>"><?=htmlspecialchars($channel->name)?></a></td>
<td><?=htmlspecialchars($channel->usercount)?></td>
<td style="word-wrap: break-word; white-space: pre-wrap; max-width:700px"><?=htmlspecialchars($channel->topic)?></td>
<td><a href="<?=$channel->webchatlink?>"><?=$channel->name?></a></td>
<td><?=$channel->usercount?></td>
<td style="word-wrap: break-word; white-space: pre-wrap; max-width:700px"><?=$channel->topic?></td>
</tr>
<?php endforeach; ?>
</tbody>

View File

@ -8,8 +8,7 @@ to contribute to the wiki:
* clone the repo to your local machine (or your public_html folder on the tilde.team box for live testing)
```sh
git clone git@tildegit.org:tildeverse/tilde.chat
cd tilde.chat
git clone git@tilde.chat:tildeverse/tilde.chat
```
* create a new branch for your page
@ -19,23 +18,9 @@ git checkout -b my-new-page
* if you want to add a new page, copy `template.md` into your new page!
```sh
cp wiki/template.md wiki/my-new-page.md
cp template.md my-new-page.md
```
* test your changes locally
```sh
composer install
php -S localhost:9000
```
this will run your site at http://localhost:9000/
if you are running the development server on your tilde account, you
will not be able to access it on (hostname):9000 because it only runs
on localhost, but you can create a tunnel with
ssh -L 9000:localhost:9000
to access from your localhost:9000 address
* edit as needed!
* commit your changes and [create a pull request](https://tildegit.org/tildeverse/tilde.chat/pulls) :)
@ -49,4 +34,4 @@ git push origin my-new-page # this should match the branch name you created earl
thanks!~
ps. if you have any questions, ask on irc! (try #helpdesk or #meta)
ps. if you have any questions, ask on irc! (preferably in #meta)

View File

@ -1,6 +1,7 @@
<?php
require __DIR__.'/../vendor/autoload.php';
use tildeteam\wiki;
use Tildeverse\Wiki\Parser;
$additional_head = "
<style>
@ -15,19 +16,9 @@ $additional_head = "
<meta property='og:site_name' content='tilde.chat wiki'>
";
$parser = wiki::factory(true);
$parser = Parser::factory();
if(isset($_GET["page"])) {
$page=$_GET["page"];
} else {
$page="";
}
if(preg_match("/[^a-z0-9_-]/", $page)) {
$page="";
}
if ($page=="" || !file_exists("pages/$page.md")) {
if (!isset($_GET["page"]) || !file_exists("pages/{$_GET['page']}.md")) {
$title = "tilde.chat~wiki";
$additional_head .= "
@ -36,20 +27,6 @@ if ($page=="" || !file_exists("pages/$page.md")) {
<meta property='og:description' content='tilde.chat wiki'>
";
include __DIR__.'/../header.php';
$pages = [];
foreach (glob("pages/*.md") as $page) {
$yaml = $parser->parse(file_get_contents($page))->getYAML();
if (!$yaml["published"]) continue;
$pages[] = [
"title" => $yaml["title"],