# GitCitadel Online A server-generated static website that fetches content from Nostr relays, processes AsciiDoc articles, and serves professional HTML pages with intelligent caching. Built with Go and designed for decentralized content publishing. ## Features - **Wiki System**: Fetches and displays wiki articles (kind 30818) from Nostr relays - **Blog & Articles**: Supports blog posts and longform articles (kind 30023) with full markdown/AsciiDoc processing - **E-Books Library**: Displays e-books and publications (kind 30040) from Nostr - **Feed Integration**: Real-time kind 1 feed integration in sidebar - **Contact Form**: Nostr-based contact form with browser extension support and anonymous submission - **AsciiDoc Processing**: Full AsciiDoc to HTML conversion with table of contents support - **Intelligent Caching**: Multi-layer caching system with background rewarming - **Media Caching**: Automatic caching of external images and media - **SEO Optimized**: Structured data, sitemaps, and meta tags - **Responsive Design**: Mobile-first responsive design with medium-dark theme - **Accessibility**: WCAG AA/AAA compliant with proper ARIA labels and keyboard navigation - **Content Security Policy**: Secure CSP headers for XSS protection ## Requirements - **Go 1.22+** - For building and running the server - **Node.js** - For AsciiDoc processing - **@asciidoctor/core** - npm package for AsciiDoc conversion - **Network access** - To connect to Nostr relays ## Installation 1. **Clone the repository:** ```bash git clone cd gitcitadel-online ``` 2. **Install Go dependencies:** ```bash go mod tidy ``` 3. **Install Node.js dependencies:** ```bash npm install @asciidoctor/core ``` Or install globally: ```bash npm install -g @asciidoctor/core ``` 4. **Download nostr-tools bundle (for contact form):** ```bash mkdir -p static/js curl -L -o static/js/nostr.bundle.js https://unpkg.com/nostr-tools@latest/lib/nostr.bundle.js ``` Note: The nostr-tools library is hosted locally to avoid dependency on external CDNs. 5. **Copy and configure:** ```bash cp config.yaml.example config.yaml ``` Edit `config.yaml` with your Nostr indices, relay URLs, and settings. ## Configuration Edit `config.yaml` to configure: ### Required Settings - `wiki_index`: naddr for your wiki index (kind 30040) - `blog_index`: naddr for your blog index (kind 30040) - `repo_announcement`: naddr for repository announcement (for contact form) - `relays.feeds`: Primary relay URL for fetching content - `relays.profiles`: Comma-separated relay URLs for profile data - `relays.contactform`: Comma-separated relay URLs for contact form submissions ### Optional Settings - `link_base_url`: Base URL for external links (default: Alexandria) - `cache.refresh_interval_minutes`: How often to refresh cached pages (default: 30) - `feed.poll_interval_minutes`: How often to poll for new feed items (default: 5) - `feed.max_events`: Maximum number of feed items to display (default: 30) - `server.port`: HTTP server port (default: 8080) - `server.enable_compression`: Enable gzip compression (default: true) - `seo.site_name`: Site name for SEO - `seo.site_url`: Canonical site URL - `seo.default_image`: Default OpenGraph image path ### Example Configuration ```yaml wiki_index: "naddr1qvzqqqr4tqpzplfq3m5v3u5r0q9f255fdeyz8nyac6lagssx8zy4wugxjs8ajf7pqyd8wumn8ghj7..." blog_index: "naddr1qvzqqqr4tqpzplfq3m5v3u5r0q9f255fdeyz8nyac6lagssx8zy4wugxjs8ajf7pqyvhwumn8ghj7..." repo_announcement: "naddr1qvzqqqrhnypzplfq3m5v3u5r0q9f255fdeyz8nyac6lagssx8zy4wugxjs8ajf7pqq9xw6t5vd5hgctyv4kqde47kt" relays: feeds: "wss://theforest.nostr1.com" profiles: "wss://theforest.nostr1.com,wss://nostr.land" contactform: "wss://thecitadel.nostr1.com,wss://relay.damus.io" server: port: 8080 enable_compression: true seo: site_name: "GitCitadel" site_url: "https://gitcitadel.com" ``` ## Running ### Development Mode Run with verbose logging: ```bash go run cmd/server/main.go --dev ``` ### Production Mode Build and run: ```bash go build -o gitcitadel-online cmd/server/main.go ./gitcitadel-online ``` ### Command Line Options - `--config `: Path to configuration file (default: `config.yaml`) - `--dev`: Enable development mode with verbose logging - `--log-level `: Set log level (debug, info, warn, error) (default: info) ## Routes & Endpoints ### Public Pages - `/` - Landing page with feed sidebar - `/wiki` - Wiki index page - `/wiki/` - Individual wiki article pages - `/blog` - Blog index page with article navigation - `/articles` - Longform articles index page - `/ebooks` - E-books library with sortable table - `/feed` - Feed page with relay information - `/contact` - Contact form with Nostr integration ### Static Assets - `/static/` - Static files (CSS, JavaScript, images, icons) - `/cache/media/` - Cached external media files - `/favicon.ico` - Site favicon ### API Endpoints - `/api/contact` - POST endpoint for submitting contact form events (JSON) ### System Endpoints - `/health` - Health check endpoint - `/metrics` - Metrics endpoint (Prometheus format) - `/sitemap.xml` - XML sitemap for search engines - `/robots.txt` - Robots.txt file ## Project Structure ``` gitcitadel-online/ ├── cmd/ │ └── server/ # Main server application entry point ├── internal/ │ ├── asciidoc/ # AsciiDoc processing with Node.js │ ├── cache/ # Multi-layer caching system │ │ ├── cache.go # Page cache │ │ ├── feed_cache.go # Feed item cache │ │ └── media_cache.go # Media file cache │ ├── config/ # Configuration management │ ├── generator/ # HTML generation and SEO │ ├── logger/ # Structured logging │ ├── nostr/ # Nostr client and event parsing │ │ ├── client.go # Relay connection management │ │ ├── wiki.go # Wiki event parsing │ │ ├── profile.go # Profile metadata │ │ ├── feed.go # Feed event parsing │ │ ├── ebooks.go # E-book parsing │ │ └── issues.go # Issue/contact form handling │ └── server/ # HTTP server and handlers ├── static/ # Static assets │ ├── css/ # Stylesheets │ ├── icons/ # SVG icons │ └── js/ # JavaScript libraries ├── templates/ # HTML templates │ ├── base.html # Base template │ ├── landing.html # Landing page │ ├── wiki.html # Wiki pages │ ├── blog.html # Blog pages │ ├── articles.html # Article pages │ ├── ebooks.html # E-books page │ ├── feed.html # Feed page │ ├── contact.html # Contact form │ └── components.html # Reusable components ├── cache/ # Runtime cache directory │ └── media/ # Cached media files ├── config.yaml # Configuration file (not in repo) ├── config.yaml.example # Example configuration ├── go.mod # Go module dependencies ├── package.json # Node.js dependencies └── README.md # This file ``` ## Development ### Building ```bash go build -o gitcitadel-online cmd/server/main.go ``` ### Testing The server uses a caching system that pre-generates all pages. On first run, pages will be generated and cached. Subsequent requests serve from cache until the refresh interval. ### Cache Management - Pages are cached in memory for fast serving - Cache rewarming runs in the background at configured intervals - Media files are cached to disk in `cache/media/` - Cache can be cleared by restarting the server ### Logging Logs are structured and can be configured via: - `--log-level` flag (debug, info, warn, error) - `--dev` flag enables debug logging and verbose output ## Content Types Supported ### Wiki Articles (Kind 30818) - AsciiDoc content processing - Table of contents generation - Cross-referencing support - Syntax highlighting ### Blog Posts (Kind 30023) - Markdown/AsciiDoc content - Image support with caching - Author profiles - Timestamps and metadata ### E-Books (Kind 30040) - Publication listings - Author information - Sortable table interface - Links to Alexandria library ### Feed Items (Kind 1) - Real-time note display - Author badges with profiles - Timestamp formatting - Content rendering ## Contact Form The contact form supports two submission methods: 1. **Browser Extension**: Users can sign with their Nostr browser extension (nos2x, Alby, etc.) 2. **Anonymous**: Server generates a temporary key pair for anonymous submissions Both methods publish kind 1 events to configured relays with proper tags for issue tracking. ## Security - Content Security Policy (CSP) headers prevent XSS attacks - All external scripts are hosted locally - Input validation on contact form - Event signature verification for API submissions - Secure relay connections (WSS) ## Performance - Multi-layer caching (memory + disk) - Background cache rewarming - Gzip compression support - Optimized static asset serving - Efficient Nostr event parsing ## License MIT License - see LICENSE.md for details ## Contributing Contributions are welcome! Please ensure: - Code follows Go conventions - Templates are accessible (WCAG AA/AAA) - All routes are documented - Configuration changes are backward compatible