Introducing Opus
A content creator's website framework.
Back in 2019 I finally got round to creating 'clean URLs' for my website - so each page had its own clear address (like antsmith.net/words/fare-thee-well/tag/love) instead of using 'query parameters' (like antsmith.net?section=words&item=fare-thee-well&category=tag&context=love)
It was a massive improvement. I'd wanted to do it since around 2016, but my crappy hosting provider just made it impossibly difficult to achieve for years; especially since I was building the site in my spare time when most of my spare time was dedicated to creating the content I wanted to put on the site.
Which is THE perennial problem. As content creators it's the content that matters, not the technology that delivers it! Yet we end up having to spend yonks managing technology... even with the 'simple' socials (SnapDrag, instaGrump, Facebukake, Twatter, et ál) we haveta set-up profiles, manage notifications, report the persistant nuisance of the capitalist 'sponsors' and all the rest of it. Nevermind the ridiculous efforts needed to create a website using WordDepress or DreadSpace*.
*names have been changed to protect the guilty (I think you know who you are...)
So I established a 'software framework' offering low maintenance (zero content management overhead) for content producers (aka 'artists'). Something that could deliver new pages of compelling content as a bi-product of creating that content - a website driven wholly by the content it is given without having to mess around with 'templates' or 'pages' or whatever.
Providing the content exists in an appropriate electronic format (which it does, as a result of making it!) it just needs copying to the right place on the web-server for it to appear in the website.
Sure, you need to pay for the web-server (there's no real way round that) - but with my framework you don't spend extra hours 'conditioning material for the website'. Nor do you have additional monthly fees for the 'templates and widgets' you waste your time configuring. Nor do you have weeks of effort if you ever wanna get YOUR materials back out of their systems.
I believe strongly in preserving the democracy of cyberspace.
My original framework was created with around 20,000 lines of PHP code in about 40 seperate script files. It took a year or so...
I was pretty proud of the framework, well, I was proud of what it did and the stand it took in the corrupt world of cyber-services. IT WAS AND IS FREE. Free to adopt and free to use.
But I was never proud of the code itself. It was ugly AF. I mean, really damned ugly - and here I am, a proper seasoned and educated Software Engineer...
Last year I finally changed hosting provider to a local outfit (cgcdesign.co.uk) - they are great. Well priced, decent performance. This move gave me the impetus to really beef-up the performance, security and accessibility of websites powered by my framework.
I use Page Speed Insights to test my site for core metrics (Performance, Accessibility, Best Practices and SEO) on mobile and desktop.
Performance depends on just how busy the world is at any given moment, but is damn near 100% most of the time on desktop and around 90% on mobile. I have a small accessibility issue right now so only score 94% on that today (this will be fixed!). But the framework scores 100% in terms of 'best practices' (think 'security') and 'seo' (or discoverability).
To put this in perspective, the mighty BBC's home page (with its hundreds of so called 'Future Media' experts) performs miserably. Well under 50% wrt performance. A lack-lustre care for accessibility concerns (89%) and an awful 75% for best practices. Oh, they do score 100% on SEO, I guess their marketing people insist on that - at least it's good to know where their priorities lie these days...
...but anyway, I was feeling justifiably proud of what my framework was capable of. But I was hesitant to update the free download of the software that has always been available on the website; on account of its utter ugliness!
So I have been taking it in-hand, somewhat. Those original 20,000 lines of code in 40 scripts are now around 8,000 lines in 24 scripts; and will probably be around 6,000 lines by the time I am finished with this reworking.
A very small number of little used and over complex features have been dumped - but the majorty of the simplifications come from a change in approach. Previously I created scripts just as and when needed on the journey from the requested URL to the delivery of a complete page. Now I am creating object-oriented represenations of the site structure and content which are produced or consumed by a small number of scripts that do the delivery - which is how it shoulda always been...but for time...
Throughout, I have been struggling with the concept of 'purpose'. Why? Why do this? The sites that use the framework are working fine; more than fine. No one else is ever REALLY ever gonna look at this code, let alone work on it. It isn't in anyway going to outlive me. It isn't like a poem, or a story - very few people would ever care to understand it, or appreciate it.
Except that, while rewriting it all, I have found that it IS like a poem. Or a story, or a musical score.
For example, here's a fragment of how I create the dynamic styles for a given section of the site:
$dynamicCss->setProperty ('color');
$dynamicCss->addSelector ('body');
$dynamicCss->addSelector ('a:link');
$dynamicCss->addSelector ('a:active');
$dynamicCss->addSelector ('a:visited');
$dynamicCss->setProperty ('border-color');
$dynamicCss->addSelector ('.display-top>nav');
$dynamicCss->addSelector ('.display-bottom>nav');
$dynamicCss->addSelector ('.list-up-button:hover');
$dynamicCss->addSelector ('.list-down-button:hover');
$dynamicCss->setProperty ('background-color');
$dynamicCss->addSelector ('.menu-actions:hover');
$dynamicCss->changeValue ($site->decor->bg->hexColour);
$dynamicCss->setProperty ('color');
$dynamicCss->addSelector ('body');
$dynamicCss->addSelector ('.vpp-playlist a:link');
$dynamicCss->addSelector ('.vpp-playlist a:active');
$dynamicCss->addSelector ('.vpp-playlist a:visited');
$dynamicCss->setProperty ('background-color');
$dynamicCss->addSelector ('.user-literal');
$dynamicCss->addSelector ('.user-callout');
$dynamicCss->addSelector ('.user-callout-text');
$dynamicCss->addSelector ('.menu-actions > div');
I can readily read this with a lilt, in 'The Poets Voice' (if I wanted to) with rhythms and cadences that fall-out naturally. This is poetry: selectors, properties, values standing as lines, stanzas, sections... Perhaps the effect is somewhat muted by this small fragment (there's 200 lines of this epic in the full code) - but the fact is, the experience of writing (and reading) this code is exactly the same as writing poetry; in fact the results may be more meaningful and useful than many actual poems I have met in my life! Compare with the pure-scripting approach (similar, but not identical fragment):
a:link { color: <?php echo $GLOBALS["FG"] ?>; }
a:visited { color: <?php echo $GLOBALS["FG"] ?>; }
a:active { color: <?php echo $GLOBALS["FG"] ?>; }
.vpp-playlist a:link { color: <?php echo $GLOBALS["BG"] ?> !important; }
.vpp-playlist a:visited { color: <?php echo $GLOBALS["BG"] ?> !important; }
.vpp-playlist a:hover { color: <?php echo $GLOBALS["LINK_HOVER"] ?> !important; }
.vpp-playlist a:active { color: <?php echo $GLOBALS["BG"] ?> !important; }
Although only a small fragment, I think it is clear that it lacks the musicality of the new approach.
But more than this. Writing the code in this way, code as poetry, provides us with 'resonance'. We can elect to 'scan' rather than 'read' the code. We see quickly that decor-fg is largely concerned with color and border-color. Whereas decor-bg deals with color and background-color. The simple script fragment can really only be digested line-by-line; the inherent patterns of the intent are hidden from view. The decor-fg 'poem', like many good poems, ends in an obvious dissonance - with the forground being used as a background colour in one case. This fact could be completely missed if we were to scan a more loosely composed work; or worse could be spotted and presumed to be a mistake. This disonance though is a deliberate fact of some usecase in the software, and its presentation in this form forces the reviewer to spot, contemplate and resolve the truth of the matter.
Approaching the code as a 'composition' effects the way we write it. We find we can be less ensnared by 'principles' like DRY (Don't Repeat Yourself) - as here we are using deliberate repetition (setProperty 'color') to create the compositional framework [to be fair DRY is more meaningful than stated here, but we absolutely MUST repeat ourselves if the code is to exhibit natural resonance to the pattern-affirming human mind!]
This is only one aspect of coding, but rhythms and musicality are to be found throughout.
As are narrative arcs and characterisations.
A part of the Framework's responsibility is to place the content of text files (poems, stories etc) in to web pages. These text files can contain special 'macros': small instructions that are automatically expanded into complex blocks of HTML. Eg. to provide a list, or table, or an embedded video player etc...
When the framework meets one of these macros, a midwife is called to ensure it's safe delivery. The midwife maintains a link with the macro and the (parent) text file, providing caring services that the two need for the early establishment of a viable and functional life together...
class midwife {
public function deliverMacro($kind) {
$macro = new macro($kind);
$macro->attachTxtFile($this->source);
$macro->attachMidwife($this);
} // deliverMacro
} // class:midwifeObviously the story is bigger than that in the full code, but it IS a story. It FELT like a story when I wrote it. It made me smile.
The Midwife here is based on the defacto 'Abstract Factory Pattern'. 'Patterns' are pseudo-standard approaches folk employ to constrain creativity and innovation. The 'Factory' is a standard pattern where one lump of code is used to churn out widgets. People think 'standard design patterns' are how code should be written. It isn't. First off there are no actual standards for these things, only opinions. Secondly, no thank you. I won't liter my code with grey and mundane metaphores of an exploitative world. I'd rather look at the case in-hand and find a true human comparison with what I am doing. And besides, the midwife (unlike any factory) provides on-going essential care services.
Whilst patterns can enhance literacy, they do very little to aid in comprehension. Learn the pattern understand the code - but only in a very limited local way. Like pieces of a jigsaw, they are of limited use themselves, you need the picture on the box to get the most out of them.
Perhaps I'm digressing - the really important point is that Software Engineering is concerned with the creation of musicality, narrative and characterisation; more than factory's, classes and functions.
In terms of purpose, since the framework is designed to allow artists to deliver their works, it just feels right that the framework itself should be delivered in precisely these same artistic concerns.
I guess this is why I've given the framework a name now (Opus), maybe it's just a nickname... it isn't finished but here it is so far (so at least I can remove the earlier versions that really are, ugly AF!):
Ant Smith, 2023
Download The Framework
So you can download this framework for free here.
Or you could take a moment to value the efforts and hit the DONATE button in the footer of the page first.
It kinda depends on what kind of a person you want to be...
acknowledgements
The famework's audio player component is based on original work from Script Tutorials
The framework uses a reset approach for styling from
Richard Clark (html5reset) and Keith Clark (selectivizr)
Some of the fancy fonts that appear are free icons from fontawesome.com
EXIF metadata extraction is based on Evan Hunter's PHP JPEG Toolkit
The lightbox and gallery viewer use the excellent NanoGallery2 tool
HTML Truncation uses a code fragment from the CakeWalk2 framework
UTF8 BOM Removal from text files thanks to jasonhao
Sorry, can't remember where I got the cookie consent stuff from...
I also use stackoverflow very regularly to answer PHP specific questions.
I THINK this covers all unwitting contributors to my framework, apologies if it turns out I missed anyone...