source "build.onyx"
}
wasmer {
- target "wasmer.wasm"
+ target "site.wasm"
runtime "wasi"
source "build.onyx"
define "WASIX" "CGI_MODE"
@route.{.GET, "/docs/getting_started"}
(req: &Req, res: &Res) => res->render("pages/docs/getting_started", null);
+@route.{.GET, "/docs/guides"}
+(req: &Req, res: &Res) => res->render("pages/docs/guides", null);
+
+@route.{.GET, "/docs/guides/http-server"}
+(req: &Req, res: &Res) => res->render("pages/docs/guide_http_server", null);
+
+@route.{.GET, "/docs/packages"}
+(req: &Req, res: &Res) => res->render("pages/docs/package", null);
+
+@route.{.GET, "/docs/packages/list"}
+(req: &Req, res: &Res) {
+ res->render("pages/docs/package_list", &.{
+ core_packages = core_packages,
+ third_party_packages = third_party_packages
+ });
+}
+
+
@route.{.GET, "/robots.txt"}
(req: &Req, res: &Res) {
res->file("./www/static/robots.txt");
main :: () {
default_log_level(.Error);
+ load_library_list();
reg = otmp.registry();
reg->load_directory("./www/templates", ".html");
logger := http.server.logger(style=.V2);
pipes->pipe(&logger);
- app := http.server.tcp(pipes, .{ thread_count = 8 });
+ app := http.server.tcp(pipes, .{ thread_count = 4 });
port := conv.parse_int(os.env("SERVER_PORT") ?? "8000");
}
+Package :: struct {
+ url, name, description: str;
+}
+
+#local {
+ core_packages: [] Package;
+ third_party_packages: [] Package;
+}
+
+load_library_list :: () {
+ os.get_contents("www/packages/core_packages.json")
+ |> json.decode_into(&core_packages);
+
+ slice.sort(core_packages, (a, b) => string.compare(a.name, b.name));
+
+ os.get_contents("www/packages/third_party_packages.json")
+ |> json.decode_into(&third_party_packages);
+
+ slice.sort(third_party_packages, (a, b) => string.compare(a.name, b.name));
+}
--- /dev/null
+[
+ {
+ "name": "http-server",
+ "url": "https://github.com/onyx-lang/pkg-http-server",
+ "description": ""
+ },
+ {
+ "name": "raylib",
+ "url": "https://github.com/onyx-lang/pkg-raylib",
+ "description": ""
+ },
+ {
+ "name": "stb_image",
+ "url": "https://github.com/onyx-lang/pkg-stb_image",
+ "description": ""
+ },
+ {
+ "name": "stb_truetype",
+ "url": "https://github.com/onyx-lang/pkg-stb_truetype",
+ "description": ""
+ },
+ {
+ "name": "perlin",
+ "url": "https://github.com/onyx-lang/pkg-perlin",
+ "description": ""
+ },
+ {
+ "name": "postgres",
+ "url": "https://github.com/onyx-lang/pkg-postgres",
+ "description": ""
+ },
+ {
+ "name": "postgres-orm",
+ "url": "https://github.com/onyx-lang/pkg-postgres-orm",
+ "description": ""
+ },
+ {
+ "name": "qoi",
+ "url": "https://github.com/onyx-lang/pkg-qoi",
+ "description": ""
+ },
+ {
+ "name": "http-client",
+ "url": "https://github.com/onyx-lang/pkg-http-client",
+ "description": ""
+ },
+ {
+ "name": "openssl",
+ "url": "https://github.com/onyx-lang/pkg-openssl",
+ "description": ""
+ },
+ {
+ "name": "glfw3",
+ "url": "https://github.com/onyx-lang/pkg-glfw3",
+ "description": ""
+ },
+ {
+ "name": "openal",
+ "url": "https://github.com/onyx-lang/pkg-openal",
+ "description": ""
+ },
+ {
+ "name": "opengles",
+ "url": "https://github.com/onyx-lang/pkg-opengles",
+ "description": ""
+ },
+ {
+ "name": "opencl",
+ "url": "https://github.com/onyx-lang/pkg-opencl",
+ "description": ""
+ },
+ {
+ "name": "ncurses",
+ "url": "https://github.com/onyx-lang/pkg-ncurses",
+ "description": ""
+ },
+ {
+ "name": "json-rpc",
+ "url": "https://github.com/onyx-lang/pkg-json-rpc",
+ "description": ""
+ },
+ {
+ "name": "otmp",
+ "url": "https://github.com/onyx-lang/pkg-otmp",
+ "description": ""
+ }
+]
a {
color: var(--text);
- text-decoration: none;
+ text-decoration: underline;
}
a.link-button {
p code {
border-radius: 4px;
padding: 2px;
+ border: 1px solid var(--accent);
+ background: var(--accent-background);
}
@font-face {
}
main blockquote {
- border-left: 4px solid var(--dark-background-color);
- background-color: var(--light-background-color);
- margin-top: 12px;
+ border-left: 4px solid var(--accent);
+ background-color: var(--accent-background);
+ margin-top: 16px;
padding: 8px;
}
padding-bottom: 32px;
}
+table {
+ border-radius: 8px;
+ border: 1px solid var(--accent);
+ width: 100%;
+ background: linear-gradient(135deg, #000, var(--accent-background));
+ box-shadow: 0px 7px 41px 30px rgba(200, 200, 230, 0.2);
+ margin-top: 24px !important;
+}
+
+table tr:nth-child(2n) {
+ background: var(--accent-background);
+ border: none;
+}
+
+table th {
+ font-size: 1.1rem;
+ border: none;
+ padding: 8px;
+}
+
+table td {
+ padding: 8px;
+ border: none;
+}
+
.scrollport > div {
min-width: 1000px;
}
<div class="container">
<h2>Learn</h2>
<p>
- Learn the core ideas behind programming in Onyx.
+ Learn the core ideas behind programming in Onyx, and how to use developer tooling.
</p>
<p>
+ <a class="link-button" href="/docs/guides">Guides</a>
+ <a class="link-button" href="/docs/packages">Package Manager</a>
<a class="link-button" href="https://docs.onyxlang.io/book">Language Reference</a>
</p>
</div>
</p>
<p>
<a class="link-button" href="https://docs.onyxlang.io/packages/core">Core packages</a>
+ <a class="link-button" href="/docs/packages/list">External packages</a>
</p>
</div>
<div class="container header">
<h1>Setting Up Your Environment for Onyx</h1>
+ <div>⇦ <a href="/docs">Back to the docs</a></div>
<p>The following sections will help set up an environment for you to program Onyx effectively.</p>
Getting Started
{{ endblock }}
+{{ let navbar_page = "docs" }}
+
{{ block "page_content" }}
<div class="container header">
<h1>Getting Started</h1>
+ <div>⇦ <a href="/docs">Back to the docs</a></div>
</div>
<div class="container">
{{ endblock }}
-{{ extends "pages/normal_page" }}
\ No newline at end of file
+{{ extends "pages/normal_page" }}
--- /dev/null
+{{block "title"}}HTTP Server in Onyx{{endblock}}
+
+{{ let navbar_page = "docs" }}
+
+{{ block "page_content" }}
+
+<div class="container header">
+ <h1>Guide - HTTP Server</h1>
+ <div>⇦ <a href="/docs">Back to the docs</a></div>
+
+ <p>
+ This guide walks you through all steps of setting up an HTTP server Onyx,
+ writing some routes on it, and then deploying it to Wasmer Edge or Spin
+ using WCGI.
+ </p>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2>Setting up the Project</h2>
+ </div>
+
+ <p>
+ First, you need create a new folder for this project, and initialize that folder as an Onyx project.
+ See the <a href="/docs/packages">package manager</a> explainer for more details.
+ </p>
+
+ <pre class="hljs"><code class="language-sh">mkdir my-http-server
+cd my-http-server
+onyx package init</code></pre>
+
+ <p>
+ Then you need to add the <a href="https://github.com/onyx-lang/pkg-http-server">HTTP server</a> package to this project, and synchronize
+ changes to install the package.
+ </p>
+ <pre class="hljs"><code class="language-sh"># Add the package
+onyx package add http-server
+# Synchronize changes
+onyx package sync</code></pre>
+
+ <p>
+ Once the package is successfully fetched, you can start writing some code!
+ </p>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2>Writing the code</h2>
+ </div>
+
+ <p>
+ You can now write the code for your server.
+ Begin by creating a <code>main.onyx</code> file that will house your code.
+ In this file, you first need to load your packages and use <code>http</code> package.
+ </p>
+
+ <pre class="hljs"><code class="language-onyx">#load "./lib/packages"
+
+// Include everything from the core library.
+use core {*}
+
+// Include the http package, and specifically use some common symbols.
+use http
+use http.server { Request, Response, route }</code></pre>
+
+ <p>
+ Now you write a simple <code>main</code> function that will create a TCP HTTP server,
+ with one route for the getting <code>"/"</code> endpoint.
+ </p>
+
+ <pre class="hljs"><code class="language-onyx">main :: () {
+ // Create a router that will route the traffic.
+ router := http.server.router();
+
+ // Register a handler for 'GET /'.
+ router->get("/", (req: &Request, res: &Response) {
+ // Respond with HTML
+ res->html("<h1>HTTP Server in Onyx!</h1>");
+
+ // Set status to 200
+ res->status(200);
+
+ // Mark the response as completed
+ res->end();
+ });
+
+
+ // Create a TCP server out of your router.
+ app := http.server.tcp(&router);
+
+ // Serve on port 8000.
+ app->serve(8000);
+}</code></pre>
+
+ <p>
+ That is everything you need to create a simple HTTP server that will respond to a <code>GET</code>
+ request on <code>/</code> with <code>"<h1>HTTP Server in Onyx!<h1>"</code>.
+ </p>
+
+ <p>
+ You could define more routes in this way, using <code>router->get</code> or <code>router->post</code>,
+ but there is a better way described shortly.
+ </p>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2>Running your server</h2>
+ </div>
+
+ <p>
+ To run your server, you can either use the builtin Onyx runtime, or Wasmer with WASIX support.
+ These are the only two options for now, as there no other runtimes with fully networking support.
+ </p>
+
+ <p>
+ In a later section, you can make this web server use WCGI, so it can be deployed anywhere.
+ </p>
+
+ <p>
+ To run using the Onyx runtime (if it is installed), simply run the following command.
+ </p>
+ <pre class="hljs"><code class="language-sh">$ onyx run main.onyx
+[Info][Http-Server] Serving on port 8000</code></pre>
+
+ <p>
+ To run using Wasmer and WASIX, you need to compile your server to a WASM binary, then
+ run it with <code>wasmer</code>.
+ </p>
+ <pre class="hljs"><code class="language-sh">$ # Adding '-r wasi' to target WASI, and '-DWASIX' to add WASIX extensions.
+$ onyx build main.onyx -r wasi -DWASIX
+$ wasmer run --net out.wasm
+[Info][Http-Server] Serving on port 8000</code></pre>
+
+ <p>
+ To test your server, you can visit <a href="http://localhost:8000">localhost:8000</a> in your browser.
+ Or, make a request using cURL.
+ </p>
+ <pre class="hljs"><code class="language-sh">$ curl http://localhost:8000
+<h1>HTTP Server in Onyx!<h1>
+</code></pre>
+
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2>Rewriting our code</h2>
+ </div>
+
+ <p>
+ The server you have is perfectly functional, and you could keep adding more routes to it
+ in the same way as above. However, with all of this code in <code>main</code>, it doesn't
+ scale terribly well.
+ </p>
+
+ <p>
+ An alternative way to register routes is to use Onyx's <em>procedure tags</em> feature
+ to label certain procedures as request handlers. Then, the router can automatically find
+ them and register them!
+ </p>
+
+ <p>
+ Here is how this works. First, you move the request handler from before into a new
+ global procedure, and add a <code>#tag</code> to it.
+ </p>
+
+ <pre class="hljs"><code class="language-onyx">// Tag the procedure with a `route` structure, so it can be found by the router.
+#tag route.{ .GET, "/" }
+index :: (req: &Request, res: &Response) {
+ // Respond with HTML
+ res->html("<h1>HTTP Server in Onyx!</h1>");
+
+ // Set status to 200
+ res->status(200);
+
+ // Mark the response as completed
+ res->end();
+}</code></pre>
+
+ <p>
+ Now in <code>main</code>, you can remove the <code>router->get()</code> call and replace it with <code>router->collect_routes()</code>.
+ This procedure will find all <code>route</code> tags in all packages in the code base.
+ </p>
+
+ <pre class="hljs"><code class="language-onyx">main :: () {
+ // Create a router that will route the traffic.
+ router := http.server.router();
+
+ // Collect routes from all packages.
+ router->collect_routes();
+
+ // Create a TCP server out of our router.
+ app := http.server.tcp(&router);
+
+ // Serve on port 8000.
+ app->serve(8000);
+}</code></pre>
+
+ <p>
+ You can test the server in the same way as before.
+ </p>
+ <pre class="hljs"><code class="language-sh">$ onyx run main.onyx
+[Info][Http-Server] Serving on port 8000</code></pre>
+ <pre class="hljs"><code class="language-sh">$ curl http://localhost:8000
+<h1>HTTP Server in Onyx!<h1></code></pre>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2>Deploying to Wasmer Edge</h2>
+ </div>
+
+ <p>
+ To deploy to Wasmer Edge, you need to first convert the code to use
+ the Common Gateway Interface (CGI) protocol instead of being a TCP server.
+ </p>
+
+ <p>
+ Simply, replace the <code>http.server.tcp</code> call with <code>http.server.cgi</code>.
+ </p>
+ <pre class="hljs"><code class="language-onyx">main :: () {
+ // Create a router that will route the traffic.
+ router := http.server.router();
+
+ // Collect routes from all packages.
+ router->collect_routes();
+
+ // Respond using the CGI protocol
+ http.server.cgi(&router);
+}</code></pre>
+
+ <p>
+ Then compile the code to a WebAssembly module targeting the WASI runtime.
+ </p>
+ <pre class="hljs"><code class="language-sh">$ onyx build main.onyx -r wasi -o my-http-server.wasm </code></pre>
+
+ <p>
+ To deploy to <strong>Wasmer Edge</strong>, create a <code>wasmer.toml</code> file that contains the following.
+ Replace <code><your-namespace></code> and <code><your-package-name></code> with your details.
+ </p>
+ <pre class="hljs"><code>[package]
+name = "<your-namespace>/<your-package-name>"
+version = "0.1.0"
+description = "My first HTTP server"
+license = "MIT"
+
+[[module]]
+name = "server"
+source = "my-http-server.wasm"
+abi = "wasi"
+
+[[command]]
+name = "server"
+module = "server"
+runner = "https://webc.org/runner/wcgi"
+
+[command.annotations.wasi]
+env = ["SCRIPT_NAME=rust_wcgi"]
+
+[command.annotations.wcgi]
+dialect = "rfc-3875"</code></pre>
+
+ <p>
+ Also, create an <code>app.yaml</code> file with the following contents.
+ </p>
+ <pre class="hljs"><code>---
+kind: wasmer.io/App.v0
+name: <your-app-name>
+package: <your-namespace>/<your-package-name></code></pre>
+
+ <p>
+ Then use Wasmer CLI to deploy it.
+ </p>
+
+ <pre class="hljs"><code class="language-sh">$ wasmer deploy</code></pre>
+
+ <p>
+ Follow the instructions from the Wasmer to test your deployment.
+ </p>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2>Next Steps</h2>
+ </div>
+
+ <p>
+ If you want to keep building up your HTTP server, you can look at more examples in <a href="https://onyxlang.io/onyx-lang/pkg-http-server">the HTTP Server package</a>.
+ </p>
+</div>
+
+
+{{ endblock }}
+
+{{ extends "pages/normal_page" }}
--- /dev/null
+{{block "title"}}Onyx Guides{{endblock}}
+
+{{ let navbar_page = "docs" }}
+
+{{ block "page_content" }}
+
+<div class="container header">
+ <h1>Guides</h1>
+ <div>⇦ <a href="/docs">Back to the docs</a></div>
+
+ <p>
+ Here is a small list of guides for getting started with common types of Onyx projects.
+ </p>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2><a href="/docs/guides/http-server">Setting Up an HTTP Server</a></h2>
+ </div>
+
+ <p>
+ Get started making an HTTP Server, entirely in Onyx.
+ This guide also descibes how to deploy your server to Wasmer Edge.
+ </p>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2><a href="/docs/guides/raylib">Using Raylib</a></h2>
+ </div>
+
+ <p>
+ Get started making games and graphical applications using the popular open source <a href="https://raylib.com">Raylib</a> library.
+ </p>
+</div>
+
+{{ endblock }}
+
+{{ extends "pages/normal_page" }}
<div class="container header">
<h1>Installing Onyx</h1>
+ <div>⇦ <a href="/docs">Back to the docs</a></div>
<p>
<a class="link-button" href="#online">Online</a>
<a class="link-button" href="#linux-macos">Linux</a>
--- /dev/null
+{{block "title"}}Onyx Package Manager{{endblock}}
+
+{{ let navbar_page = "docs" }}
+
+{{ block "page_content" }}
+
+<div class="container header">
+ <h1>Onyx Package Manager</h1>
+ <div>⇦ <a href="/docs">Back to the docs</a></div>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2>Philosophy</h2>
+ </div>
+
+ <p>
+ The Onyx package manager is intentionally very simple.
+ Onyx does not have a central package repository like NPM, PyPI, or Cargo.
+ Instead Onyx uses a <em>decentralized</em> approach, that follows this simple rule.
+ </p>
+
+ <blockquote>
+ Every package is a Git repository, with a file called <code>module.onyx</code> that is responsible for
+ including all other files in the package.
+ </blockquote>
+
+ <p>
+ The job of the package manager is to simply clone each of these Git repositories into a known structure,
+ and build a file for you to include in your project that loads all of your packages.
+ </p>
+
+ <p>
+ The package manager uses Git's tags feature to store version numbers.
+ This way the package manager can clone exactly one tag, at one commit, to avoid downloading all history of the package,
+ when all you want is a single version.
+ </p>
+
+ <p>
+ When you publish a package, using <code>onyx package publish</code> it simply increments the version number in the package file,
+ commits that change, creates a new tag at that commit, and pushes all changes and tags to the Git server.
+ When someone else runs <code>onyx package update</code>, the new version will be found and updated to.
+ </p>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2>Basic Usage</h2>
+ </div>
+
+ <p>
+ To use Onyx's package manager, you must be in an Onyx project.
+ An Onyx project is simply a directory with a file named <code>onyx-pkg.kdl</code>.
+ </p>
+
+ <p>
+ To create a new project in a directory, you can use the following command, and answer the prompts (or leave any them blank).
+ </p>
+ <pre class="hljs"><code class="language-sh">$ onyx package init
+Creating new project manifest in ./onyx-pkg.kdl.
+
+Package name: example-project
+Package description: A simple example project
+Package url: https://github.com/...
+Package author: Brendan Hansen
+Package version (0.0.1):</code></pre>
+
+ <p>Once your project is created, you can add packages by running <code>onyx package add ...</code>
+ <pre class="hljs"><code class="language-sh">$ onyx package add http-server
+$ # Or
+$ onyx package add https://github.com/onyx-lang/pkg-http-server</code></pre>
+
+ <p>
+ If you want to specify a particular version of a package, you can add the version number as another argument to the command.
+ </p>
+ <pre class="hljs"><code class="language-sh">$ # Specify version 0.1.2
+$ onyx package add http-server 0.1.2 </code></pre>
+
+ <p>
+ For the sake of convience, the package manager maintains a list of string templates to try to resolve where your package comes from.
+ Currently by default, there is only one, <code>https://github.com/onyx-lang/pkg-X</code>.
+ This means that when you try to add <code>http-server</code>, it will actually end up using <code>https://github.com/onyx-lang/pkg-http-server</code>.
+ If you want, you can change this list of string templates at the top of <code>ONYX_PATH/tools/onyx-pkg.onyx</code>.
+ </p>
+
+ <p>
+ You will notice that no files were downloaded and nothing has change in your directory.
+ This is because adding a package simply adds it to the list of dependencies in your <code>onyx-pkg.kdl</code>
+ It <strong>does not</strong> synchronize all of your packages.
+ </p>
+
+ <p>
+ To do that, simply run <code>onyx package sync</code>.
+ </p>
+ <pre class="hljs"><code class="language-sh">$ onyx package sync
+ Fetch http://github.com/onyx-lang/pkg-http-server 0.2.24</code></pre>
+
+ <p>
+ This downloads all new packages, upgrades exist packages, builds <a href="#">native libraries</a>, and creates a new
+ package file to include.
+ </p>
+
+ <p>
+ Once all packages are synchroized, you can use them in your project but simplying including the <code>package.onyx</code>
+ file automatically created. By default this file lives at <code>lib/packages.onyx</code> in your project.
+ </p>
+
+ <p>
+ Here is a simple example of using the <code>http-server</code> package in a project.
+ </p>
+ <pre class="hljs"><code class="language-onyx">// main.onyx
+
+#load "./lib/packages" // <--- Have to include the packages file!
+
+use core
+use http
+
+main :: () {
+ router := http.server.router();
+ router->get("/", (req, res) => {
+ res->html("<h1>Simple server is working!</h1>");
+ res->status(200);
+ res->end();
+ });
+
+ app := http.server.tcp(&router);
+ app->serve(8000);
+}</code></pre>
+
+ <p>
+ Once all of this is setup, your workflow will likely just look like <code>onyx pacakge update</code>, then <code> onyx package sync</code>,
+ with a bit of <code>onyx package add ...</code> sprinkled in there.
+ </p>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2>Creating a Package</h2>
+ </div>
+
+ <p>
+ Creating a new package for Onyx is incredibly simple.
+ There just three things a project needs to become a package.
+ <ol>
+ <li>Be a public Git repository</li>
+ <li>Have an <code>onyx-pkg.kdl</code> file</li>
+ <li>Have a <code>module.onyx</code> file</li>
+ </ol>
+ </p>
+
+ <p>
+ Hosting a package on GitHub, GitLab, or any Git server is very simple if you are familiar with Git.
+ Just make sure everyone that needs to access the package has pull access to the repository.
+ </p>
+
+ <p>
+ Every Onyx project already has an <code>onyx-pkg.kdl</code> file.
+ Ensure the package section has correct information about your package, and you should be good to go there.
+ See the <a href="#">guide</a> on creating a native library for how to set that up in your project.
+ </p>
+
+ <p>
+ Finally, you need a <code>module.onyx</code> file.
+ This file simply needs to include all other source files for the package.
+ In a particularly small package, all of the code might go <em>right inside</em> of <code>module.onyx</code>.
+ </p>
+
+ <p>
+ A typical <code>module.onyx</code> looks like this.
+ </p>
+ <pre class="hljs"><code class="language-onyx">// module.onyx
+
+package package_name_here
+
+#load_all "./src"</code></pre>
+
+ <p>
+ This file simply includes everything inside of the <code>src</code> folder.
+ If needed you can conditionally load source files, depending on your package's needs.
+ </p>
+
+ <p>
+ When your package is ready for a release, you can simply run <code>onyx package publish</code>.
+ This bumps the version in <code>onyx-pkg.kdl</code>, creates a new commit, tags that commit with the new version,
+ then pushes all of the changes to the Git server, assuming you have push access.
+ </p>
+ <pre class="hljs"><code class="language-shell">$ onyx package publish
+ Publishing Creating new published version
+ Published Successfully published new version.
+</div>
+
+{{ endblock }}
+
+{{ extends "pages/normal_page" }}
--- /dev/null
+{{block "title"}}Onyx Package Manager{{endblock}}
+
+{{ let navbar_page = "docs" }}
+
+{{ block "page_content" }}
+
+<div class="container header">
+ <h1>Package Listing</h1>
+ <div>⇦ <a href="/docs">Back to the docs</a></div>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2>First-Party Packages</h2>
+ </div>
+
+ <p>
+ These are official packages hosted on the <a href="https://github.com/onyx-lang">onyx-lang</a> GitHub account.
+ </p>
+
+ <table cellspacing=0 cellpadding=0>
+ <colgroup>
+ <col style="width: 30%">
+ <col style="width: 70%">
+ </colgroup>
+ <thead>
+ <tr>
+ <th>Package</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{ foreach $p in core_packages }}
+ <tr>
+ <td style="text-align: center"><a href="{% p.url %}">{% p.name %}</a></td>
+ <td>{% p.description %}</td>
+ </tr>
+ {{ endforeach }}
+ </tbody>
+ </table>
+</div>
+
+<div class="container">
+ <div class="title">
+ <h2>Third-Party Packages</h2>
+ </div>
+
+ <table cellspacing=0 cellpadding=0>
+ <colgroup>
+ <col style="width: 30%">
+ <col style="width: 70%">
+ </colgroup>
+ <thead>
+ <tr>
+ <th>Package</th>
+ <th>Description</th>
+ </tr>
+ </thead>
+ <tbody>
+ {{ let had_packages = 0 }}
+ {{ foreach $p in third_party_packages }}
+ <tr>
+ <td style="text-align: center"><a href="{% p.url %}">{% p.name %}</a></td>
+ <td>{% p.description %}</td>
+ </tr>
+ {{ let had_packages = 1 }}
+ {{ endforeach }}
+ {{ if had_packages == 0 }}
+ <tr>
+ <td colspan="2" style="text-align: center"><em>There are currently no third-party packages.</em></td>
+ </tr>
+ <tr>
+ <td colspan="2" style="text-align: center"><em>Create your own package and email <a href="mailto:me@brendanfh.com">me@brendanfh.com</a> to have it added.</em></td>
+ </tr>
+ {{ endif }}
+ </tbody>
+ </table>
+</div>
+
+{{ endblock }}
+
+{{ extends "pages/normal_page" }}
<div class="container header">
<div style="height: 20rem; display: flex; flex-direction: column; place-content: center;">
+ <svg viewBox="0 0 16 16" version="1.1" alt="Onyx Logo">
+ {% partial "partials/logo_svg" %}
+ </svg>
+
<div style="text-align: center;">
<h1>The <b>Onyx</b> Programming Language</h1>
</div>