diff --git a/README.md b/README.md
index d9bfd3b..ef44260 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,9 @@
-# website
+# Vegvisir Website
+Source code for the [Vegvisir website](https://vegvisir.vlw.se). The website is build from the ground up using the [Vegvisir](https://codeberg.org/vegvisir/vegvisir) web framework to highlight the framework's features.
+
+# Installation
+
+To run this website locally, follow the [installation instructions for the Vegvisir framework](https://vegvisir.vlw.se/docs/installation). After that, all you have to do is clone this repo and point Vegvisir to the cloned folder.
+
+No additional steps are required!
\ No newline at end of file
diff --git a/modules/docs/contribute.php b/modules/docs/contribute.php
new file mode 100644
index 0000000..355e265
--- /dev/null
+++ b/modules/docs/contribute.php
@@ -0,0 +1,12 @@
+
+ Have you found a problem om this page? Would you like to help make this little project a bit better?Contribute? 💕
+
!REF#
";
+ }
+
+ // Use enum name in lowercase as highlight.js lanuage definer
+ $output = "";
+ $output .= htmlspecialchars(file_get_contents($path));
+ $output .= "
";
+
+ return $output;
+ }
+ }
+
+?>
+
+
\ No newline at end of file
diff --git a/modules/snippet/snippet.js b/modules/snippet/snippet.js
new file mode 100644
index 0000000..0eefd2a
--- /dev/null
+++ b/modules/snippet/snippet.js
@@ -0,0 +1,19 @@
+import hljs from "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/es/highlight.min.js";
+
+import php from "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/es/languages/php.min.js";
+import css from "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/es/languages/css.min.js";
+import plaintext from "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/es/languages/plaintext.min.js";
+import javascript from "https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.10.0/es/languages/javascript.min.js";
+
+hljs.registerLanguage("php", php);
+hljs.registerLanguage("css", css);
+hljs.registerLanguage("plaintext", plaintext);
+hljs.registerLanguage("javascript", javascript);
+
+// Initialize syntax highlighting for all code snippets on this page
+const highlightElements = () => {
+ [...document.querySelectorAll("pre code")].forEach(element => hljs.highlightElement(element));
+}
+
+document.querySelector("[vv-shell-id='6ccb0465']").addEventListener(vegvisir.Navigation.EVENTS.FINISHED, () => highlightElements);
+highlightElements();
diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/EVENTS/description-additional.js b/modules/snippet/snippets/docs/API/JS/Navigation/EVENTS/description-additional.js
new file mode 100644
index 0000000..106a2c7
--- /dev/null
+++ b/modules/snippet/snippets/docs/API/JS/Navigation/EVENTS/description-additional.js
@@ -0,0 +1,3 @@
+{
+ target: HTMLElement
+}
\ No newline at end of file
diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/EVENTS/description.js b/modules/snippet/snippets/docs/API/JS/Navigation/EVENTS/description.js
new file mode 100644
index 0000000..b3ebdcd
--- /dev/null
+++ b/modules/snippet/snippets/docs/API/JS/Navigation/EVENTS/description.js
@@ -0,0 +1,4 @@
+static Navigation.EVENTS = {
+ STARTED: "navstarted",
+ FINISHED: "navfinished"
+}
\ No newline at end of file
diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/EVENTS/example-0-0.js b/modules/snippet/snippets/docs/API/JS/Navigation/EVENTS/example-0-0.js
new file mode 100644
index 0000000..e58f8c6
--- /dev/null
+++ b/modules/snippet/snippets/docs/API/JS/Navigation/EVENTS/example-0-0.js
@@ -0,0 +1,3 @@
+document.addEventListener(vegvisir.Navigation.EVENTS.STARTED, (event) => {
+ console.log(event.detail.target);
+});
\ No newline at end of file
diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/MODE/description.js b/modules/snippet/snippets/docs/API/JS/Navigation/MODE/description.js
new file mode 100644
index 0000000..06714d6
--- /dev/null
+++ b/modules/snippet/snippets/docs/API/JS/Navigation/MODE/description.js
@@ -0,0 +1,4 @@
+static Navigation.MODE = {
+ REPLACE: "replace",
+ INSERT: "insert"
+}
\ No newline at end of file
diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/POSITION/description.js b/modules/snippet/snippets/docs/API/JS/Navigation/POSITION/description.js
new file mode 100644
index 0000000..45bba4a
--- /dev/null
+++ b/modules/snippet/snippets/docs/API/JS/Navigation/POSITION/description.js
@@ -0,0 +1,6 @@
+static Navigation.POSITION = {
+ AFTEREND: "afterend",
+ BEFOREEND: "beforeend",
+ AFTERBEGIN: "afterbegin",
+ BEFOREBEGIN: "beforebegin"
+}
\ No newline at end of file
diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/TARGET/description.js b/modules/snippet/snippets/docs/API/JS/Navigation/TARGET/description.js
new file mode 100644
index 0000000..3cbd36c
--- /dev/null
+++ b/modules/snippet/snippets/docs/API/JS/Navigation/TARGET/description.js
@@ -0,0 +1,6 @@
+static Navigation.TARGET = {
+ TOP: "_top",
+ SELF: "_self",
+ BLANK: "_blank",
+ PARENT: "_parent"
+};
\ No newline at end of file
diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/TARGET/example-0-0.php b/modules/snippet/snippets/docs/API/JS/Navigation/TARGET/example-0-0.php
new file mode 100644
index 0000000..3f1b1de
--- /dev/null
+++ b/modules/snippet/snippets/docs/API/JS/Navigation/TARGET/example-0-0.php
@@ -0,0 +1 @@
+Click here to replace this button with the contents of /some-page
\ No newline at end of file
diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/TARGET/example-0-1.php b/modules/snippet/snippets/docs/API/JS/Navigation/TARGET/example-0-1.php
new file mode 100644
index 0000000..6d9658f
--- /dev/null
+++ b/modules/snippet/snippets/docs/API/JS/Navigation/TARGET/example-0-1.php
@@ -0,0 +1,4 @@
+...
+ Click here to replace this button and its siblings with /some-page + \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/abort/description.js b/modules/snippet/snippets/docs/API/JS/Navigation/abort/description.js new file mode 100644 index 0000000..08afca9 --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/abort/description.js @@ -0,0 +1 @@ +Navigation.abort: AbortController \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/bindElements/description.js b/modules/snippet/snippets/docs/API/JS/Navigation/bindElements/description.js new file mode 100644 index 0000000..e02da3b --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/bindElements/description.js @@ -0,0 +1 @@ +static Navigation.bindElements(): void \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/bindElements/example-0-0.js b/modules/snippet/snippets/docs/API/JS/Navigation/bindElements/example-0-0.js new file mode 100644 index 0000000..e31c81f --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/bindElements/example-0-0.js @@ -0,0 +1,5 @@ +// The programatically appended anchor tag will not have Vegvisir event listeners on it yet +document.body.appendChild(document.createElement("a")); + +// It will have Vegvisir event listeners after this method is called +vegvisir.Navigation.bindElements(); \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/constructor/description.js b/modules/snippet/snippets/docs/API/JS/Navigation/constructor/description.js new file mode 100644 index 0000000..b42d7a7 --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/constructor/description.js @@ -0,0 +1,4 @@ +new globalThis.vegvisir.Navigation( + URL|String url = window.location, + Object options = vegvisir.Navigation.options +): Navigation \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/constructor/example-0-0.js b/modules/snippet/snippets/docs/API/JS/Navigation/constructor/example-0-0.js new file mode 100644 index 0000000..6494008 --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/constructor/example-0-0.js @@ -0,0 +1,2 @@ +// Pathname string with leading slash +const nav = new vegvisir.Navigation("/some-page"); \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/constructor/example-0-1.js b/modules/snippet/snippets/docs/API/JS/Navigation/constructor/example-0-1.js new file mode 100644 index 0000000..7e8d07a --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/constructor/example-0-1.js @@ -0,0 +1,2 @@ +// Pathname string without leading slash and a search parameter +const nav = new vegvisir.Navigation("some-page?foo=bar"); \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/constructor/example-0-2.js b/modules/snippet/snippets/docs/API/JS/Navigation/constructor/example-0-2.js new file mode 100644 index 0000000..a45cada --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/constructor/example-0-2.js @@ -0,0 +1,6 @@ +// URL object with a pathname and search parameter +const url = new URL(window.location); +url.pathname = "/some-page"; +url.searchParams.set("foo", "bar"); + +const nav = new vegvisir.Navigation(url); \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/navigate/0.js b/modules/snippet/snippets/docs/API/JS/Navigation/navigate/0.js new file mode 100644 index 0000000..02e89ef --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/navigate/0.js @@ -0,0 +1,4 @@ +const nav = new vegvisir.Navigation("/some-page"); + +// Will navigate the top shell to /some-page +nav.navigate(); \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/navigate/1.js b/modules/snippet/snippets/docs/API/JS/Navigation/navigate/1.js new file mode 100644 index 0000000..970bf78 --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/navigate/1.js @@ -0,0 +1,5 @@ +const target = document.querySelector("#target"); +const nav = new vegvisir.Navigation("/some-page"); + +// Will replace the contents of an element with id #target with the contents of /some-page +nav.navigate(target); \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/navigate/2.js b/modules/snippet/snippets/docs/API/JS/Navigation/navigate/2.js new file mode 100644 index 0000000..1ce57bd --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/navigate/2.js @@ -0,0 +1,8 @@ +const target = document.querySelector("#target"); +const nav = new vegvisir.Navigation("/some-page"); + +// Will place the contents of /some-page after the target element as a sibling +nav.navigate(target, vegvisir.Navigation.POSITION.AFTEREND); + +// Tip: You can also pass an insertAdjacentElement position string directly +nav.navigate(target, "afterend"); \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/navigate/description.js b/modules/snippet/snippets/docs/API/JS/Navigation/navigate/description.js new file mode 100644 index 0000000..1714708 --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/navigate/description.js @@ -0,0 +1,5 @@ +Navigation.navigate( + target: HTMLELement = Navigation.#rootShellElement + position: Navigation.POSITION = Navigation.POSITION.BEFOREEND, + mode: Navigation.MODE = Navigation.MODE.REPLACE +): void \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/navigate/example-0-0.js b/modules/snippet/snippets/docs/API/JS/Navigation/navigate/example-0-0.js new file mode 100644 index 0000000..54c9df6 --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/navigate/example-0-0.js @@ -0,0 +1,6 @@ +const target = document.querySelector("#update-this-element"); +const button = document.querySelector("#click-me-to-refresh"); + +const nav = new vegvisir.Navigation("/page-with-new-content"); + +button.addEventListener("click", () => nav.navigate(target)); \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/JS/Navigation/options/description.js b/modules/snippet/snippets/docs/API/JS/Navigation/options/description.js new file mode 100644 index 0000000..c2bc5aa --- /dev/null +++ b/modules/snippet/snippets/docs/API/JS/Navigation/options/description.js @@ -0,0 +1,3 @@ +{ + pushHistory: boolean +} \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/css/0.php b/modules/snippet/snippets/docs/API/PHP/VV/css/0.php new file mode 100644 index 0000000..ebb4007 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/css/0.php @@ -0,0 +1,4 @@ + + +// Without file extension (appended automatically) + \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/css/1.php b/modules/snippet/snippets/docs/API/PHP/VV/css/1.php new file mode 100644 index 0000000..0c6476c --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/css/1.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/css/2.php b/modules/snippet/snippets/docs/API/PHP/VV/css/2.php new file mode 100644 index 0000000..77d81a2 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/css/2.php @@ -0,0 +1 @@ +"const hello = ()=>console.log('Hello world');hello()" \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/css/description.php b/modules/snippet/snippets/docs/API/PHP/VV/css/description.php new file mode 100644 index 0000000..3251b2c --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/css/description.php @@ -0,0 +1,4 @@ +VV::css( + string $pathname, + bool $relative = true +): string \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/css/example-1-0.css b/modules/snippet/snippets/docs/API/PHP/VV/css/example-1-0.css new file mode 100644 index 0000000..0d2c803 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/css/example-1-0.css @@ -0,0 +1,6 @@ +/* File: /var/www/my-website/public/assets/css/style.css */ + +p { + color: blue; + background-color: red; +} \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/css/example-1-1.php b/modules/snippet/snippets/docs/API/PHP/VV/css/example-1-1.php new file mode 100644 index 0000000..dfb160d --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/css/example-1-1.php @@ -0,0 +1,4 @@ +// File: /var/www/my-website/public/index.php + + +Some content...
\ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/embed/0.php b/modules/snippet/snippets/docs/API/PHP/VV/embed/0.php new file mode 100644 index 0000000..ebb4007 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/embed/0.php @@ -0,0 +1,4 @@ + + +// Without file extension (appended automatically) + \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/embed/1.php b/modules/snippet/snippets/docs/API/PHP/VV/embed/1.php new file mode 100644 index 0000000..0c6476c --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/embed/1.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/embed/2.php b/modules/snippet/snippets/docs/API/PHP/VV/embed/2.php new file mode 100644 index 0000000..77d81a2 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/embed/2.php @@ -0,0 +1 @@ +"const hello = ()=>console.log('Hello world');hello()" \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/embed/description.php b/modules/snippet/snippets/docs/API/PHP/VV/embed/description.php new file mode 100644 index 0000000..70b5401 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/embed/description.php @@ -0,0 +1,4 @@ +VV::embed( + string $pathname, + bool $relative = true +): string \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/embed/example-1-0.php b/modules/snippet/snippets/docs/API/PHP/VV/embed/example-1-0.php new file mode 100644 index 0000000..c1826be --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/embed/example-1-0.php @@ -0,0 +1,3 @@ +/* File: /var/www/my-website/public/assets/media/logo.svg */ + + \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/embed/example-1-1.php b/modules/snippet/snippets/docs/API/PHP/VV/embed/example-1-1.php new file mode 100644 index 0000000..5c07fee --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/embed/example-1-1.php @@ -0,0 +1,5 @@ +// File: /var/www/my-website/shells/document.php + +Important text!
+Some header content
+ = VV::include("modules/banner") ?> +Some content...
+ \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/root/0.php b/modules/snippet/snippets/docs/API/PHP/VV/root/0.php new file mode 100644 index 0000000..34f4b5a --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/root/0.php @@ -0,0 +1 @@ +VV::root("/src/databases"); \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/root/1.txt b/modules/snippet/snippets/docs/API/PHP/VV/root/1.txt new file mode 100644 index 0000000..38f9b6d --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/root/1.txt @@ -0,0 +1 @@ +"/var/www/my-website/src/databases" \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/root/2.php b/modules/snippet/snippets/docs/API/PHP/VV/root/2.php new file mode 100644 index 0000000..c5b8f90 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/root/2.php @@ -0,0 +1,9 @@ +// File: /var/www/my-website/src/MyClass.php + + +A normal Vegvisir page whch has access to MyClass
\ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/root/description.php b/modules/snippet/snippets/docs/API/PHP/VV/root/description.php new file mode 100644 index 0000000..6bf4ff6 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/root/description.php @@ -0,0 +1,3 @@ +VV::root( + string $pathname = "" +): string \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/shell/0.php b/modules/snippet/snippets/docs/API/PHP/VV/shell/0.php new file mode 100644 index 0000000..0df0de9 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/shell/0.php @@ -0,0 +1 @@ += VV::shell("shells/docs") ?> \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/shell/description.php b/modules/snippet/snippets/docs/API/PHP/VV/shell/description.php new file mode 100644 index 0000000..9d82be9 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/shell/description.php @@ -0,0 +1,3 @@ +VV::shell( + string $pathname = "" +): never \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/shell/example-0-0.php b/modules/snippet/snippets/docs/API/PHP/VV/shell/example-0-0.php new file mode 100644 index 0000000..091a064 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/shell/example-0-0.php @@ -0,0 +1,4 @@ +// File: /var/www/my-website/public/some-page.php + +Inner content
+= VV::shell("shells/outer-content") ?> \ No newline at end of file diff --git a/modules/snippet/snippets/docs/API/PHP/VV/shell/example-0-1.php b/modules/snippet/snippets/docs/API/PHP/VV/shell/example-0-1.php new file mode 100644 index 0000000..9dad618 --- /dev/null +++ b/modules/snippet/snippets/docs/API/PHP/VV/shell/example-0-1.php @@ -0,0 +1,5 @@ +// File: /var/www/my-website/shells/some-shell.php + +This paragraph will be above the wrapped content
+This parahraph will be below the wrapped content
\ No newline at end of file diff --git a/modules/snippet/snippets/docs/installation/0.txt b/modules/snippet/snippets/docs/installation/0.txt new file mode 100644 index 0000000..6a68fe0 --- /dev/null +++ b/modules/snippet/snippets/docs/installation/0.txt @@ -0,0 +1 @@ +git clone https://codeberg.org/vegvisir/vegvisir.git --depth 1 \ No newline at end of file diff --git a/modules/snippet/snippets/docs/installation/1.txt b/modules/snippet/snippets/docs/installation/1.txt new file mode 100644 index 0000000..312037a --- /dev/null +++ b/modules/snippet/snippets/docs/installation/1.txt @@ -0,0 +1 @@ +composer install --optimize-autoloader \ No newline at end of file diff --git a/modules/snippet/snippets/docs/installation/2.txt b/modules/snippet/snippets/docs/installation/2.txt new file mode 100644 index 0000000..92a4de8 --- /dev/null +++ b/modules/snippet/snippets/docs/installation/2.txt @@ -0,0 +1,16 @@ +# You might need to alter this block to suit your NGINX configuration +# The important thing is that all requests should be routed to /public/index.php + +server { + listen 80; + server_name _; + + root /var/www/vegvisir/public; + + location / { + try_files /index.php =503; + + include snippets/fastcgi-php.conf; + fastcgi_pass unix:/run/php/php8.3-fpm.sock; + } +} \ No newline at end of file diff --git a/modules/snippet/snippets/docs/installation/3.txt b/modules/snippet/snippets/docs/installation/3.txt new file mode 100644 index 0000000..8b30c60 --- /dev/null +++ b/modules/snippet/snippets/docs/installation/3.txt @@ -0,0 +1 @@ +mkdir /var/www/my-website \ No newline at end of file diff --git a/modules/snippet/snippets/docs/installation/4.txt b/modules/snippet/snippets/docs/installation/4.txt new file mode 100644 index 0000000..038eaa1 --- /dev/null +++ b/modules/snippet/snippets/docs/installation/4.txt @@ -0,0 +1 @@ +cp -p /var/www/vegvisir/.env.example.ini /var/www/vegvisir/.env.ini \ No newline at end of file diff --git a/modules/snippet/snippets/docs/installation/5.txt b/modules/snippet/snippets/docs/installation/5.txt new file mode 100644 index 0000000..7c45f5b --- /dev/null +++ b/modules/snippet/snippets/docs/installation/5.txt @@ -0,0 +1,10 @@ +# /var/www/vegvisir/.env.ini + +; +--------------------+ +; | Base configuration | +; +--------------------+ + +; An absolute path to the root directory of your website +root_path = "/var/www/my-website" + +... \ No newline at end of file diff --git a/public/assets/css/document.css b/public/assets/css/document.css new file mode 100644 index 0000000..524af4b --- /dev/null +++ b/public/assets/css/document.css @@ -0,0 +1,267 @@ +:root { + --primer-color-deep: 0, 128, 255; + --primer-color-light: 135, 255, 255; + --color-deep: rgba(var(--primer-color-deep)); + --color-light: rgba(var(--primer-color-light)); + + --border-style-width: 1px; + --border-style: solid var(--border-style-width) rgba(var(--primer-color-deep), .2); + + --padding: 10px; + --running-size: 70px; + --max-width: 1400px; +} + +/* # Cornerstones */ + +* { + margin: 0; + color: inherit; + font-size: inherit; + box-sizing: border-box; + font-family: monospace; +} + +body { + font-size: 15px; + overflow-x: hidden; + overscroll-behavior: none; +} + +body.menuOpen { + overflow: hidden; +} + +a { + color: inherit; + display: contents; + text-decoration: none; +} + +/* # Components */ + +:is(h1, h2, h3, p, li) > a { + --underline-tickness: 3px; + + display: initial; + text-decoration: underline; + text-decoration-color: var(--color-accent); + text-underline-offset: var(--underline-tickness); + text-decoration-thickness: var(--underline-tickness); +} + +@media (hover: hover) { + :is(h1, h2, h3, p, li) > a:hover { + text-decoration-color: var(--color-deep); + } +} + +h1 { + font-size: 30px; + color: var(--color-accent); +} + +h2 { + font-size: 25px; +} + +h3 { + font-size: 18px; +} + +/* ## Container */ + +container { + margin: auto; + height: 100%; + display: flex; + width: clamp(200px, 100%, 80vw); + max-width: var(--max-width); + align-items: center; + gap: var(--padding); + padding: var(--padding) 0; +} + +container.split { + display: grid; + grid-template-columns: repeat(2, 1fr); +} + +container.split.reverse div:last-child { + order: -1; +} + +container.split > div { + display: flex; + flex-direction: column; + align-items: baseline; + gap: var(--padding); +} + +/* ## Button */ + +button { + border: unset; + fill: black; + cursor: pointer; + padding: 10px 15px; + border-radius: 4px; + background-color: rgba(0, 0, 0, 0); + border: solid var(--border-style-width) transparent; +} + +button.solid { + fill: white; + color: white; + background-color: var(--color-deep); +} + +button.shade { + background-color: rgba(0, 0, 0, .05); +} + +@media (hover: hover) { + button:hover { + background-color: rgba(var(--primer-color-light), .3); + } + + button.solid:hover { + color: var(--color-light); + background-color: var(--color-deep); + } +} + +button svg { + fill: inherit; + width: 1em; +} + +/* # Content */ + +/* ## Runners */ + +:is(header, footer) ul { + display: flex; + padding-left: 0; + list-style: none; + gap: var(--padding); +} + +:is(header, footer) ul:last-of-type { + margin-left: auto; +} + +:is(header, footer) container > button { + display: none; + margin-left: auto; +} + +/* ### Header */ + +header { + --border-width: 2px; + + top: 0px; + position: sticky; + background-color: white; + height: calc(var(--running-size) + var(--border-style-width)); + border-bottom: var(--border-style); + z-index: 1000; +} + +header .logo { + height: 40px; + padding: 5px; + border-radius: 4px; + background-color: var(--color-deep); +} + +[vv-top-page="/"] header:not(.transparent) a[href="/"] button, +[vv-top-page="/help"] header a[href="/help"] button, +[vv-top-page^="/docs"] header a[href="/docs"] button, +[vv-top-page="/demos"] header a[href="/demos"] button, +[vv-top-page="/why"] header a[href="/why"] button { + font-weight: bold; + color: var(--color-deep); + border: var(--border-style); +} + +/* ### Footer */ + +footer { + padding: var(--padding); + color: var(--color-light); + background-color: var(--color-deep); +} + +/* ### Menu */ + +menu { + display: none; + position: fixed; + top: var(--running-size); + left: 0; + width: 100svw; + padding: calc(var(--padding) * 2); + height: calc(100svh - var(--running-size)); + background-color: var(--color-deep); +} + +body.menuOpen menu { + display: initial; +} + +menu ul { + list-style: none; + padding-left: unset; +} + +menu button { + color: white; + width: 100%; + margin-top: var(--padding); +} + +/* # Size queries */ + +@media (max-width: 950px) { + container { + min-width: unset; + width: 100%; + padding: calc(var(--padding) * 2); + } + + container.split { + display: flex; + flex-direction: column; + } + + container.split.reverse { + flex-direction: column-reverse; + } + + header ul button.solid, + :is(header, footer) ul:not(:last-of-type) { + display: none; + } + + :is(header, footer) container > button { + display: initial; + } + + footer :is(container, ul) { + flex-direction: column; + } + + footer button, + footer ul:last-of-type { + width: 100%; + margin-left: unset; + } +} + +@media (min-width: 950px) { + body.menuOpen menu { + display: none; + } +} \ No newline at end of file diff --git a/public/assets/css/pages/demos.css b/public/assets/css/pages/demos.css new file mode 100644 index 0000000..036cef3 --- /dev/null +++ b/public/assets/css/pages/demos.css @@ -0,0 +1,26 @@ +/* # WIP */ + +section#wip { + background-color: rgba(var(--primer-color-light), .3); +} + +section#wip container { + flex-direction: column; + gap: var(--padding); +} + +/* # Websites */ + +section#websites container { + flex-direction: column; +} + +section#websites ul { + list-style: none; + padding-left: unset; +} + +section#websites button { + margin-top: var(--padding); + width: 100%; +} \ No newline at end of file diff --git a/public/assets/css/pages/index.css b/public/assets/css/pages/index.css new file mode 100644 index 0000000..2a189f5 --- /dev/null +++ b/public/assets/css/pages/index.css @@ -0,0 +1,188 @@ +:root { + --wavelength: 20vw; +} + +body { + background-color: var(--color-deep); +} + +section h2 { + color: white; + background-color: black; +} + +header.transparent { + color: white; + background-color: transparent; + border-color: rgba(255, 255, 255, .1); +} + +header.transparent .logo { + fill: var(--color-deep); +} + +header.transparent button { + fill: white; +} + +header.transparent button.solid { + fill: var(--color-deep); + color: var(--color-deep); + background-color: white; +} + +/* # Sections */ + +/* ## Divider */ + +section.divider { + width: 100%; + overflow: hidden; + line-height: 0; + background-color: white; +} + +section.divider svg { + position: relative; + display: block; + width: calc(148% + 1.3px); + height: 79px; +} + +section.divider .shape-fill { + fill: var(--color-deep); +} + +/* ## Intro */ + +section#intro { + display: grid; + color: white; + min-height: 300px; +} + +section#intro h1 { + font-size: 50px; +} + +section#intro div { + display: flex; + flex-direction: column; + justify-content: center; + align-items: baseline; +} + +/* ### Waves */ + +section.waves { + --easing: .2; + + position: relative; + height: 300px; + user-select: none; + pointer-events: none; + z-index: -1; +} + +section.waves img { + margin: auto; + margin-top: -14%; + width: 50%; + transform-origin: 50% 100%; + animation: ship 6s alternate infinite ease; +} + +@keyframes ship { + 0% { + transform: translate(0, -7px) rotate(-7deg); + } + + 100% { + transform: translate(5px, 10px) rotate(4deg); + } +} + +section.waves .wave { + position: absolute; + width: 100%; + height: 100%; + transform: scale(1.5); + bottom: 70px; + animation: wave 7s alternate infinite cubic-bezier(var(--easing), 0, calc(1 - var(--easing)), 1); +} + +@keyframes wave { + to { transform: scale(1.5) translateX(100px); } +} + +section.waves + section { + background-color: #4ca6ff; +} + +section.waves .wave:first-child { + background-image: url("/assets/media/waves/0.svg"); +} + +section.waves .wave:last-child { + animation-duration: 5s; + background-image: url("/assets/media/waves/1.svg"); +} + +/* ## Softnav */ + +section#softnav { + color: white; + background: linear-gradient(0deg, rgba(0,128,255,1) 0%, rgba(76,166,255,1) 100%); +} + +/* ## BYOE */ + +section.info { + background-color: white; +} + +section.info container { + min-height: 400px; +} + +section.info svg { + justify-self: center; + width: 400px; +} + +/* ## Lead */ + +section#lead h1 { + color: white; + text-align: center; + font-weight: normal; +} + +/* ## Free */ + +section#free { + box-shadow: inset 0 0 20px 20px white, inset 0 0 140px 20px white; + background-color: rgba(255, 255, 255, .9); + background-blend-mode: screen; + background-image: url("/assets/media/gnu.png"); +} + +/* # Size queries */ + +@media (max-width: 950px) { + section.waves { + display: none; + } + + section.info container { + min-height: unset; + } + + section.info svg { + width: 300px; + } + + section#lead h1 { + font-size: 20px; + } +} \ No newline at end of file diff --git a/public/assets/css/pages/why.css b/public/assets/css/pages/why.css new file mode 100644 index 0000000..d2fded6 --- /dev/null +++ b/public/assets/css/pages/why.css @@ -0,0 +1,15 @@ +/* # Sections */ + +/* ## Free */ + +section#freedom { + background-position: 50% 50%; + background-size: 400px; + background-color: var(--color-deep); + background-blend-mode: lighten; + background-image: url("/assets/media/gnu.png"); +} + +section#freedom svg { + filter: drop-shadow(0 0 40px rgba(255, 255, 255, .3)); +} \ No newline at end of file diff --git a/public/assets/css/shells/docs.css b/public/assets/css/shells/docs.css new file mode 100644 index 0000000..7573160 --- /dev/null +++ b/public/assets/css/shells/docs.css @@ -0,0 +1,274 @@ +body { + background-color: rgba(var(--primer-color-deep), .01); +} + +[vv-shell-id="/"] { + display: grid; + min-height: calc(100svh - var(--running-size) - var(--border-style-width)); + grid-template-areas: + "aside main" + "contribute contribute" + ; + grid-template-columns: 400px 1fr; + grid-template-rows: 1fr 200px; + gap: calc(var(--padding) * 2); + margin: auto; +} + +[vv-shell-id="6ccb0465"] { + grid-area: main; + display: flex; + flex-direction: column; + gap: calc(var(--padding) * 2); + margin-top: calc(var(--padding) * 2); + padding-right: calc(var(--padding) * 2); +} + +hr { + border: unset; + border-top: var(--border-style); +} + +/* # Aside */ + +aside { + grid-area: aside; + height: 100%; + display: flex; + flex-direction: column; + padding: var(--padding) 0; + padding-left: calc(var(--padding) * 2); + border-right: var(--border-style); +} + +aside button { + width: calc(100% - (var(--padding) * 2)); + text-align: left; +} + +aside hr { + margin: calc(var(--padding) * 2) 0; +} + +aside ul { + list-style: none; + padding-left: 0; +} + +aside ul ul { + padding-left: var(--padding); +} + +aside ul > p { + margin: var(--padding) 0; +} + +/* ---- */ + +aside .cc + ul { + display: none; +} + +aside .cc.php button { + background-color: rgba(122, 134, 184, .2); +} + +aside .cc.js button { + background-color: rgba(240, 219, 79, .3); +} + +[vv-page^="/docs/API/PHP"] aside .cc.php + ul, +[vv-page^="/docs/API/JS"] aside .cc.js + ul { + display: initial; +} + +/* # Collapsible */ + +details { + border: 1px solid #aaa; + border-radius: 4px; + padding: 0.5em 0.5em 0; +} + +summary { + margin: -0.5em -0.5em 0; + padding: 0.5em; + cursor: pointer; +} + +details[open] { + width: 100%; + padding: 0.5em; +} + +details[open] summary { + border-bottom: 1px solid #aaa; + margin-bottom: 0.5em; +} + +/* # Sections */ + +/* ## Inset */ + +section.inset { + padding-left: var(--padding); +} + +/* ## Markdown */ + +section.md container { + padding-top: 0; + flex-direction: column; + align-items: baseline; +} + +section.md :is(h1, h2, h3) { + cursor: pointer; +} + +section.md h1::before { + content: "#"; + opacity: 1; + padding: 0 10px; + margin-right: .5em; + color: var(--color-light); + background-color: var(--color-deep); +} + +section.md h2::before { + content: "#"; + opacity: 1; + margin-right: .5em; + color: var(--color-deep); +} + +/* ## Code inline */ + +:is(h1, h2, h3, a, p, quote) > code { + padding: 5px; + border-radius: 6px; + white-space: nowrap; + font-family: 'Courier New', monospace; + background-color: rgba(0, 0, 0, .05); +} + +code.tag::before { + content: "<"; +} + +code.tag::after { + content: ">"; +} + +/* ## Code block */ + +section.md pre { + width: 100%; + max-width: calc(100svw - (var(--padding) * 4)); + tab-size: 3; + overflow: scroll; +} + +section.md pre code { + --copy-size: 37px; + --copy-inset: 5px; + --copy-border-size: 1px; + + overflow: scroll; + position: relative; + padding-right: calc(var(--copy-size) + (var(--copy-inset) * 2) + var(--padding)); + border-radius: 6px; +} + +section.md pre code::after { + content: "📋"; + display: grid; + font-size: 20px; + cursor: pointer; + position: absolute; + border-radius: 4px; + align-items: center; + justify-items: center; + top: var(--copy-inset); + width: var(--copy-size); + right: var(--copy-inset); + height: var(--copy-size); + border: solid 1px rgba(255, 255, 255, .1); + background-color: rgba(255, 255, 255, .1); +} + +@media (hover: hover) { + section.md h1:hover::before { + background-color: black; + } + + section.md :is(h1, h2, h3):hover::after { + content: " <- click to copy link"; + font-size: .5em; + opacity: .5; + } + + section.md pre code:hover::after { + border: solid 1px rgba(255, 255, 255, .3); + background-color: rgba(255, 255, 255, .2); + } +} + +/* ## Menu */ + +section.menu { + display: none; + fill: white; + color: white; + grid-area: menu; + cursor: pointer; + background-color: rgba(var(--primer-color-deep), .8); +} + +section.menu container svg { + width: 1em; +} + +section.menu p::before { + content: "Open "; +} + +/* # Size queries */ + +@media (max-width: 950px) { + [vv-shell-id="/"] { + grid-template-areas: + "menu" + "main" + "contribute" + ; + grid-template-columns: 1fr; + grid-template-rows: var(--running-size) 1fr 300px; + } + + body.docsMenuOpen [vv-shell-id="/"] { + grid-template-areas: + "menu" + "aside" + ; + grid-template-rows: var(--running-size) 1fr; + } + + body.docsMenuOpen [vv-shell-id="6ccb0465"], + body.docsMenuOpen section.contribute, + body:not(.docsMenuOpen) aside { + display: none; + } + + /* ---- */ + + [vv-shell-id="6ccb0465"] { + margin-top: unset; + } + + /* ---- */ + + section.menu { + display: initial; + } +} \ No newline at end of file diff --git a/public/assets/js/pages/index.js b/public/assets/js/pages/index.js new file mode 100644 index 0000000..5df688f --- /dev/null +++ b/public/assets/js/pages/index.js @@ -0,0 +1,10 @@ +const headerElement = document.querySelector("header"); + +const updateHeader = () => { + document.documentElement.scrollTop > 0 + ? headerElement.classList.remove("transparent") + : headerElement.classList.add("transparent") +} + +window.addEventListener("scroll", updateHeader); +updateHeader(); \ No newline at end of file diff --git a/public/assets/js/shells/docs.js b/public/assets/js/shells/docs.js new file mode 100644 index 0000000..c5dd70b --- /dev/null +++ b/public/assets/js/shells/docs.js @@ -0,0 +1,9 @@ +// Handle docs menu open/close +{ + const CLASSNAME_DOCS_MENU_OPEN = "docsMenuOpen"; + + // Toggle docs menu on button click + document.querySelector("section.menu").addEventListener("click", () => document.body.classList.toggle(CLASSNAME_DOCS_MENU_OPEN)); + // Hide docs menu on navigation + document.addEventListener(vegvisir.Navigation.EVENTS.STARTED, () => document.body.classList.remove(CLASSNAME_DOCS_MENU_OPEN)); +} \ No newline at end of file diff --git a/public/assets/js/shells/document.js b/public/assets/js/shells/document.js new file mode 100644 index 0000000..27bdc5f --- /dev/null +++ b/public/assets/js/shells/document.js @@ -0,0 +1,9 @@ +// Handle global menu open/close events +{ + const CLASSNAME_MENU_OPEN = "menuOpen"; + + // Toggle menu on menu button click + document.querySelector("header .menuToggle").addEventListener("click", () => document.body.classList.toggle(CLASSNAME_MENU_OPEN)); + // Close menu on navigation + document.addEventListener(vegvisir.Navigation.EVENTS.STARTED, () => document.body.classList.remove(CLASSNAME_MENU_OPEN)); +} \ No newline at end of file diff --git a/public/assets/media/byoe.svg b/public/assets/media/byoe.svg new file mode 100644 index 0000000..b293752 --- /dev/null +++ b/public/assets/media/byoe.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/media/gnu.png b/public/assets/media/gnu.png new file mode 100644 index 0000000..a8622ed Binary files /dev/null and b/public/assets/media/gnu.png differ diff --git a/public/assets/media/gnu.svg b/public/assets/media/gnu.svg new file mode 100644 index 0000000..603cd0c --- /dev/null +++ b/public/assets/media/gnu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/media/icons/codeberg.svg b/public/assets/media/icons/codeberg.svg new file mode 100644 index 0000000..327966a --- /dev/null +++ b/public/assets/media/icons/codeberg.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/media/icons/email.svg b/public/assets/media/icons/email.svg new file mode 100644 index 0000000..7c8b827 --- /dev/null +++ b/public/assets/media/icons/email.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/media/icons/matrix.svg b/public/assets/media/icons/matrix.svg new file mode 100644 index 0000000..63cbd84 --- /dev/null +++ b/public/assets/media/icons/matrix.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/media/icons/menu.svg b/public/assets/media/icons/menu.svg new file mode 100644 index 0000000..a361919 --- /dev/null +++ b/public/assets/media/icons/menu.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/media/logo.svg b/public/assets/media/logo.svg new file mode 100644 index 0000000..510be1a --- /dev/null +++ b/public/assets/media/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/media/replace.svg b/public/assets/media/replace.svg new file mode 100644 index 0000000..630883c --- /dev/null +++ b/public/assets/media/replace.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/media/waves/0.svg b/public/assets/media/waves/0.svg new file mode 100644 index 0000000..f16be57 --- /dev/null +++ b/public/assets/media/waves/0.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/media/waves/1.svg b/public/assets/media/waves/1.svg new file mode 100644 index 0000000..f4d4b33 --- /dev/null +++ b/public/assets/media/waves/1.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/assets/media/waves/shiponastick.svg b/public/assets/media/waves/shiponastick.svg new file mode 100644 index 0000000..fbfd6d1 --- /dev/null +++ b/public/assets/media/waves/shiponastick.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/demos.php b/public/demos.php new file mode 100644 index 0000000..da2e789 --- /dev/null +++ b/public/demos.php @@ -0,0 +1,18 @@ + +Sorry, this whole website is a work in progress.. this page especially so.
+(Vegvisir 3)
+vegvisir.Navigation.EVENTS
Various navigation CustomEvent
s that can be listened for.
All events will also fire on document
as a catch-all interface.
navstarted
This CustomEvent
will be fired on the navigation target
and document
when a navigation is started with .navigate()
.
navfinished
This CustomEvent
will be fired on the navigation target
and document
when a navigation with .navigate()
has finished completely.
A navigation is considered finished when the page has been fully loaded and all element attributes have been updated.
+CustomEvent.detail
propertyAccessing the .detail
property on a captured Vegvisir event will contain the following object.
target
The target
element that is used/was used for the navigation.
This example logs the target
element of all navigations on this page.
(Vegvisir 3)
+vegvisir.Navigation.MODE
Change if content should be replaced or inserted when used in .navigate()
.
REPLACE
Content of the destination URL will replace the content at vegvisir.Navigation.POSITION
.
INSERT
Content of the destination URL will append/prepend to the existing content at vegvisir.Navigation.POSITION
.
Setting the mode to INSERT
will make .navigate()
behave exactly like HTMLElement.insertAdjacentElement()
.
Position: beforebegin
= Prepend before the target
element itself.
Position: afterbegin
= Prepend just inside the target
element, before its first child.
Position: beforeend
= Append just inside the target
element, after its last child.
Position: afterend
= Append after the target
element itself.
(Vegvisir 3)
+vegvisir.Navigation.POSITION
Change where content should be placed when .navigate()
is used.
The effect of Navigation.POSITION
depend on the Navigation.MODE
used for the current navigation.
The default Navigation.POSITION
for .navigate()
is beforeend
and the default mode is replace
.
afterend
beforeend
This is the default position for .navigate()
.
afterbegin
beforebegin
(Vegvisir 3)
+vegvisir.Navigation.TARGET
Defines the target
element of a navigation triggered from a bound element.
This object follows the same syntax as the target
attribute of HTMLAnchorElement
.
If a string is provided to a target
attribute of the bound element that isn't in this enumerable, the string will be treated as a CSS selector.
These values correspond to the value of a target
attribute on a bound element.
_top
Target vegvisir.Navigation.rootShellElement
. This is the same as performing a normal soft-navigation.
This is the default behavior if a target
attribute is omitted or equals an empty string.
_self
Target the bound element itself with the defaults vegvisir.Navigation.POSITION.BEFOREEND
and vegvisir.Navigation.MODE.REPLACE
, which will replace the bound element itself with the contents of the destination URL.
The default position and mode behavior can be overridden with by setting a vv-position
and vv-mode
attribute on the bound element respectivly.
_blank
Default browser behavior. The destination URL will open in a new tab or window.
+_parent
Target the closest parent HTMLElement that has a vv-page
attribute.
vegvisir.Navigation.rootShellElement
will become the target if no parent is found.
The value of the bound element's target
attribute will be treated as a CSS selector if the string value does not equal an entry in this enumerable.
Here's an example that uses a native anchor tag to do various navigations.
+ = Snippet::put("docs/API/JS/Navigation/TARGET/example-0-0", Snippet::PHP) ?> + = Snippet::put("docs/API/JS/Navigation/TARGET/example-0-1", Snippet::PHP) ?> +(Vegvisir 2, Vegvisir 3)
+Navigation.abort
Interrupt a navigation started with .navigate()
.
Navigation.abort
is an instance of AbortController which gets contructed automatically with new vegvisir.Navigation
instances.
.abort()
Call Navigation.abort.abort()
to interrupt a Vegvisir navigation in progress.
(Vegvisir 2, Vegvisir 3)
+vegvisir.Navigation.bindElements()
Trigger automatic binding of unbound tags.
+Bind event listeners for HTMLAnchorElement
tags and other tags with a vv
attribute that haven't already been bound.
This method is runned automatically after a finished Vegvisir navigation.
+In this example we will programatically create and append an anchor tag to the DOM and use this method to bind it.
+ = Snippet::put("docs/API/JS/Navigation/bindElements/example-0-0", Snippet::JAVASCRIPT) ?> +(Vegvisir 2, Vegvisir 3)
+vegvisir.Navigation()
constructorThe Vegvisir navigation constructor is used to create a new instance of Navigation
. This is the first step to creating a custom navigation.
url
A URL
object or string with to a location on the same origin as the initiator.
options
An optional object containing vegvisir.Navigation.options
overrides.
Navigation
instanceA Navigation
object instance. Use the instance method .navigate()
to navigate an, or many element(s) in the DOM.
Different ways to initialize vegvisir.Navigation
with a location that will open /public/some-page.php
relative from project root.
With strings:
+ = Snippet::put("docs/API/JS/Navigation/constructor/example-0-0", Snippet::JAVASCRIPT) ?> + = Snippet::put("docs/API/JS/Navigation/constructor/example-0-1", Snippet::JAVASCRIPT) ?> +With URL objects:
+ = Snippet::put("docs/API/JS/Navigation/constructor/example-0-2", Snippet::JAVASCRIPT) ?> +vegvisir.Navigation
The Vegvisir Navigation
class contains APIs for triggering navigations of any element programmatically.
A new navigation can be initialized by constructing the vegvisir.Navigation
class.
(Vegvisir 2, Vegvisir 3)
+Navigation.navigate()
Perform a soft-navigation on an element.
+target
An optional instance of an HTMLElement
which will be the target of this navigation.
Vegivisr.rootShellElement
will be used if no argument is passed to this parameter.
Passing nothing to this parameter will target the top shell. This would be equivalent to clicking a link.
+ = Snippet::put("docs/API/JS/Navigation/navigate/0", Snippet::JAVASCRIPT) ?> +Passing an HTMLElement
to this parameter would in this example with no other arguments changed, replace the innerHTML of the target element with the response from /some-page
.
position
This parameter takes an optional Navigation.POSITION
string which can be used to change where content from the destination URL should be placed relative to the target
element.
Passing nothing to this parameter will replace the innerHTML of target
.
Passing an position string will in this example place the contents afterEnd from target.
+ = Snippet::put("docs/API/JS/Navigation/navigate/2", Snippet::JAVASCRIPT) ?> +mode
This parameter takes an optional Navigation.MODE
string which can be used to change how the contents of the destination URL should be placed relative to existing content around the target
element.
This method will not return anything, but a navigation in progress can be aborted with Navigation.abort
.
Programmatically invoke a top navigation - as if a user clicked a link.
+ = Snippet::put("docs/API/JS/Navigation/navigate/0", Snippet::JAVASCRIPT) ?> +An example how a simple "click to refresh" button can be implemented.
+ = Snippet::put("docs/API/JS/Navigation/navigate/example-0-0", Snippet::JAVASCRIPT) ?> +(Vegvisir 2, Vegvisir 3)
+Navigation.options
Override default Vegvisir navigation behavior.
+This object should be passed as the second argument when constructing a vegvisir.Navigation
instance.
pushHistory
This option has no default value:
+The default behavior of any Vegvisir top navigation is to push the new URL to the history stack. Ie. History API entry and browser pathname changes.
+Any navigation that is not a top navigation will not push to the history stack.
+By setting the pushHistory
option to:
true
Force all navigations with .navigate()
on this instance will push to the history stack. Including non-top navigations.
false
Force no navigations with .navigate()
on this instance will push to the history stack. Including top navigations.
Here is an example the embeds an SVG file directly on a page.
+This can come in handy for inlining small vector icons.
+ = Snippet::put("docs/API/PHP/VV/embed/example-1-0", Snippet::PHP) ?> + = Snippet::put("docs/API/PHP/VV/embed/example-1-1", Snippet::PHP) ?> +By using VV::css()
inside a style
, we've enabled this stylesheet for that specific page.
Vegvisir will automatically bind HTMLAnchorElement
tags and perform soft-navigation between pages on the same origin.
The Navigation
lets you interact with, and expand Vegvisirs front-end behavior.
(Vegvisir 2, Vegvisir 3)
+VV::css()
Import and minify a CSS file.
+The syntax is identical to VV::js()
, and VV::embed()
.
VV::css()
imports and minifies a CSS styleheet file and returns it as a string.
pathname
Path to a CSS stylesheet file to import relative from project root.
+relative
Path provided to pathname
will be a relative when this parameter is true
(default). Set to false
to make path absolute.
string
A string containing minified CSS. Please note that linebreaks are preserved.
+Will return an empty string if the path provided to pathname
is not a valid CSS stylesheet file, or if it failed to import.
Let's take the following CSS stylesheet file and put it into a page.
+ = Snippet::put("docs/API/PHP/VV/css/example-1-0", Snippet::CSS) ?> + = Snippet::put("docs/API/PHP/VV/css/example-1-1", Snippet::PHP) ?> +By using VV::css()
inside a style
, we've enabled this stylesheet for that specific page.
(Vegvisir 2, Vegvisir 3)
+VV::embed()
Import and inline the contents of any file without executing code.
+ +VV::embed()
returns the contents of any file as a string.
pathname
Path to a file to embed relative from project root.
+relative
Path provided to pathname
will be a relative when this parameter is true
(default). Set to false
to make path absolute.
string
A string containing the raw contents of the file. File encoding is preserved.
+Will return an empty string if the path provided to pathname
is not a valid file, or if it failed to import.
Here is an example the embeds an SVG file directly on a page.
+This can come in handy for inlining small vector icons.
+ = Snippet::put("docs/API/PHP/VV/embed/example-1-0", Snippet::PHP) ?> + = Snippet::put("docs/API/PHP/VV/embed/example-1-1", Snippet::PHP) ?> +By using VV::css()
inside a style
, we've enabled this stylesheet for that specific page.
(Vegvisir 2, Vegvisir 3)
+VV::include()
Inline contents of one page inside another page.
+The syntax and functionality is similar to VV::embed()
, except it executes included code.
VV::include()
lets you put the contents of one page into another page.
pathname
Path to a PHP file to import and evaluate relative from project root.
+relative
Path provided to pathname
will be a relative when this parameter is true
(default). Set to false
to make path absolute.
This method will return whatever the compiled output of the included PHP file will be.
+Consider the following page snippet
+ = Snippet::put("docs/API/PHP/VV/include/example-1-0", Snippet::PHP) ?> +Let's put this snippet into another page
+ = Snippet::put("docs/API/PHP/VV/include/example-1-1", Snippet::PHP) ?> +By importing the snippet with VV::include()
we have placed the banner
tag and its contents into another page.
VV
The VV
(two "V"'s, not a W) contains everything needed to interact with Vegvisir's PHP features.
The class can not be instanced since it only contains static methods.
+The VV
class is accessible without a namespace from any PHP file within your project.
The class intentionally lacks a namespace to reduce the (all be it short) boilerplate code that would be required to import and use
it on every page of your project.
(Vegvisir 2, Vegvisir 3)
+VV::js()
Import and minify a JavaScript file.
+The syntax is identical to VV::css()
, and VV::embed()
.
VV::js()
imports and minifies a JavaScript file and returns it as a string.
pathname
Path to a JavaScript file to import relative from project root.
+relative
Path provided to pathname
will be a relative when this parameter is true
(default). Set to false
to make path absolute.
string
A string containing minified JavaScript. Please note that linebreaks are preserved.
+Will return an empty string if the path provided to pathname
is not a valid JavaScript file, or if it failed to import.
Let's take the following JavaScript file and put it into a page.
+ = Snippet::put("docs/API/PHP/VV/js/example-1-0", Snippet::JAVASCRIPT) ?> + = Snippet::put("docs/API/PHP/VV/js/example-1-1", Snippet::PHP) ?> +By using VV::js()
inside a script
, we've enabled the code for that specific page.
(Vegvisir 3)
+VV::root()
Return an absolute path to a file or folder relative from project root.
+Return an absolute path to a file or folder relative from project root. This method does not process the entity at the provided location in any way. It simply returns an absolute path to it, which can be used with other functions.
+pathname
Path to a location relative from project root. This parameter is an empty string by default, which will return an absolute path to project root itself.
+string
An absolute path to the relative location provided by pathname
.
VV::root()
doesn't do anything on its own other than "convert" a relative path into an absolute one.
This can come in really handy when importing other PHP classes within your project. Let's import a PHP class from one location in the project into a public page.
+Let's import and use this class on our page with VV::root()
.
(Vegvisir 3)
+VV::shell()
Wrap contents of a page within another page.
+This method is similar to VV::include()
except it lets you place persistent content around the included page.
VV::shell()
is a powerful method which lets you put the contents of one page into a vv-shell
tag on another page.
Subsequent navigations to pages using the same shell will preserve the outer shell's state. The shell will not be fetched again.
+pathname
Path to a PHP shell page relative from project root which the contents of the initiator page will be wrapped inside.
+This method is buffered and will flush the buffer contents to stdout
when the last shell has been imported.
If we want the contents of page /public/some-page.php
wrapped inside the contents of /shells/some-shell.php
, we can do the following:
Place a VV::shell()
snippet at the end of the page you wish to wrap.
Now let's add a vv-shell
tag somewhere in our /shells/some-shell.php
file.
The contents of /public/some-page.php
will replace the inner contents of the vv-shell
tag.
The shell file acts like any other Vegvisir page, which means you have access to all VV
methods.
Vegvisir only has one class you need to worry about. The VV
class contains everything needed to interact with Vegvisir functions from project pages.
Here are some one-liners to help remember what things do.
+VV::include()
and VV::shell()
VV::include()
puts content inside another page.
VV::shell()
puts a page inside other content.
Vegvisir is a PHP and JavaScript web framework developed by Victor Westerlund as a hobby project.
+This framework is not intended to replace the true-and-tested like Laravel, it would be interesting of course if it gained some users but my goal is to keep this project small and flexible.
+This documentation only covers the new experimental version of Vegvisir, which is version 3.
+The older versions of Vegvisir can be found here. They lack proper documentation and function a bit differently than Vegvisir 3 which has been largely rewritten from scratch. The main addition to version 3 are what I call "shells".
+In this guide we will be installing Vegvisir on a Debian-based system with NGINX as the web server. The process should be similar for other configurations as well.
+ +Let's start by cloning Vegvisir to a folder. The code for Vegvisir will be separate from the code for your project.
+ = Snippet::put("docs/installation/0", Snippet::PLAINTEXT) ?> +I have cloned this into the folder /var/www/vegvisir
but you can put it wherever you want.
Vegvisir only has one dependency, let's cd
into our folder and install it with Composer.
We will be pointing a virtual host to the /public/index.php
file from the Vegvisir root directory.
Since your project files will live in a different directory, this can be set-and-forget.
+ = Snippet::put("docs/installation/2", Snippet::PLAINTEXT) ?> +We're almost done here. We want to create a separate folder which will hold our project files.
+Let's create a folder /var/www/my-website
as an example - you can put this wherever you want!
Now let's finish up by pointing Vegvisir to the folder we just created.
+Make a copy of the .env.example.ini
file from Vegvisir's root directory and place it in the same spot as .env.ini
There is only one line we need to change inside the .env.ini
file we just created. It should be the top most variable called root_path
.
Change the value of this variable to an absolute path to your project root folder. In our case it will be /var/www/my-website
.
That's all there is to it. Restart your webserver if you haven't and navigate to your published website.
+If everything worked correctly, you should see a default landing page with a summary.
+Vegvisir will automatically serve anything that isn't a .php
file under /public
in your project directory as a static asset. You can for example put your robots.txt
file under /public/robots.txt
and it will be returned as a text/plain
document.
While this works fine for smaller assets, they still have to be passed through the PHP CGI. This process is a bit slower than serving assets with your web server directly - and might be a lot slower for larger files.
+To fix this, let's add an optional location
block to our NGINX configuration which will handle assets. The process should be similar for other web servers - contact me if you need help.
Let's add the following location
block to our NGINX virtual host that we set up in Step X.
that handles navigation and routing, and nothing else
+No problem, Vegvisir's primary ethos is to not lock you down a specific paradigm. That is why Vegvisir will always try to interfere as little as possible with how and with what you build your website by being as simple as possible.
+The big names in PHP frameworks are all licensed under the permissive MIT license. This legally allows those frameworks to be used to develop proprietary malware. Vegvisir is free to use and will always respects your rights.
+