Pinakes
Complete Library Management System (ILS) - Circulation, OPAC, cataloging, reservations, loans, automatic notifications, plugin system, and Z39.50/SRU server
Install / Use
/learn @fabiodalez-dev/PinakesREADME
Pinakes 📚
Open-Source Integrated Library System License: GPL-3 | Languages: Italian, English, German
Pinakes is a self-hosted, full-featured ILS for schools, municipalities, and private collections. It focuses on automation, extensibility, and a usable public catalog without requiring a web team.
What's New in v0.5.3
🔍 Cross-Version Consistency Fixes (v0.4.9.9–v0.5.2)
descrizione_plainpropagated — Catalog FULLTEXT search and admin grid now useCOALESCE(NULLIF(descrizione_plain, ''), descrizione)for LIKE conditions, completing the HTML-free search feature from v0.4.9.9- ISSN in Schema.org & API —
issnproperty now emitted in Book JSON-LD and returned by the public API (/api/books) - CollaneController atomicity —
rename()aborts onprepare()failure instead of committing partial state - LibraryThing import aligned —
descrizione_plain(withhtml_entity_decode+ spacing), ISSN normalization,AuthorNormalizeron traduttore, soft-delete guards on all UPDATE queries, anddescrizione_plaincolumn conditional (safe on pre-0.4.9.9 databases) - Secondary Author Roles — LT import now routes translators to
traduttorefield based onSecondary Author Roles
Previous Releases
<details> <summary><strong>v0.5.2</strong> - Name Normalization (#93)</summary>🔧 Name Normalization for Translators, Illustrators, Curators (#93)
AuthorNormalizerapplied to translator, illustrator, and curator on create, update, and scraping- Client-side normalization — "Surname, Name" → "Name Surname" for translator/illustrator in book form
- Shared
normalizeAuthorName()JS helper across authors, translator, illustrator
📚 ISSN, Series Management, Multi-Volume Works (#75)
ISSN Field:
- New ISSN field on book form with XXXX-XXXX validation (server-side + client-side)
- Displayed on frontend book detail and in public API responses
- Schema.org
issnproperty emitted in JSON-LD
Series (Collane) Management:
- Admin page
/admin/collane— List all series with book counts, create, rename, merge, delete - Series detail page — Description editor, book list with volume numbers, autocomplete merge
- Bulk assign — Select multiple books and assign to a series from the book list
- Search autocomplete — Series name suggestions in merge and bulk assign dialogs
- Empty series preserved — Series with no books still appear in the admin list
- Frontend "Same series" section — Book detail shows other books in the same series
Multi-Volume Works:
volumitable — Links parent works to individual volumes with volume numbers- Admin UI — Add/remove volumes via search modal, volume table on book detail
- Parent work badge — "This book is volume X of Work Y" badge with link
- Cycle prevention — Full ancestor-chain walk prevents circular relationships
- Create from collana — One-click creation of parent work from a series page
Import Improvements:
- LibraryThing Series parsing — Splits
"Series Name ; Number"into separate collana + numero_serie - Scraping series split — Same parsing for ISBN scraping results
- CSV/TSV import —
collanafield already supported with multilingual aliases
Bug Fixes & Improvements:
- ISSN validation — Explicit error message instead of silent discard
- Transactions — Delete, rename, merge collane wrapped in DB transactions
- Error handling — execute() results checked in all AJAX endpoints
- Soft-delete guards — addVolume rejects deleted books, updateOptionals includes guard
- Migration resilience —
hasCollaneTable()guard for partial migration scenarios - Non-numeric volume sorting — Special volumes sort after numbered ones
- Unified search fix — Add-volume modal correctly parses flat array response
🔍 SEO & LLM Readiness, Schema.org Enrichment, Curator Field
- Hreflang alternate tags on all frontend pages
- RSS 2.0 feed at
/feed.xml - Dynamic
/llms.txtendpoint (admin-toggleable) - Schema.org enrichment — Book
sameAs, all author roles,bookEdition, conditionalOffer - New
curatorefield — Database, form, admin detail, Schema.orgeditor - CSV column shift fix (#83), admin genre display fix (#90)
📤 Social Sharing, Genre Navigation, Inline PDF Viewer & Search
- 7 sharing providers — Facebook, X, WhatsApp, Telegram, LinkedIn, Reddit, Pinterest + Email, Copy Link, Web Share API
- Genre breadcrumb navigation — Clickable genre hierarchy links that filter by category
- Inline PDF viewer — Browser-native
<iframe>PDF viewer (Digital Library plugin v1.3.0) - Description-inclusive search — New
descrizione_plaincolumn for HTML-free search - RSS icon in footer — SVG feed icon next to "Powered by Pinakes"
- Auto-hook registration — Plugin hooks auto-registered on page load
🔒 Security & Database Integrity
- SMTP password encryption — AES-256-CBC at rest using
APP_KEY - isbn10/ean UNIQUE indexes — Blank values normalized to NULL, duplicates resolved
- prestiti FK fix — Foreign key corrected to reference
utenti(id) - Email notification test suite — 16 Playwright E2E tests covering all email types
⚡ Quick Start
- Clone or download this repository and upload all files to the root directory of your server.
- Visit your site's root URL in the browser — the guided installer starts automatically.
- Provide database credentials (database must be empty).
- Select language (Italian, English, or German).
- Configure organization name, logo, and email notifications.
- Create admin account and start cataloging.
Email configuration: Supports both PHP mail() and SMTP. Required for notifications to work (loan confirmations, due-date reminders, registration approvals, reservation alerts). Can be configured during installation or later from the admin panel.
Post-install (optional but recommended):
- Remove/lock the
installer/directory (button provided on final step) - Configure SMTP, registration policy, and CMS blocks from Admin → Settings
- Schedule cron jobs for automated tasks:
# Notifications every hour (8 AM - 8 PM) 0 8-20 * * * /usr/bin/php /path/to/cron/automatic-notifications.php >> /var/log/biblioteca-cron.log 2>&1 # Full maintenance at 6 AM (handles reservation/pickup expirations) 0 6 * * * /usr/bin/php /path/to/cron/full-maintenance.php >> /var/log/biblioteca-maintenance.log 2>&1
All frontend assets are precompiled. Works on shared hosting. No Composer or build tools required on production. All configuration values can be changed later from the admin panel.
Story Behind the Name
Pinakes comes from the ancient Greek word πίνακες ("tables" or "catalogues"). Callimachus of Cyrene compiled the Pinakes around 245 BC for the Library of Alexandria: 120 scrolls that indexed more than 120,000 works with authorship, subject and location. This project borrows that same mission—organising and sharing knowledge with modern tools.
Full documentation: fabiodalez-dev.github.io/Pinakes
What It Does
Pinakes provides cataloging, circulation, a self-service public frontend, and REST APIs out of the box. It ships with precompiled frontend assets and a guided installer so you can deploy quickly on standard LAMP hosting.
