Recently Visited
Recently Visited

Information Architecture

[DRAFT] Last updated by Joe Schaefer on Fri, 26 Jun 2026    source
 

Information Architecture

Introduction

Web Information Architecture organizes, contextualizes, and arranges the entire gamut of technologies relevant to the design, presentation, relationships, and architectural constraints that cover every URL you serve over HTTP, both publicly and privately. This essay is a high-level survey of my expertise in these areas; it is far from comprehensive given the vast field it intends to cover.

This document is opinionated, since it covers these topics as currently architected into Orion.

Weaving Your Website’s Dependency Graph Together

Mathematically, a Topology τ\tau is a complete specification of the open subsets of a space XX, the purpose of which is to indicate the proximity relationships between points xx of the space XX. When XX is a graph, a topology τ\tau for XX amounts to specifying the edges connecting the vertices of the graph together (here vertices are viewed as the points of XX, and the connecting edges determine the neighborhoods of those points as basis open sets for the topology). A directed graph topology is essentially the same thing, but incorporates a reference to a topological embedding of (X,τ)(X,\tau) into a larger topological space (Y,σ)(Y,\sigma) , where the embedding’s edge connections are represented by directional, non-intersecting (Jordan) curves.

The latter concept is what we will utilize when discussing the dependency graph’s topology τ\tau associated to the space XX of source files beneath your site’s content/ subdirectory (here (Y,σ)(Y,\sigma) is Rn\mathbb{R}^n with its metric topology for n{2,3}n \in \{2,3\}, and the edges of XX are non-intersecting, directed Jordan curves connecting a file xXx \in X to its set of files upon which xx depends: {xXxx}\set{x^\prime \in X | x \rightarrow x^\prime}).

Having a clear understanding of your website’s dependency graph will ensure you can maximize the performance of our build technology at scale. We take the information you provide to %path::dependencies during the build’s load of your website’s lib/path.pm file, construct a reverse map of dependent files, and use that reverse map to determine the full corpus of files to build for any given svn commit you make to our system.

It’s important to note that the dependency relationships between source files can and should be fully captured by the %path::dependencies hash during the build-system’s startup load of lib/path.pm from your source tree, which is how the built-in views contained in our SunStarSys::View Perl package are meant to operate. The walk_content_tree and archived utility functions importable from SunStarSys::Util are useful aids in constructing the %path::dependencies hash, with built-in support for managing a dependency cache to accelerate incremental builds at scale.

Here’s that portion of our live lib/path.pm:

