5 changed files with 409 additions and 96 deletions
@ -1,109 +1,290 @@ |
|||||||
# GitCitadel Online |
# GitCitadel Online |
||||||
|
|
||||||
A server-generated website that fetches kind 30818 wiki events from Nostr relays, processes AsciiDoc content, and serves professional HTML pages with caching. |
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 |
## Features |
||||||
|
|
||||||
- Fetches wiki content from Nostr relays (kind 30818 events) |
- **Wiki System**: Fetches and displays wiki articles (kind 30818) from Nostr relays |
||||||
- Processes AsciiDoc content to HTML |
- **Blog & Articles**: Supports blog posts and longform articles (kind 30023) with full markdown/AsciiDoc processing |
||||||
- Caches all pages for fast serving |
- **E-Books Library**: Displays e-books and publications (kind 30040) from Nostr |
||||||
- Background cache rewarming to keep content fresh |
- **Feed Integration**: Real-time kind 1 feed integration in sidebar |
||||||
- Kind 1 feed integration in sidebar |
- **Contact Form**: Nostr-based contact form with browser extension support and anonymous submission |
||||||
- SEO optimized with structured data |
- **AsciiDoc Processing**: Full AsciiDoc to HTML conversion with table of contents support |
||||||
- Responsive design with medium-dark theme |
- **Intelligent Caching**: Multi-layer caching system with background rewarming |
||||||
- WCAG AA/AAA compliant accessibility |
- **Media Caching**: Automatic caching of external images and media |
||||||
- YAML configuration for easy index management |
- **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 |
## Requirements |
||||||
|
|
||||||
- Go 1.22+ |
- **Go 1.22+** - For building and running the server |
||||||
- Node.js (for asciidoctor.js) |
- **Node.js** - For AsciiDoc processing |
||||||
- @asciidoctor/core npm package |
- **@asciidoctor/core** - npm package for AsciiDoc conversion |
||||||
- Network access to Nostr relays |
- **Network access** - To connect to Nostr relays |
||||||
|
|
||||||
## Installation |
## Installation |
||||||
|
|
||||||
1. Clone the repository |
1. **Clone the repository:** |
||||||
2. Install Go dependencies: |
```bash |
||||||
|
git clone <repository-url> |
||||||
|
cd gitcitadel-online |
||||||
|
``` |
||||||
|
|
||||||
|
2. **Install Go dependencies:** |
||||||
```bash |
```bash |
||||||
go mod tidy |
go mod tidy |
||||||
``` |
``` |
||||||
3. Install Node.js dependencies: |
|
||||||
|
3. **Install Node.js dependencies:** |
||||||
```bash |
```bash |
||||||
npm install @asciidoctor/core |
npm install @asciidoctor/core |
||||||
``` |
``` |
||||||
Or globally: |
Or install globally: |
||||||
```bash |
```bash |
||||||
npm install -g @asciidoctor/core |
npm install -g @asciidoctor/core |
||||||
``` |
``` |
||||||
4. Download nostr-tools bundle (for contact form): |
|
||||||
|
4. **Download nostr-tools bundle (for contact form):** |
||||||
```bash |
```bash |
||||||
mkdir -p static/js |
mkdir -p static/js |
||||||
curl -L -o static/js/nostr.bundle.js https://unpkg.com/nostr-tools@latest/lib/nostr.bundle.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. |
Note: The nostr-tools library is hosted locally to avoid dependency on external CDNs. |
||||||
5. Copy the example config: |
|
||||||
|
5. **Copy and configure:** |
||||||
```bash |
```bash |
||||||
cp config.yaml.example config.yaml |
cp config.yaml.example config.yaml |
||||||
``` |
``` |
||||||
6. Edit `config.yaml` with your indices and settings |
Edit `config.yaml` with your Nostr indices, relay URLs, and settings. |
||||||
|
|
||||||
## Configuration |
## Configuration |
||||||
|
|
||||||
Edit `config.yaml` to set: |
Edit `config.yaml` to configure: |
||||||
|
|
||||||
|
### Required Settings |
||||||
|
|
||||||
- `wiki_index`: naddr for your wiki index (kind 30040) |
- `wiki_index`: naddr for your wiki index (kind 30040) |
||||||
- `blog_index`: naddr for your blog index (kind 30040) |
- `blog_index`: naddr for your blog index (kind 30040) |
||||||
- Relay URLs |
- `repo_announcement`: naddr for repository announcement (for contact form) |
||||||
- Cache refresh intervals |
- `relays.feeds`: Primary relay URL for fetching content |
||||||
- Server port |
- `relays.profiles`: Comma-separated relay URLs for profile data |
||||||
- SEO settings |
- `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 |
## Running |
||||||
|
|
||||||
|
### Development Mode |
||||||
|
|
||||||
|
Run with verbose logging: |
||||||
```bash |
```bash |
||||||
go run cmd/server/main.go |
go run cmd/server/main.go --dev |
||||||
``` |
``` |
||||||
|
|
||||||
Or build and run: |
### Production Mode |
||||||
|
|
||||||
|
Build and run: |
||||||
```bash |
```bash |
||||||
go build -o gitcitadel-online cmd/server/main.go |
go build -o gitcitadel-online cmd/server/main.go |
||||||
./gitcitadel-online |
./gitcitadel-online |
||||||
``` |
``` |
||||||
|
|
||||||
Development mode with verbose logging: |
### Command Line Options |
||||||
```bash |
|
||||||
go run cmd/server/main.go --dev |
- `--config <path>`: Path to configuration file (default: `config.yaml`) |
||||||
``` |
- `--dev`: Enable development mode with verbose logging |
||||||
|
- `--log-level <level>`: Set log level (debug, info, warn, error) (default: info) |
||||||
|
|
||||||
|
## Routes & Endpoints |
||||||
|
|
||||||
|
### Public Pages |
||||||
|
|
||||||
|
- `/` - Landing page with feed sidebar |
||||||
|
- `/wiki` - Wiki index page |
||||||
|
- `/wiki/<d-tag>` - 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 |
## Project Structure |
||||||
|
|
||||||
``` |
``` |
||||||
gitcitadel-online/ |
gitcitadel-online/ |
||||||
├── cmd/server/ # Main server application |
├── cmd/ |
||||||
|
│ └── server/ # Main server application entry point |
||||||
├── internal/ |
├── 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 |
│ ├── nostr/ # Nostr client and event parsing |
||||||
│ ├── asciidoc/ # AsciiDoc processing |
│ │ ├── client.go # Relay connection management |
||||||
│ ├── generator/ # HTML generation |
│ │ ├── wiki.go # Wiki event parsing |
||||||
│ ├── cache/ # Caching layer |
│ │ ├── profile.go # Profile metadata |
||||||
│ ├── server/ # HTTP server |
│ │ ├── feed.go # Feed event parsing |
||||||
│ └── config/ # Configuration management |
│ │ ├── 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 |
├── templates/ # HTML templates |
||||||
├── static/ # Static assets (CSS, images) |
│ ├── base.html # Base template |
||||||
└── config.yaml # Configuration file |
│ ├── 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 |
||||||
``` |
``` |
||||||
|
|
||||||
## API |
## Development |
||||||
|
|
||||||
The server provides: |
### Building |
||||||
- `/` - Landing page |
|
||||||
- `/wiki/<d-tag>` - Wiki article pages |
```bash |
||||||
- `/blog` - Blog index page |
go build -o gitcitadel-online cmd/server/main.go |
||||||
- `/static/` - Static assets |
``` |
||||||
- `/health` - Health check endpoint |
|
||||||
- `/metrics` - Metrics endpoint |
### Testing |
||||||
- `/sitemap.xml` - Sitemap |
|
||||||
- `/robots.txt` - Robots.txt |
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 |
## License |
||||||
|
|
||||||
MIT License - see LICENSE.md |
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 |
||||||
|
|||||||
Loading…
Reference in new issue