• File: index.cache.php
  • Full Path: /home/daemondevin/public_html/blog/data/backups/20261025103013-1.2.0-to-1.3.0/files/docs/index.cache.php
  • Date Modified: 10/26/2026 9:44 PM
  • File size: 63.81 KB
  • MIME-type: text/x-php
  • Charset: utf-8
<?php http_response_code(404); exit; ?>
a:2:{s:3:"sig";s:32:"a6405947f969d24a0d1ec4ebb85671f2";s:5:"posts";a:18:{i:0;a:15:{s:4:"slug";s:5:"about";s:5:"title";s:5:"About";s:4:"date";s:16:"2026-10-02 09:05";s:7:"updated";s:16:"2026-10-14 15:55";s:6:"status";s:9:"published";s:4:"type";s:4:"page";s:4:"tags";a:0:{}s:11:"description";s:18:"About daemon.devin";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:16:"Hi, I’m Devin.";s:5:"words";i:389;s:7:"minutes";i:2;s:5:"plain";s:2553:"hi, i’m devin. i’m a web developer and ui enthusiast with well over a decade of hands on experience building for the web. my work bridges the gap between functional backend architecture and clean, intuitive frontend interfaces. over the years, i’ve specialized deeply in php and javascript, creating everything from custom ui frameworks to lightweight web tools. what i do full stack development: over 10+ years of experience crafting php applications, writing clean javascript, and integrating modular code bases. ui & design systems: i enjoy blending modern frontend architecture with retro futuristic and mid century modern aesthetic influences. whether it's building component libraries like themestrap https://github.com/daemondevin/themestrap or design tools like theme o matic, i aim for tools that look as good as they function. open source & side projects: outside of client and enterprise work, i'm usually working on pac man https://github.com/daemondevin/pac man . it's a fork of the portableapps.com launcher framework but its designed to support complex, modern, and legacy windows applications that portableapps.com launcher intentionally does not target. my version is not meant to replace the original. it exists to solve a different class of problems. why daemon.devin my alias daemon.devin is a clever play on words that bridges computer science concepts with my actual name. in unix like operating systems, a daemon is a background process that runs quietly and continuously in the background, handling tasks autonomously behind the scenes without needing direct user intervention. blending that technical foundation with "devin" speaks to my role as a backend focused full stack developer—someone who works under the hood, writing robust php and javascript apps, maintaining system architecture, and keeping the machinery running seamlessly behind the user interface. beyond the code when i’m not staring at a code editor or tweaking design tokens, i'm usually annoying claude with my antics.. just kidding. you can usually find me messing around with fl studio making music soundcloud profile found below , writing custom javascript games, or experimenting with ascii and vector graphics tools. in the wild github: @daemondevin https://github.com/daemondevin soundcloud: @daemondevin https://soundcloud.com/daemondevin codepen: @daemondevin https://codepen.io/daemondevin website: daemon.devn https://envs.net/ daemondevin get in touch email: daemon.devin@gmail.com secondary: daemon.devin@envs.net discord: daemon.devin ";}i:1;a:15:{s:4:"slug";s:13:"dark-dominion";s:5:"title";s:13:"Dark Dominion";s:4:"date";s:16:"2026-10-19 02:30";s:7:"updated";s:16:"2026-10-19 02:33";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:2:{i:0;s:5:"music";i:1;s:10:"SoundCloud";}s:11:"description";s:35:"A song I made called Dark Dominion.";s:5:"image";s:0:"";s:6:"format";s:5:"audio";s:5:"media";a:1:{i:0;s:48:"https://soundcloud.com/daemondevin/dark-dominion";}s:7:"excerpt";s:91:"Just testing out the format feature for TSBlog so here's a song I made called Dark Dominion";s:5:"words";i:17;s:7:"minutes";i:1;s:5:"plain";s:92:"just testing out the format feature for tsblog so here's a song i made called dark dominion ";}i:2;a:15:{s:4:"slug";s:28:"first-launch-post-for-tsblog";s:5:"title";s:29:"First Launch/Post for TSBlog!";s:4:"date";s:16:"2026-10-05 09:00";s:7:"updated";s:16:"2026-10-14 15:58";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:19:{i:0;s:6:"TSBlog";i:1;s:10:"Themestrap";i:2;s:8:"blogging";i:3;s:15:"web development";i:4;s:10:"web design";i:5;s:17:"component library";i:6;s:13:"UI components";i:7;s:10:"JavaScript";i:8;s:4:"HTML";i:9;s:3:"CSS";i:10;s:20:"frontend development";i:11;s:14:"web components";i:12;s:19:"reusable components";i:13;s:8:"open web";i:14;s:15:"developer tools";i:15;s:3:"CMS";i:16;s:14:"user interface";i:17;s:20:"software development";i:18;s:14:"web technology";}s:11:"description";s:158:"This post launches TSBlog, a lightweight, flat-file blogging system built to showcase the author's reusable UI components in the Themestrap Component Library.";s:5:"image";s:72:"/~daemondevin/blog/uploads/2026/10/tsblog-better-web-building-de000a.jpg";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:203:"Hi. You've just stumbled upon the very first officially posted blog entry from the very first officially hosted TSBlog blogging system! How exciting it must be for you to be witnessing history being w…";s:5:"words";i:1556;s:7:"minutes";i:8;s:5:"plain";s:4008:" welcome to tsblog hi. you've just stumbled upon the very first officially posted blog entry from the very first officially hosted tsblog blogging system how exciting it must be for you to be witnessing history being written as you read walk with me a moment.. the web wild west there was a brief, beautiful window in the early 2000s when the internet belonged entirely to the amateurs. before the web was consolidated into a handful of corporate platforms and slick, predictable templates, it was a lawless frontier built on raw curiosity. it was an era of beautifully chaotic experimentation. novices with zero formal training were building the world wide web from their bedrooms, throwing together bits of copied html, flashing gif banners, and background music that shocked your speakers on arrival. we didn't care about ui nor did we know the term " user experience "—we just wanted a small corner of the www to call our own. it was the peak of digital lawlessness i remember reading about css and a thing called div overlay . now i knew what div was thanks to html. does anyone else remember the old school div layouts phase back then? however, this was different. this meant tearing down the rigid walls of myspace with the legendary div overlay hack. we didn’t just customize our profiles; we staged a hostile takeover. armed with a chaotic string of table table table { display: none; } , we aggressively nuked the default website, leaving a blank canvas. in its place, we used position: absolute and custom photoshop backgrounds to force scrollable text boxes exactly where we wanted them. it was a brilliant, fragile illusion—a pixel perfect masterpiece held together by a prayer and a single string of stolen css. for those who don't know what i'm talking about, here's what my myspace profile page looked like back then: myspace / daemondevin/blog/uploads/2026/10/myspace f2937d.jpg we copy pasted layout codes into livejournal , spent hours customizing winamp skins, and integrated scripts like cutenews using a single, magical php include tag because we didn't even know what a mysql database was yet. everyone was learning by breaking things, fueled by a collective, unpolished enthusiasm. it was a digital web wild west see what i did there? =p , populated not by content creators or influencers or algorithms, but by programming pioneers who built simply because they were curious about code and it wasn't so overwhelming back then. anyway, there's something satisfying about building a publishing system from scratch. not because the world needs another blogging system. it probably doesn’t. but because building your own system gives you an opportunity to learn what actually goes into a project like this. i can certainly say i have a new found appreciation for bigger projects like modx and wordpress. however, those projects have their own staff and employees on an actual payroll. not to mention the immense amount of contributors thanks to their open source eco system. as they should.. well written software does deserve it but what about the little things that normally disappear beneath layers of themes, plugins, frameworks, configuration screens, and dependencies? tsblog: a throwback tsblog is my attempt at acknowledging those little things and bringing back that innovative musings from the past when things were of a simpler nature. inspired by from memory.. i'm sure it's still out there in the wild the old school flat file blogging script called cutenews by cutephp, tsblog is a nostalgic tribute to the good ol' days. it's basically a lightweight blogging and publishing system built around the same philosophy behind my themestrap component library : useful components, sensible defaults, minimal friction, and an emphasis on the actual experience of using the web. and rather than simply telling you what tsblog can do, i thought the first post should demonstrate it. so, welcome to the first post on tsblog. a blog built to showcase the system one of the fun ";}i:3;a:15:{s:4:"slug";s:27:"new-theme-and-entry-formats";s:5:"title";s:27:"New Theme and Entry Formats";s:4:"date";s:16:"2026-10-18 16:10";s:7:"updated";s:16:"2026-10-18 16:16";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:3:{i:0;s:10:"Themestrap";i:1;s:6:"TSBlog";i:2;s:13:"release notes";}s:11:"description";s:117:"TSBlog gets a Themestrap theme, six entry formats for posts, and a fix for updating when a release adds a new folder.";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:103:"TSBlog now has a second theme, and posts can be more than text and a cover image. Here is what changed.";s:5:"words";i:317;s:7:"minutes";i:2;s:5:"plain";s:1737:"tsblog now has a second theme, and posts can be more than text and a cover image. here is what changed. < more the themestrap theme it has no dependencies. the slider, lightbox, tabs and menu are one small script, so there is no bootstrap, no icon font and nothing to build. to recolor it, change one variable accent in style.css . pick it under settings → theme . entry formats every post now has a format that decides what sits above its text: standard: a cover image, as before. slider: several pictures in a carousel. gallery: a grid of thumbnails that opens in a lightbox. video: a youtube or vimeo link, or an mp4 or webm file. audio: a soundcloud or spotify link, or an mp3 or ogg file. embed: a codepen link. paste the normal link from the address bar and the blog turns it into the right player. you never paste embed code. only those services are accepted, so a post cannot carry a stray frame. for pictures, one address per line works, or use add pictures to upload several at once. the format is stored in the post file format: and media: , and sqlite databases from before this change upgrade themselves the first time they open. updating if an update said it "tried to change a file updates are never allowed to touch", this is why: a blog decides what an update may change using the code it is running now, so an old blog refuses a release that adds a new folder. nothing was changed when that happened. the fix is a short bridge release first, which teaches the blog about the new folder, followed by the real release. the release tool has a bridge option for it, and the steps are in the updates docs. if you publish your own releases, build the bridge before the full release. everyone else just clicks update twice. ";}i:4;a:15:{s:4:"slug";s:23:"our-fallacious-thoughts";s:5:"title";s:23:"Our Fallacious Thoughts";s:4:"date";s:16:"2026-10-19 02:34";s:7:"updated";s:16:"2026-10-19 02:37";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:2:{i:0;s:7:"YouTube";i:1;s:23:"Our Fallacious Thoughts";}s:11:"description";s:53:"A YouTube video I made called Our Fallacious Thoughts";s:5:"image";s:0:"";s:6:"format";s:5:"video";s:5:"media";a:1:{i:0;s:43:"https://www.youtube.com/watch?v=kKr1eSjF-7Q";}s:7:"excerpt";s:76:"Now testing a YouTube video with one I made called Our Fallacious Thoughts..";s:5:"words";i:13;s:7:"minutes";i:1;s:5:"plain";s:78:"now testing a youtube video with one i made called our fallacious thoughts .. ";}i:5;a:15:{s:4:"slug";s:8:"projects";s:5:"title";s:8:"Projects";s:4:"date";s:16:"2026-10-25 22:58";s:7:"updated";s:16:"2026-10-25 23:34";s:6:"status";s:9:"published";s:4:"type";s:4:"page";s:4:"tags";a:0:{}s:11:"description";s:0:"";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:153:"Here is what I am working on. Most of it follows one idea: carry only what you use. No build step, no vendor bloat, nothing that needs constant patching.";s:5:"words";i:803;s:7:"minutes";i:4;s:5:"plain";s:4000:"here is what i am working on. most of it follows one idea: carry only what you use. no build step, no vendor bloat, nothing that needs constant patching. note this page is a snapshot. projects move at different speeds, and some are further along than others. at a glance project what it is built with themestrap themestrap a zero build ui component library jquery, bootstrap 5 tsblog tsblog a blog engine that needs no setup php, optional sqlite pac man pac man a launcher framework for portable windows apps nsis portableapps portableapps portableapps i've built with pac man nsis themestrap github social preview / daemondevin/blog/uploads/2026/10/github social preview 960391.png a component library with no build pipeline. no webpack, no npm, no compile step. every component is a self contained jquery plugin that you drop in with a script tag and switch on with a data attribute. html <div data plugin hovercard data plugin options='{"side": "bottom", "delay": 200, 300 }' <a data hovercard trigger href=" " @daemon.devin</a <div data hovercard content a preview card, shown on hover.</div </div tip themestrap is what's behind this blog you're viewing = the github project page can be found here https://github.com/daemondevin/themestrap . the library covers carousels, dialogs, calendars, menus, command palettes, hover cards, markdown editing, dark mode, and a long tail of smaller pieces. a few plugins i am proud of: plugincarouselpro. a carousel with no vendor dependencies. seamless infinite loop, drag with pointer events, fade or slide, dots, thumbnails, an autoplay progress bar, lazy loading and responsive breakpoints. pluginscrollbar. a custom scrollbar written from scratch with pure css arrows and every axis and theme covered. pluginselect. a custom select that wraps the native one, so forms still submit. grouped options, type ahead, full keyboard control, and it flips upward when there is no room below. pluginalert. alerts and toasts with auto dismiss, animations, a countdown bar and a css token file you can restyle in minutes. pluginhighlight. code block enhancement and a generated table of contents, hardened with retries and a graceful fall back to plain text when a cdn misbehaves. there is also a dependency aware module loader that knows about the plugins, a manifest and documentation page to go with it, and a showcase mailbox app that puts eleven plugins to work in one real screen. every plugin ships with a demo page and a markdown guide. tsblog tsblog better web building / daemondevin/blog/uploads/2026/10/tsblog better web building 4d6e4a.jpg the blog you are reading. it is a blog engine for people who want to write. no setup. upload it, open it, choose a password. posts are plain files, or optionally one sqlite database. fast and light. a small theme, no third party scripts, clean addresses, an rss feed, a sitemap and sensible search metadata. a real writing experience. markdown, a simple mode for people who would rather not see it, scheduling, and drafts. entry formats. standard, slider, gallery, video, audio and embed posts, with players built from a plain link. everything in the box. github style alerts, reference links, light comments with spam protection, and an analytics page with hover cards for visitor ips. updates from the admin. it checks for a new release, downloads it, checks the signature, and swaps the files in, with a way back. it reuses themestrap plugins wherever they fit, and where one was missing i built it. pac man pac man / daemondevin/blog/uploads/2026/10/pac man 151b59.jpg pac man https://github.com/daemondevin/pac man is my launcher framework for portable windows apps. it builds on the official portableapps.com launcher and goes further, for the apps that need services, scheduled tasks, dll registration, drivers, registry and file redirection, fonts and firewall rules. each feature is its own segment, so a launcher only carries what it uses, and your system goes back to how it was when you close the app.";}i:6;a:15:{s:4:"slug";s:35:"reference-links-alerts-and-comments";s:5:"title";s:36:"Reference links, alerts and comments";s:4:"date";s:16:"2026-10-22 22:30";s:7:"updated";s:16:"2026-10-22 23:05";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:3:{i:0;s:6:"TSBlog";i:1;s:10:"Themestrap";i:2;s:13:"release notes";}s:11:"description";s:112:"TSBlog now understands reference-style links and GitHub alerts, and has a lite comment system you can switch on.";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:78:"Three additions this time: reference links, GitHub style alerts, and comments.";s:5:"words";i:289;s:7:"minutes";i:2;s:5:"plain";s:1630:"three additions this time: reference links, github style alerts, and comments. < more reference links write the address once and reuse it. the definition can sit anywhere in the post and never shows on the page: images work the same way alt logo , and names are not case sensitive. alerts start a quote with note , tip , important , warning or caution and it becomes a highlighted box: note useful information. they are drawn with themestrap's pluginalert, with an icon, a title and colors for light and dark mode. the script only loads on posts that contain an alert, and without javascript you still get a plain colored box. comments comments are off until you turn them on under settings → comments. pick one of: i approve each comment first. new comments wait in the admin. show comments right away. a comment with more than two links still waits. closed. existing comments stay, no new ones are accepted. readers give a name, an optional email never shown and their comment, and can reply one level deep. the admin has a comments page to approve, mark as spam or delete, with a count of what is waiting. spam is handled without a captcha: a form token, a hidden trap field, a per visitor rate limit, a link limit and duplicate detection. everything lives in one private file, data/comments.php, which works the same with files or sqlite and is included in the backup. both themes show comments out of the box. if you made your own theme, add one call to ts comments section $post in post.php. the comments page in the docs has the details. updating this release adds no new folders, so one click on update is all it takes. ";}i:7;a:15:{s:4:"slug";s:16:"vs-code-portable";s:5:"title";s:16:"VS Code Portable";s:4:"date";s:16:"2026-10-19 07:34";s:7:"updated";s:16:"2026-10-19 07:56";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:4:{i:0;s:7:"VS Code";i:1;s:8:"portable";i:2;s:7:"pac-man";i:3;s:3:"paf";}s:11:"description";s:0:"";s:5:"image";s:52:"/~daemondevin/blog/uploads/2026/10/vscode-e7a6e2.jpg";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:203:"My VS Code Portable now runs on the newest pac-man, and that means a portable launcher that cleans up after itself even when it crashes. Every change it makes to Windows is written down before it happ…";s:5:"words";i:1766;s:7:"minutes";i:9;s:5:"plain";s:4000:"my vs code portable now runs on the newest pac man, and that means a portable launcher that cleans up after itself even when it crashes. every change it makes to windows is written down before it happens and undone when vs code closes, or on the next launch if something went wrong. if you haven't met it before: pac man https://github.com/daemondevin/pac man portableapps compiler & management is my launcher framework for portable windows apps. it's built on top of the portableapps.com launcher pal , but it isn't pal and doesn't replace it. pal deliberately stays away from apps that need services, drivers, firewall rules, scheduled tasks or shell integration. pac man exists for exactly those apps, and treats every launch like a transaction rather than an install. this post covers what changed in the framework, what that made possible for vs code portable, and the bugs that fell out along the way. the journal: every change comes with its undo the core of this release is a journal: before the launcher changes anything on your pc, it writes down how to undo that change. when the app closes, the launcher works back through the list, newest first, until nothing is left. if the launcher is killed, the pc loses power, or the usb stick gets pulled mid session, the undo steps are still in the journal. the next launch notices, tells you, and rolls back the old session before changing anything new. a few details that make this hold up in practice: it lives on the pc, not the stick. the journal is kept under hkcu\software\pac man\journal , and backup files under %localappdata%\pac man\journal , so recovery works even if the stick comes back with a different drive letter. undo steps are safe to run twice. if a recovery is itself interrupted, the next one simply picks up where it stopped. one rollback, in a fixed order. segments are undone in the reverse of the order they were applied, so nothing is removed while something else still depends on it. it covers 14 kinds of change. that's registry keys and values, files and folders, links, fonts, services, com dlls and type libraries, scheduled tasks, drivers, text lines and commands. five segments rewritten on the journal five segments were rebuilt from scratch on top of the journal this round. each one is switched on with a single line under activate and configured with numbered sections in the launcher ini. segment what it does how it's undone associations file types, url protocols and context menu entries, written under hkcu\software\classes only. it never touches windows' own default app choice; a type that already has a handler just gains an "open with" entry. new keys are deleted, replaced keys are re imported from a backup, changed values are put back. firewall temporary firewall rules through netsh, tagged so the launcher only ever removes its own. its rules are deleted; a rule someone else made is left alone. commands that need admin rights wait until they have them. tasks scheduled tasks the app needs while it runs. tasks that would store a password are refused. the task is deleted, and a task it replaced is re created from its exported xml. drivers driver packages added to the driver store for the session. the package is found by content in the driver store and removed with pnputil. runtime visual c++ and .net checks that run before anything else changes. a missing runtime can come from a portable copy put on path, or set as dotnet\ root for the app's process only. nothing to undo. the one exception, installing a runtime system wide, only happens after a prompt that says it's permanent. fonts, symlinks, regdll, services and hosts already run on the journal, so a launcher can now combine any of these and still get one clean rollback, in a fixed order, on exit or after a crash. what vs code portable gets out of it vs code portable is the first package rebuilt on all of this, and about 150 lines of hand written registry code are gone from it. here's what you'll notice: open with code por";}i:8;a:15:{s:4:"slug";s:35:"what-s-new-in-tsblog-and-themestrap";s:5:"title";s:35:"What's new in TSBlog and Themestrap";s:4:"date";s:16:"2026-10-14 15:59";s:7:"updated";s:16:"2026-10-14 16:00";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:3:{i:0;s:6:"TSBlog";i:1;s:10:"Themestrap";i:2;s:13:"release notes";}s:11:"description";s:118:"One-click updates, a friendlier writing screen, and a handful of new Themestrap plugins. Here is what changed and why.";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:144:"TSBlog has had a busy week, and a lot of the work spilled over into Themestrap, the component library it is built on. Here is the short version.";s:5:"words";i:308;s:7:"minutes";i:2;s:5:"plain";s:1785:"tsblog has had a busy week, and a lot of the work spilled over into themestrap, the component library it is built on. here is the short version. < more tsblog it can update itself. open settings, press check for updates , and if there is something new, install it with one click. every release is signed, checked before anything changes, and backed up first, so you can go back with a single button. your posts, pictures and settings are never touched. a nicer writing screen. the publish date has a proper calendar, and the time has a picker of its own or just type 8:30pm . every dropdown is now a clean custom select, the number fields have real plus and minus buttons, and the questions it asks you, such as "delete this post?", appear as dialogs instead of the browser's plain boxes. leave with unsaved changes and it asks first. tags you can paste. paste design, css, javascript and you get three tags, not one long one. it skips duplicates and tells you if a post is over its limit of twenty. better posts for readers. posts get a thin reading progress bar and a soft "keep reading" fade. both can be switched off in settings. safer sign in. the login and setup screens were rebuilt, with inline errors and a lockout countdown after too many wrong passwords. themestrap new: pluginnumberinput a styled stepper and plugintimepicker a popover time picker that pairs with the calendar . plugindialog gained confirm and alert , so replacing a browser prompt takes a few lines. pluginselect now fires normal change events and opens a long list at the selected item. plugintagsinput splits pasted lists into separate tags. pluginauth was rewritten to work with any backend, not just modx. pluginscrollshadow can fade the edge of the page, and the markdown plugins got a security fix. ";}i:9;a:15:{s:4:"slug";s:9:"analytics";s:5:"title";s:9:"Analytics";s:4:"date";s:16:"2026-10-26 05:36";s:7:"updated";s:0:"";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:0:{}s:11:"description";s:0:"";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:203:"TSBlog can show you how many people read your posts, where they came from, and which links they click. It runs on your own server: no cookies, no outside service, nothing sent anywhere. It is off unti…";s:5:"words";i:687;s:7:"minutes";i:4;s:5:"plain";s:3797:" analytics tsblog can show you how many people read your posts, where they came from, and which links they click. it runs on your own server: no cookies, no outside service, nothing sent anywhere. it is off until you turn it on under settings → analytics , and the results are under analytics at the top of the admin. what is recorded record how contains page view the server, when a page is built time, page, referring site, browser, system, device, ip address, a visitor code link click a 1 kb script assets/track.js time, the page it was on, the address clicked, the same browser details not found the server the address that did not exist clicks are counted for links to other sites, for downloads zip, pdf, office files, audio, video and similar and for email and phone links. links between your own pages are not. left out: your own visits while you are signed in, requests from bots and crawlers they are only counted, and shown as a number , the rss feed, and browser prefetching. a “visitor” is a distinct browser, worked out from a keyed hash of the address and browser. it is not a person, and it cannot be matched with anything on another site. the page choose the last 7, 30, 90 or 365 days. you get page views, visitors, link clicks and broken addresses with today's numbers; a views per day chart hover a bar for the day ; top pages; where visitors came from; links clicked; browsers, systems and devices; visitor ip addresses with request counts; addresses that were not found; and the latest 60 events. export csv downloads the raw records for the range. clear data deletes everything after asking. ip addresses and privacy an ip address can identify a person, and the law in some places the eu and uk, for instance treats it as personal data. under visitor ip addresses choose: keep the full address. the most detail. useful for spotting one visitor or a scanner. keep a shortened address. the last number of an ipv4 address is set to 0, and an ipv6 address is cut to its first three groups. do not keep addresses. the ip address list disappears. views and visitors still work. records are deleted after keep records for days 90 by default . if your visitors are in a region with privacy rules, shorten or drop the addresses and say what you collect on a privacy page. ip address cards hover or tab to any ip address on the page and a themestrap hovercard shows where it is: place, provider, time zone and whatever else the lookup service returns. the blog asks the service https://www.publicsofttools.com/api/ip geolocation?ip=address when you first hover an address, never automatically, and remembers the answer for 30 days in data/ipinfo.php , so each address is looked up once. your browser never contacts the service itself. this sends the visitor's ip address to that service, which is a disclosure to a third party. if you do not want that, store shortened or no addresses a shortened address looks up the wrong place , or point ip lookup url in config.php at a service you run. private and local addresses such as 127.0.0.1 are not sent anywhere. clear data also clears the remembered lookups. where it is stored one file per month in data/ , such as hits 2026 10.php , one line per record, behind the same guard as your other private files. a month stops growing at 25 mb. analytics are not part of the backup download. copy the hits .php files yourself if you want them. limits pages served from another cache a cdn, say are never seen by the blog, so they are not counted. a click is sent by the browser, so someone could send false ones. treat click lists as a guide. there is no location lookup, no search keywords and no time on page. keeping it small is the point. themes need no changes: the click script is added to every public page just before </body . ";}i:10;a:15:{s:4:"slug";s:12:"architecture";s:5:"title";s:12:"Architecture";s:4:"date";s:16:"2026-10-25 17:30";s:7:"updated";s:0:"";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:0:{}s:11:"description";s:0:"";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:203:"Architecture How the blog is built, for anyone who wants to understand it, change it or extend it. You do not need any of this to use the blog. Design rules - Works the moment it is uploaded. No setti…";s:5:"words";i:2331;s:7:"minutes";i:11;s:5:"plain";s:4000:" architecture how the blog is built, for anyone who wants to understand it, change it or extend it. you do not need any of this to use the blog. design rules works the moment it is uploaded. no settings file, no server rules, no root access. every feature that needs the server to cooperate has a fallback that does not. files first. posts are markdown files. the database is optional. no dependencies. no composer packages and no framework. the markdown renderer, router, feed, sitemap, settings and login are all in lib/ . one path in. every request that is not a real file goes to index.php . public pages ship almost nothing. no cookies, no framework, one stylesheet and one tiny script. folder map index.php tiny bootstrap: php version check, then lib/front.php config.sample.php optional overrides copy to config.php .htaccess, .user.ini optional extras for apache and php fpm hosts lib/ front.php public router app.php urls, http, sessions, csrf, feed, sitemap settings.php settings layers, private data files, folder setup, health checks store.php the store interface and both drivers analytics.php lite analytics: monthly guarded logs, bot and author filtering, reports, csv comments.php lite comments: storage in data/comments.php, form checks, thread and section markup media.php entry formats: validates media addresses and builds safe players markdown.php the markdown renderer admin.php the admin controller compat.php fallbacks for hosts without mbstring or ctype version.php the installed version, plus the built in update address and public key update.php the self updater vendor/ bundled third party code sodium compat, used only when php has no sodium extension views/ admin templates theme/default/ the plain public theme templates, style.css, reading.js, post.js, vendor/ theme/themestrap/ the bootstrap style theme adds functions.php for its helpers assets/admin/ admin interface: stylesheet, scripts, themestrap plugins content/posts/ markdown files file store uploads/ pictures data/ settings, password, state, caches, log tools/migrate.php copy posts between stores from a terminal tools/build release.php builds signed update and install packages publishers only, never shipped in packages release.json the file list and hashes of the installed release every file in lib/ , lib/views/ and theme/ starts with defined 'ts root' or exit; , so none of them does anything when requested directly. settings layers ts boot builds the configuration from three sources, later ones winning: 1. ts defaults in lib/settings.php 2. data/settings.php , written by the settings page 3. config.php , if present. its keys are recorded in locked , which the admin uses to grey out fields it also reads data/state.php , which holds facts the blog learned about the server, and derives: derived value from pretty pretty urls on , off , or auto with state.pretty === true guard post files protected , plain , or auto with state.exposed == false base , url script name and the request host, unless url is set private data files ts data read and ts data write store json in data/<name .php , behind the guard line <?php http response code 404 ; exit; ? . writes are atomic temp file, then rename and use mode 0600 where the host allows it. state key meaning pretty true once a clean address has reached the blog or the browser test succeeded exposed true if a visitor could download a file inside content/ , false if not, absent if unknown sqlite file the random name of the sqlite database self setup ts prepare dirs runs on every request. it creates data/ , content/posts/ and uploads/ if missing, and drops index.html and .htaccess files and a probe file content/ts probe.txt in them. all errors are silenced, because the health check reports what could not be done. the life of a request 1. the web server hands any request that is not a real file to index.php and php s serves real files itself . on php older than 8.1 a friendly page is shown instead. 2. lib/front.php loads the settings, in";}i:11;a:15:{s:4:"slug";s:8:"comments";s:5:"title";s:8:"Comments";s:4:"date";s:16:"2026-10-23 03:48";s:7:"updated";s:0:"";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:0:{}s:11:"description";s:0:"";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:132:"TSBlog has a small built in comment system. It needs no account, no database and no outside service. It is off until you turn it on.";s:5:"words";i:458;s:7:"minutes";i:3;s:5:"plain";s:2625:" comments tsblog has a small built in comment system. it needs no account, no database and no outside service. it is off until you turn it on. turning it on open settings → comments and choose a mode: mode what happens off nothing is shown and nothing is accepted. your existing comments are kept on, i approve each comment first new comments wait until you approve them on, show comments right away comments appear at once. a comment with more than two links still waits for you closed existing comments stay visible. the form is replaced by “comments are closed” comments appear under posts only, not pages. scheduled and draft posts do not accept comments. what readers see a list of approved comments, oldest first, then a form with a name, an optional email and the comment. readers can reply to a comment, one level deep. text is plain: line breaks are kept and web addresses become links marked nofollow ugc , so a spammer gets nothing from them. the email address is never shown on the site. with javascript the form sends without reloading the page. without it, the form still works and brings the reader back to the comments. moderating when comments are on, or any are waiting, a comments link appears at the top of the admin, with a count of comments waiting. the page lists every comment with approve , spam and delete . filter by waiting, approved or spam. deleting asks first. deleting a post deletes its comments, and changing a post's address keeps them with the post. spam protection each form carries a token that proves it came from your site. it lasts 24 hours, and the pages stay cacheable. a hidden field that people never see. anything that fills it in is silently dropped. a limit of 5 comments per visitor in 10 minutes and 30 per day. visitors are told apart by a keyed hash of their address, never the address itself. comments with more than two links wait for approval, even in the open mode. the same comment cannot be posted twice. length limits: name 60, comment 2000 characters. if a spam wave still gets through, switch to “i approve each comment first”. where they are stored all comments are in data/comments.php , a guarded private file like your settings, for both the file and sqlite storage options. it is included in the backup download. copy it to move comments to another install. themes a theme shows comments by calling ts comments section $post in post.php , which returns the whole section or an empty string when comments are off , and loading its own comments.js when tscomments::accepting . the markup uses tsc classes that the theme styles. see themes themes.md . ";}i:12;a:15:{s:4:"slug";s:13:"configuration";s:5:"title";s:8:"Settings";s:4:"date";s:16:"2026-10-26 05:36";s:7:"updated";s:0:"";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:0:{}s:11:"description";s:0:"";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:192:"Almost everything is changed on the Settings page in the admin. There is no file to edit. For people who want more control, an optional config.php can override the page. Both are covered here.";s:5:"words";i:1735;s:7:"minutes";i:8;s:5:"plain";s:4013:" settings almost everything is changed on the settings page in the admin. there is no file to edit. for people who want more control, an optional config.php can override the page. both are covered here. how settings work there are three layers. later ones win. 1. built in defaults. the blog works with these from the first visit. 2. the settings page. what you save is stored in data/settings.php . 3. config.php optional . for advanced users. anything set here overrides the settings page, and that setting shows as set in config.php and is greyed out in the admin. changes take effect immediately. there is nothing to restart. the settings page your blog setting what it does blog name shown in the header, page titles, the feed and social cards tagline a few words added to the home page title, such as my blog · notes on building for the web description the home page's description in search results, and the feed's description your name shown in the footer and in structured data. falls back to the blog name reading setting what it does posts per page how many posts a list shows before it paginates 1 to 50 date style how dates look on the site. choose from six styles time zone decides when scheduled posts go live and how dates are shown. detected from your browser during setup language code the language of the pages and feed, such as en , fr or pt br analytics setting what it does count visits and clicks off by default. when on, page views and link clicks are recorded and shown under analytics in the admin. see analytics analytics.md visitor ip addresses keep the full address, a shortened one the last part removed , or none. visitors are counted either way keep records for 7 to 730 days. older records are deleted automatically comments setting what it does comments off the default : no comments are shown or accepted. on, i approve each comment first: new comments wait in the admin until you approve them. on, show comments right away: comments appear at once, except any with more than two links, which wait for approval. closed: existing comments stay visible, no new ones are accepted see comments comments.md for how they work and how they are protected from spam. reading aids setting what it does show a reading progress bar on posts a thin bar at the top of the screen that fills as the reader works through the post. it measures the post's own text, so the footer and the next/previous links do not count. it hides itself when the whole post fits on screen. about 1 kb of script show a “keep reading” fade on posts a soft fade at the bottom of the screen with a small “keep reading” pill while there is more of the post to read, plus edge shadows on wide code blocks and tables. it uses themestrap's pluginscrollshadow , which needs jquery, so it adds about 110 kb to post pages. turn it off for the lightest possible pages both are on by default. they only appear on post pages, never on the home page or lists. advanced options these are folded away on purpose. the defaults suit almost everyone. footer line a short line added to the footer after the copyright. page links choice meaning automatic recommended the blog finds out whether pretty links work on your server and uses them if so always pretty addresses look like /my post . needs the server to send unknown addresses to index.php , see hosting deployment.md pretty links always plain addresses look like /index.php?r=my post . works everywhere plain links are not a problem, just longer. pretty links look nicer in search results and when shared. pretty links turn on by themselves when they can. in automatic mode the blog notices when a clean address reaches it, and it also tests your server during setup and whenever you press test my server again . if you force “always pretty” on a server that cannot do it, links break. to recover, open yoursite/index.php?r=admin/settings , which works on every server, and switch back to automatic. where posts are kept choice meaning files one file per post in c";}i:13;a:15:{s:4:"slug";s:15:"getting-started";s:5:"title";s:15:"Getting started";s:4:"date";s:16:"2026-10-17 19:00";s:7:"updated";s:0:"";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:0:{}s:11:"description";s:0:"";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:99:"From download to your first published post in about five minutes. No technical knowledge is needed.";s:5:"words";i:691;s:7:"minutes";i:4;s:5:"plain";s:3785:" getting started from download to your first published post in about five minutes. no technical knowledge is needed. what you need a web hosting account that runs php 8.1 or newer. almost every host does. if yours is older, look for php version in the hosting control panel and pick 8.1 or higher. a way to upload files: your host's file manager in the control panel or an ftp program such as filezilla. you do not need a database, a command line, or any settings. 1. upload 1. unzip the download on your computer. you will see a folder named tsblog . 2. open your host's file manager or ftp program and go to your website's main folder. it is often called public html , www or htdocs . 3. upload the contents of the tsblog folder there. to put the blog in a subfolder of your site, such as example.com/blog , create a blog folder first and upload into it. tip: if uploading many files is slow, upload the zip file itself and use the file manager's extract option. make sure you can see the hidden files .htaccess and .user.ini after uploading. your file manager may have a “show hidden files” option. they are optional, but they help. 2. open the admin in your browser, go to your site's address followed by /admin , for example https://example.com/admin . if you see a page that says welcome let’s set up your blog. , everything is working. if you see something else, open troubleshooting troubleshooting.md . do this straight away. the first person to open this page chooses the password. 3. answer three questions question notes what is your blog called? shown at the top of every page. you can change it later your name optional. shown on posts a password at least 8 characters. there is no username your time zone is detected from your browser, and the blog quietly checks your hosting to pick the best settings. click create my blog . you are signed in. if the page shows a red box titled one thing needs fixing first , follow the plain steps in it usually: set a folder's permissions to 755 in your file manager , then click check again . 4. write your first post 1. click new post . 2. type a title, press enter, and write. use the toolbar above the page for bold, headings, lists, quotes and links. to add a picture, paste it or drag it onto the page. 3. click save draft to keep it private, or publish to put it on your site. prefer to type symbols such as bold ? click markdown at the top instead of simple . your post is the same either way. the sliders button opens extra options: the web address, the publish date a future date schedules the post , tags, a summary for search engines, and a cover picture. you can ignore all of it. 5. make it yours click settings at the top of the admin. change the blog name, tagline, time zone, how many posts show per page and more. click save settings . the two sample items a welcome post and an about page can be edited or deleted from the posts list. 6. keep a backup in settings , click download a backup now and then. it gives you a zip of all your posts, pictures and settings. to restore, upload its folders back to your site. if something does not look right you see do this a page about php being too old change the php version in your hosting control panel to 8.1 or higher a red “needs fixing” box follow the steps in it. it is almost always one folder permission long addresses like index.php?r=about nothing is wrong. your server uses plain links. see settings configuration.md page links if you want pretty ones anything else troubleshooting troubleshooting.md where to go next i want to... read learn the editor and markdown writing writing.md change settings settings configuration.md change how the site looks themes themes.md move to another host, or tune the server hosting and deployment deployment.md ";}i:14;a:15:{s:4:"slug";s:8:"security";s:5:"title";s:8:"Security";s:4:"date";s:16:"2026-10-26 05:36";s:7:"updated";s:0:"";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:0:{}s:11:"description";s:0:"";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:60:"What the blog protects, how, and what is left for you to do.";s:5:"words";i:1179;s:7:"minutes";i:6;s:5:"plain";s:4004:" security what the blog protects, how, and what is left for you to do. the model one author, one password, a mostly static public site. the public pages have no forms, no cookies and no user input except the search box. everything that changes content sits behind the admin sign in. the blog is designed for hosting you do not control: no server rules are needed for it to be safe. protection that works on any server many blogs depend on .htaccess or nginx rules to hide private files. those rules are ignored on some hosts, so this blog does not rely on them. what how it stays safe password, settings, caches, logs stored as php files that start with <?php http response code 404 ; exit; ? . if a server hands one out instead of running it, the visitor sees nothing post files stored as .md.php with the same guard line whenever the server might hand out files. the blog tests for that during setup. see storage storage.md plain and protected files sqlite database given a random name, so it cannot be guessed engine files in lib/ each starts with a check that stops them from running outside the blog folder listings index.html files in the private folders extra layer on apache .htaccess files deny direct access too test it yourself: open yoursite/data/admin.php and yoursite/config.php . each should show a blank page or "not found". what is built in sign in protection detail password storage hashed with php's password hash bcrypt by default . the plain password is never stored strength at least eight characters when you set it brute force five wrong passwords within 15 minutes lock that address out for 10 minutes. the sign in form shows a live countdown for the lockout sign in form built on themestrap's pluginauth . with javascript it answers inline without reloading the page. without javascript it is an ordinary form post. redirects after sign in are limited to this site session a fresh random id is issued at sign in. the cookie is http only, samesite=lax , and secure on https. session files live in the blog's private folder when it can write there requests protection detail csrf every state changing request needs a per session token, compared in constant time headers x content type options: nosniff , referrer policy: strict origin when cross origin , x frame options: sameorigin content security policy public pages allow scripts, styles and fonts from your own site only. inline scripts do not run, anywhere. admin pages, and post pages while the “keep reading” fade is on, additionally allow inline styles, which the themestrap plugins inject. turning the fade off restores the strictest policy on posts admin pages marked noindex and never cached error messages hidden from visitors by default and saved to a private log instead content protection detail markdown output raw html is escaped by default, so a post cannot inject script links and images only http , https , mailto and tel links and only http and https images survive. javascript: and data: urls are removed output escaping every template value goes through e addresses validated against ^ a z0 9 + a z0 9 + $ , so a request cannot reach other files, and ../ never works reserved addresses names the blog uses cannot be taken by a post uploads protection detail type check the file's real content must be a jpg, png, gif or webp image. a renamed script is rejected. svg is not accepted size limited to what the server allows, and never above 8 mb names rebuilt from the original name plus a random suffix, with a safe extension chosen from the detected type execution uploads/.htaccess stops script handling on apache. on other servers, uploads are only ever created as image files updates the built in updater does not trust the network. every release is signed with an ed25519 key, and the blog verifies the signature against the key already installed before it unpacks anything. it also checks the download's sha 256, refuses any file outside the program folders, refuses links and .. paths, checks that";}i:15;a:15:{s:4:"slug";s:7:"storage";s:5:"title";s:7:"Storage";s:4:"date";s:16:"2026-10-26 05:36";s:7:"updated";s:0:"";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:0:{}s:11:"description";s:0:"";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:103:"Where your posts and settings live, how the two storage options differ, and what each file in data/ is.";s:5:"words";i:848;s:7:"minutes";i:4;s:5:"plain";s:4012:" storage where your posts and settings live, how the two storage options differ, and what each file in data/ is. two options, one behavior the blog stores posts in either files or sqlite . everything else behaves identically: the admin, the public site, the feed, search and tags. switch any time under settings → advanced → where posts are kept . switching copies your posts across for you and leaves the old copy in place. files default sqlite where posts live content/posts/ , one file per post one file in data/ , named like blog 3f9a….db needs nothing sqlite support in php most hosts have it; the admin tells you if not edit with the admin, or any text editor or ftp the admin, or any sqlite tool version control excellent. readable diffs poor. one binary file backups copy a folder copy one file best for almost everyone hosts where many small files are awkward if unsure, keep the default. the database file has a random name that is stored in data/state.php , so nobody can guess its address and download it. post files each post is a markdown file with front matter. see writing writing.md front matter for every field. content/posts/ welcome to your blog.md about.md plain and protected files some servers hand out any file they are asked for. on such a server, someone could type the address of a draft and read it. the blog guards against that. format file name when plain my post.md your server keeps private folders private protected my post.md.php your server does not, or the blog could not tell a protected file starts with one extra line: <?php http response code 404 ; exit; ? title: my post ... if a server runs it instead of handing it out, the visitor gets an empty "not found" page and never the text. the blog reads both formats at any time, and rewrites all posts when the format changes. settings → advanced → post file format lets you force either one. when editing a protected file by hand, keep its first line. the blog picks the format by testing your server during setup and when you press test my server again : it checks whether a harmless file in the private content/ folder can be downloaded. writing files by hand you can create, edit, rename and delete post files directly, with or without the admin. the blog notices changes on the next visit. a minimal post: title: my post date: 2026 10 02 hello. name it with lowercase letters, numbers and dashes, such as my post.md . files with other names are ignored. sqlite posts live in one table, created on first use: column holds slug primary key the address title , date , updated , status , type as in front matter tags a json array description , image as in front matter body the markdown excerpt , words , plain prepared when saving, for fast lists and search it uses write ahead logging, so reading while saving is safe. what is in data/ everything here is private, and every .php file starts with a guard line so it is safe even if a server hands it out. file holds settings.php what you saved on the settings page admin.php your password, hashed. the password itself is never stored hits yyyy mm.php analytics records, one file per month, one line per visit or click. not included in the backup. delete them to clear analytics ipinfo.php remembered ip address lookups for the analytics hover cards 30 days . safe to delete comments.php every comment, whichever storage option you use. included in the backup. delete it to remove all comments state.php what the blog learned about your server pretty links, private files and the sqlite file name login.php failed sign in counts, for the lockout index.cache.php a quick index of your posts. rebuilt on its own, safe to delete log.php the last 100 problems the blog recorded sessions/ who is signed in backups/ the program files replaced by the last two updates, for go back updating.lock exists only while an update runs, and is ignored after five minutes blog ….db the sqlite database, only if you use it index.html and .htaccess files in the private folders k";}i:16;a:15:{s:4:"slug";s:15:"troubleshooting";s:5:"title";s:15:"Troubleshooting";s:4:"date";s:16:"2026-10-17 19:00";s:7:"updated";s:0:"";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:0:{}s:11:"description";s:0:"";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:202:"Troubleshooting Find what you see, then follow the fix. A checklist is at the end. Most problems are one folder permission or one setting. First stop: sign in and open Settings. The Health section at…";s:5:"words";i:2119;s:7:"minutes";i:10;s:5:"plain";s:4038:" troubleshooting find what you see, then follow the fix. a checklist is at the end. most problems are one folder permission or one setting. first stop: sign in and open settings . the health section at the bottom checks your server and explains in plain words what is wrong and how to fix it. before you can sign in i see “one quick change is needed” about php your hosting runs an old php. in your hosting control panel look for php version or select php version , choose 8.1 or higher, and reload. the setup page shows a red box, “one thing needs fixing first” the blog cannot write to a folder. in your file manager, right click the folder named in the box, choose permissions , and set it to 755 . click check again . if the box stays, try 775 , then 777 . only the home page works, other addresses say “not found” that cannot happen with plain links, so check for these: you switched page links to always pretty on a server that cannot do it. open yoursite/index.php?r=admin/settings this address works on every server , set page links to automatic , and save. you are using a configuration file that forces 'pretty urls' = 'on' . remove that line. a blank white page php hit an error and is hiding it. in a file manager, open data/log.php or ask your host for the php error log . or create a config.php with <?php return 'debug' = true ; to see the message on the page, then delete it afterward. “the blog could not start” the message on the page says why. common ones: message fix this server does not have sqlite support open yoursite/index.php?r=admin/settings and choose files for storage, or set 'store' = 'files' in config.php anything about a folder set that folder's permissions as described above the page has no styling the theme/ folder was not uploaded, or settings names a theme that does not exist the blog falls back to default automatically . upload the whole theme folder again. i can’t sign in, or i keep landing back on the sign in form the browser must accept cookies for your site. the blog must be able to write to the data folder see the permissions fix above . after five wrong passwords, wait ten minutes, or delete data/login.php . i forgot my password 1. in your file manager, delete the file data/admin.php . 2. open yoursite/admin . it asks you to choose a new password, like the first time. if you set admin password hash in config.php , replace it with a new hash instead see settings configuration.md the optional configphp . because this works by file access, anyone who can write to data/ can reset the password, so keep that folder private. after you are in the links are long and look like index.php?r=… nothing is wrong. your server uses plain links, which work everywhere. if you want pretty ones and you use apache, make sure the hidden file .htaccess was uploaded, then press test my server again in settings. see hosting deployment.md pretty links . my post is not on the site 1. status. a draft is hidden. open it and click publish. 2. date. a future date means scheduled. it appears when the time comes, in your time zone see settings . 3. type. a page appears in the menu, not in the post list. 4. hand made files. the file name must be lowercase letters, numbers and dashes, ending .md or .md.php , and the front matter must start on the first line after the guard line, in protected files . the summary on the home page is wrong a summary typed in the post settings always wins. clear it to use the automatic one. otherwise type < more on its own line where you want the summary to end. see writing writing.md the summary marker . “the address … is reserved” or “another post already uses the address” pick another address in the post's settings panel. reserved names are listed in writing writing.md reserved addresses . “your session expired” when saving you were signed out. copy your text, reload, and sign in again. the editor also keeps a copy in the browser and offers to restore it. “the blog could not save your post” the content/posts fol";}i:17;a:15:{s:4:"slug";s:7:"updates";s:5:"title";s:7:"Updates";s:4:"date";s:16:"2026-10-23 03:52";s:7:"updated";s:0:"";s:6:"status";s:9:"published";s:4:"type";s:4:"post";s:4:"tags";a:0:{}s:11:"description";s:0:"";s:5:"image";s:0:"";s:6:"format";s:8:"standard";s:5:"media";a:0:{}s:7:"excerpt";s:205:"The blog can check for a new version, download it, and install it for you. It is one button in Settings → Updates. This page explains how it works, how it keeps you safe, and (for whoever publishes th…";s:5:"words";i:2110;s:7:"minutes";i:10;s:5:"plain";s:4006:" updates the blog can check for a new version, download it, and install it for you. it is one button in settings → updates . this page explains how it works, how it keeps you safe, and for whoever publishes the blog how to release a new version. for site owners updating 1. open settings and scroll to updates . if a newer version exists you will also see a banner on the posts page. 2. click check for updates to look right now. it also looks by itself about once a day when you open the admin, unless you turn that off under advanced options. 3. read what is new, then click install version x . confirm. 4. the site pauses for a few seconds. when the page reloads you are on the new version. your posts, pictures, settings, password, config.php and any theme of your own are never touched. only the blog's own program files change. going back if something looks wrong after an update, click go back to x in the same place. it puts every file back exactly as it was. each update keeps a backup; the last two are kept, so you can step back twice. what an update changes updated never touched index.php , lib/ , assets/ , tools/migrate.php , docs/ , theme/default/ , theme/themestrap/ , config.sample.php , readme.md , release.json content/ , uploads/ , data/ , config.php , .htaccess , .user.ini , any theme other than default and themestrap if you edited files in theme/default/ , an update replaces them. copy the theme to a name of your own first and select it in settings see themes themes.md . what it needs the updates card tells you in plain words if something is missing. normally nothing is. need why an update address and a signing key built into releases made with the release tool. otherwise set the address under settings → advanced and the key in config.php the zip php extension to unpack the update. almost every host has it signature checking uses php's sodium extension when there is one, and a bundled pure php copy when there is not. nothing to install either way. see no sodium extension no sodium extension a way to download curl, or allow url fopen writable program folders the same permissions that let the blog save posts. usually already true on shared hosting if your server cannot update itself, you can still update by hand. see manual updating manual updating . privacy a check downloads one small file, latest.json , from the update address. the request carries the blog's version in the user agent themestrapblog/1.0.0 and nothing else about you or your site. turn automatic checks off under settings → advanced and the blog only looks when you press the button. how it keeps you safe an update is code that runs on your site, so the blog does not simply trust whatever it downloads. check what it prevents https only someone tampering with the download in transit sha 256 checksum a damaged or substituted file ed25519 signature, checked against the key already installed a hacked download server pushing code. only the holder of the publisher's secret key can make an update the blog accepts. the signature covers the version too, so an old signed release cannot be replayed as "new" every file inside must be a plain file in an allowed folder updates reaching your content, settings, config.php or other themes, and ../ tricks, absolute paths and links every file's hash must match the package's file list a package with swapped or extra files every php file must parse a broken release taking the site down backup first, then verify after writing a failure half way. anything that goes wrong puts the old files back automatically a short maintenance pause visitors seeing a half updated site all of these happen before the first file changes, except the last two. no sodium extension signature checking needs ed25519. almost every php has it built in it has shipped with php since 7.2 , but some hosts compile it out. in that case the blog uses lib/vendor/sodium compat , an open source pure php implementation of the same algorithm isc license, bundled unmodified";}}}