walk_content_tree {

  $File::Find::prune = 1, return if m#^/(images|css|js)\b#;

  return if -d "content/$_";

  my $path = $_;
  utf8::is_utf8 $path or utf8::decode $path;
  state $count = 0;
  for my $lang (qw/en es de fr ru sv he zh-TW ar ko ja pt-BR/) {
    delete $dependencies{"/sitemap.html.$lang"} if ++$count <= 12;
    next if m!\.page/!;
    if (/\.md\.$lang$/ or m!/index\.html\.$lang$!) {
      push @{$dependencies{"/sitemap.html.$lang"}}, $path if !archived;
    }

    if (/^(.*)\.tex\.$lang$/ and -f "content$1.bib.lang") {
      push @{$dependencies{$path}}, "$1.bib.$lang";
    }

    if ($path =~ s!/index\.html\.$lang$!!) {
      $dependencies{"$path/index.html.$lang"} = [
        grep {utf8::decode $_; s/^content//}
        glob("'content$path'/*.md.$lang"),
        glob("'content$path'/*/index.html.$lang")
      ];
    }
  }
}
  and do {
    while  (my ($k, $v) = each %{$facts->{dependencies}}) {
      $dependencies{$k} = [grep $k ne $_, grep s/^content// && !archived, map glob("'content'$_"), ref $v ? @$v : split /[;,]?\s+/, $v];
    }

    open my $fh, "<:raw", "lib/acl.yml" or die "Can't open acl.yml: $!";
    unshift @acl, @{Load join "", <$fh>};
    my %cache;
    @acl = grep !$cache{$_->{path}}++, @acl;
    for (glob("content/*/index.md.*")) {
        next if /archives|categories/;
        s!/index\.md\.[^/]+$!!;
        push @acl, { path => $_, rules => {
             '@bloggers'  => 'rw',
             '@svnadmin' => 'rw',
             '*' => 'r',
        }} unless $cache{$_}++;
    }
  };

Please do mull that code over for ideas on how you want your website to work. Yes there is some reasonable complexity (involving both Perl’s regular expressions and Perl’s UNIX C-shell glob interfaces, in a very precise way) around how %path::dependencies is constructed in that file, but instead of just viewing this as optimization work, instead look at it as providing the basic ingredients necessary for construcing major aspects of the deps topology in an automated, dynamically generated fashion.

Where do entries in %path::dependencies originate? If they are not born from an invocation of walk_content_tree { ... }, (which basically dives into your markdown source files’ headers and content), then they are just hard-coded into lib/facts.yml at load-time.

No! In fact, the link topology of your website is an entirely separate matter from the source tree’s dependency graph. A search engine will naturally ferret out the link topology, but has no insight into the dependency graph.

Separation of Concerns and Engineering Tradeoffs

In a nutshell, the way every other wiki platform works is as an SQL CRUD app that makes it quick and easy to modify content, for which the results have to be reconstructed in real-time (or from a webpage cache) every time someone needs to view that content online.

In (noSQL) Orion, we take editing and rendering as two separate concerns that should be handled by two independent software stacks; where much more process, design, validation, and dependency management is invested in the editing interface. This is so that we can limit the software on the rendering stack to be a barebones SSI-enabled Apache file server with bog-standard web authentication and access controls involved, and optimistically we expect that the content is viewed an order of magnitude more often than it is edited.

Consequently, the editing experience happens on an impossible-to-access-without-a-valid-login independent web stack, is a little less quick once the changes are uploaded, and is a lot less dirty; because we validate and build the modified content, along with the entire corpus of dependent pages, at edit-time, not at render time. The build happens in a separately hardened, sandboxed Solaris Zone. The build logs are published to the editing session in real time, and saved in version control for posterity and business accountability.

In reality, the cost is a few seconds more of exposure to the build’s technical machinery and static file deployment process before being able to view committed, published changes on the live production website.

And the benefit? You will never see your live website get hacked again through zero-day or unpatched vulnerabilities in the rendering webserver’s software stack. Moreover, the editing site is invulnerable to anonymous hacking efforts, so you are in a much better security-architectural position with us than with any other wiki vendor on Earth, regardless of the additional protections implemented in the remainder of this document.

Neat trick, ain’t it?

But it critically hinges on that tradeoff being viable to the editor experience. And without application of our patent-pending Smart Content Dependency Management™ framework, may not be worth the cost for many businesses.

Human Interface Goals

Contextualized by directories. Expansive to parent directories.

Powerful Syntax

PCRE/Lucene query.

Hashtagged Seaches are Keyword Specific Instead of Generic Word Searches

Tagged Metadata Keywords.

Easy Scope Expansion

Expand scope to parent directory search.

Interactive Results Filtration Engine

Subsearches within existing matches.

See the section on HATEOAS for an overview.

Built-In Performance Scaling to 100K document trees
Comprehensible Result Ordering / Prioritization

Hits ordered by frequency + Lucence match score.

Per-User Security (ACL) Contextualized Results

Matches filtered by per-user document ACLs.

Hits Linked Directly to Target-Specific Document Locations

Jump directly to the matched content.

Live, RealTime Results (aka No Stale Indexed Corpus)

Lucene indexes tied to build-system, including incremental builds.

Customer Adoption Goals

Deliverable as “application/json” Upon Request

Options:

  • pass as_json=1 in the query string
  • set Accept: application/json in the request headers
Custom Styling is Controlled by Customer Managed Content of the /content/css/local.css File
search.html Template is Overridable by Customer Installation of the /templates/search.html File
main.html Derived Template is Overridable by Customer Installation of the /templates/main.html File

REST, HATEOAS, and Content Negotiation

Beautiful URLs — Both Permanent and Transient

content negotiation

Structured, Future-Proofed MultiMedia Source Text Formats: markdown, yaml, and csv

GitHub Flavored Markdown with KaTeX\KaTeX and @mermaid-js/mermaid Integration

YAML Headers for MetaData

CSV files for markdown table generation

A Turing Complete Programming Language Ain’t Data - it doesn’t belong in your content sources

The Value of Enabling Template Preprocessing on Content

  • Inline Data Processing Engines

    • embedded, “safe” json literals in built files
    • build-time markdown table generation
    • indentation-contextualized ssi includes to filter adjacent source files

Slowly Evolving, Centralized Configuration of Wiki Facts

  • corporate service urls
  • software artifact locations and version numbers
  • ansible has them; why not your SSG?

The role of ssi Tags in Your MultiMedia Strategy

Access Controls on Content, from a Single Source of Truth Perspective

  • walk_content_tree() in path.pm
    • seed_file_deps
    • seed_file_acl
  • acl.yml

SunStar Systems’ Orion™ for ZFS-backed Platforms

  1. zfs clones
  2. zfs send/recv

StageMaster: Experimentation with Pure Client-Side State Engine

GitOps build workflows

  1. Frontend
  2. Backend
  3. Documentation