Site Updates: Navigation
Time has granted a small reprieve to work on the greatest pain point of my personal website — the navigation bar. Due to sheer laziness, the navigation bar was initially implemented as three separate bars for each of the main views (tablet, phone, and desktop devices). This created unnecessary friction when adding new items. In the long term, the goal of integrating more programs into the website will require a certain consistency and so the navigation bar must be unified across all views.
Improvements
My website is glued together with PHP
is probably the most hated
programming language.
PHP
has native HTML
template, and generated statically by Hugo.
navigator.link
describes a
navigation link. Three parts receive or pass data: the attributes, the content,
and optionally, a faux return clause.
html
<a href="<?php echo $route ?? null; ?>" class="
<?php
$hiddenLabels = [ 'Profile' ];
if (in_array($label, $hiddenLabels)) { echo ' data-hidden'; }
if ($navigation->isActive($route ?? null)) { echo ' data-active'; }
?>
">
<?php echo icon($icon ?? null); ?>
<span title="<?php echo $label ?? null; ?>">
<?php echo $label ?? null; ?>
</span>
</a>
<?php $route = $label = $icon = null; ?>
Since this component is described in a file, it is cascaded anywhere using
require
.
html
<column-middle>
<?php
$route = '/'; $label = 'Home'; $icon = 'home'; require views('components', 'navigator.link');
$route = '/posts/'; $label = 'Posts'; $icon = 'feather'; require views('components', 'navigator.link');
$route = '/projects/'; $label = 'Projects'; $icon = 'package'; require views('components', 'navigator.link');
$route = '/about/'; $label = 'Profile'; $icon = 'file-text'; require views('components', 'navigator.link');
$route = '/contact/'; $label = 'Contact'; $icon = 'mail'; require views('components', 'navigator.link');
?>
</column-middle>
In frameworks like Laravel, this
templating method can take on a more
CSS
or JavaScript
that can be “extracted” into one final payload. Laravel uses
Blade syntax for templating.
php
@component ('components.navigator')
@slot ('left')
@include ('navigator.partials.menu')
@include ('navigator.partials.logo')
@include ('navigator.partials.header')
@endslot
@slot ('middle')
@include ('navigator.partials.title')
@endslot
@slot ('right')
@include ('navigator.partials.search')
@include ('navigator.partials.list')
@include ('navigator.partials.user')
@include ('navigator.partials.options')
@endslot
@endcomponent
@component ('components.context-menu', ['extract' => 'style']) @endcomponent
@component ('components.context-overlay', ['extract' => 'style']) @endcomponent
Templates can also be nested indefinitely. Here’s the unified context menu
component that contains nested HTML
elements inside the label
that is
stacked or cascaded in different places around the website.
php
<?php
$links = true;
$id = 'navigation';
$icon = icon('arrow-down-circle');
$label = <<<insert
$icon
<span>More</span>
insert;
require views('components', 'context.menu');
?>
You’ll notice that namespacing could become an issue, particularly for code
below the fold, and ideally data would be passed as
8
one could
simplify and structure view code further with
named arguments and
other niceties.
views
function, but this somewhat CSS
like
behavior is preferred for duplicating components of a similar type quickly.
Goals
More interesting tasks are on my to–do list and may be completed if the time allows.
Comprehensive Dark and Light Mode
The dark mode on the site isn’t implemented all that well. One of my goals is to
implement comprehensive dark mode features. In reality CSS
is the only
necessity, but adding some of the minor features may prove useful. One such
feature involves situations where light and dark mode changes apply to all open
tabs of the site. The most comprehensive guide on implementing dark mode that
I’ve come across is
written in this blog post.
Search Engine
The idea of a
vertical search engine where
the search scope is limited to a specific set of curated sites looks promising.
Here’s to hoping somebody makes a nice and
Deployment
The deployment situation for the website is looking up. The CI/CD
(Continuous
Integration and Deployment) situation, previously
Drone, was replaced with
NixOS and now the website deploys instantly. The
deployment logic lives on the server itself. The development, staging, and
production environments are setup and activated with a simple NixOS
module.
nix
{
services.thedroneely.enable = true;
services.thedroneely.development.enable = true;
services.thedroneely.staging.enable = true;
services.thedroneely.production.enable = true;
}