Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Link Menu System

A self-hostable link portal: a responsive grid of your organization's links, set as everyone's browser new-tab / start page — plus a canary router that makes sure a device off the office network never lands on a "page not found."

No database, no framework, no build step. Two PHP pages over flat-file JSON.

  • Portal (lms-menu/index.php) — the panel grid, with inline admin editing (edit links, panels, headings, banner, and settings in place; drag-and-drop reorder; hide/delete panels). Renders from config.json.
  • Canary router (lms-router/index.php) — the page you actually set as the start URL. It loads a tiny "canary" image that only exists on the internal server: if it loads, redirect to the internal portal; if it errors or times out (3s), redirect to a public fallback URL. Reads router-config.json.

Requirements

  • A web host that runs PHP (no extensions or database needed).
  • The two halves are usually deployed to two locations: the portal on an internal/in-house server, the router on the public web. For a demo they can sit side by side.

Install

For the full walkthrough — verifying both branches and troubleshooting — see INSTALL.md. The short version:

  1. Unpack this bundle on your web host. Serve lms-menu/index.php and lms-router/index.php as index.php at whatever paths you choose (e.g. lms-menu/ internal, lms-router/ public).
  2. Portal first run: browse to the portal. It auto-creates config.json (seeded with a sample layout) and walks you through creating a single admin account (stored bcrypt-hashed inside config.json). Log in via the small lock icon in the footer, then edit in place.
  3. Canary image: the portal ships a real 1×1 lms-menu/canary.png. The router probes this to detect the internal server. Keep it a valid, tiny, loadable image — an empty/broken file makes the router always fall back to external.
  4. Router config: the router auto-creates router-config.json with placeholders. Edit it so:
    • internal_url → your internal portal URL
    • external_url → your public fallback URL
    • canary_image → the URL of the portal's canary.png on the internal server
  5. Set the router URL as the browser start / new-tab page on your devices.

Instance state (not shipped, not committed)

These files are generated/edited on the server and are not part of this bundle:

  • config.json — portal layout, site settings, and the bcrypt-hashed admin credential created at first-run setup (auto-generated on first run)
  • router-config.json — the router URLs (auto-generated, then edited)

Security note: config.json (which holds the hashed admin credential) lives inside the webroot, so it may be fetchable by URL. The bundle ships a .htaccess denying *.json on Apache/LiteSpeed; nginx users add the equivalent from NGINX.md. Moving these outside the webroot via APP_* env vars is optional per-deployment hardening, not something the stock install does. Don't put real credentials on a public host before at least the deny rule is in place.

Versioning

Each PHP file carries an internal lms <build>.<ts6> stamp near the top. Auto-generated JSON files carry a _lms_version field tying the data to the code that generated it.

License

MIT — see LICENSE. © 2026 smisco <info@smisco.biz> Website: https://smisco.biz/lms

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages