# sqlite-serve - SQLite Module for NGINX A dynamic NGINX module written in Rust that integrates SQLite databases with Handlebars templating, enabling data-driven web applications directly from NGINX configuration. ## Features ✅ **SQLite Integration** - Query SQLite databases from NGINX ✅ **Handlebars Templates** - Render dynamic HTML with template inheritance ✅ **Parameterized Queries** - Safe SQL parameters from nginx variables ✅ **Global & Local Templates** - Template reuse with override support ✅ **Zero Application Server** - Serve data-driven pages directly from NGINX ## Quick Start ### 1. Build the Module ```bash direnv exec "$PWD" cargo build ``` ### 2. Run the Book Catalog Example ```bash ./start_book_catalog.sh ``` Visit http://localhost:8080/books/all ### 3. Run the Parameters Example ```bash ./start_book_detail.sh ``` Visit http://localhost:8081/book?id=1 ## Examples ### Example 1: Book Catalog (Port 8080) A full-featured catalog with category browsing, global templates, and responsive UI. **Features:** - Browse all books or filter by category - Shared header/footer/card templates - Modern gradient UI design - Multiple category pages **See:** `conf/book_catalog.conf` and `README_BOOK_CATALOG.md` ### Example 2: Positional Parameters (Port 8081) Demonstrates dynamic SQL queries with positional parameters. **Features:** - Query parameters with `?` placeholders - Multiple positional parameters - Safe prepared statement binding **See:** `conf/book_detail.conf` ### Example 3: Named Parameters (Port 8082) - Recommended Demonstrates named SQL parameters for better readability. **Features:** - Named parameters with `:name` syntax - Order-independent parameter binding - Title search with LIKE operator - Rating filtering - More maintainable configuration **See:** `conf/book_named_params.conf` and `README_PARAMETERS.md` ## Configuration Directives ### `sqlite_db` Set the SQLite database file path. **Syntax:** `sqlite_db path;` **Context:** `location` ### `sqlite_query` Define the SQL SELECT query to execute. **Syntax:** `sqlite_query "SELECT ...";` **Context:** `location` **Notes:** Use `?` placeholders for parameters ### `sqlite_template` Specify the Handlebars template file (relative to location path). **Syntax:** `sqlite_template filename.hbs;` **Context:** `location` **Notes:** Sets the content handler for the location ### `sqlite_param` Add a parameter to the SQL query (can be used multiple times). **Syntax:** - Positional: `sqlite_param $variable_or_value;` - Named: `sqlite_param :param_name $variable_or_value;` **Context:** `location` **Notes:** - Positional parameters match `?` placeholders in order - Named parameters match `:name` placeholders by name (recommended) ### `sqlite_global_templates` Set a directory for global template files (partials, layouts). **Syntax:** `sqlite_global_templates directory;` **Context:** `http` ## Basic Example ```nginx http { sqlite_global_templates "templates/global"; server { listen 8080; root "public"; # Simple query without parameters location = /books { sqlite_db "catalog.db"; sqlite_query "SELECT * FROM books ORDER BY title"; sqlite_template "list.hbs"; } # Parameterized query with named parameter (recommended) location = /book { sqlite_db "catalog.db"; sqlite_query "SELECT * FROM books WHERE id = :book_id"; sqlite_param :book_id $arg_id; sqlite_template "detail.hbs"; } # Positional parameters also supported location = /search { sqlite_db "catalog.db"; sqlite_query "SELECT * FROM books WHERE year >= ? AND year <= ?"; sqlite_param $arg_min; # First ? sqlite_param $arg_max; # Second ? sqlite_template "list.hbs"; } } } ``` ## Template System ### Template Resolution Templates are resolved as: `{document_root}{uri}/{template_name}` Example: - `root "public"` - `location /books` - `sqlite_template "list.hbs"` - Resolved to: `public/books/list.hbs` ### Global Templates Place shared templates (headers, footers, partials) in a global directory: ```nginx http { sqlite_global_templates "templates/shared"; } ``` All `.hbs` files in this directory are automatically loaded as partials (referenced without `.hbs` extension): ```handlebars {{> header}}