# datascape

Minimal self-hosted personal wiki. Folders are pages.

## Features

- **Pages** every folder is a page. Place an `index.md` inside a folder and it renders as HTML. Drop any other files (PDFs, images, etc.) alongside it and they appear in the listing below the content. Navigating to a path that does not exist shows a **[CREATE]** prompt.

- **View settings** per folder, display the file listing as a list or thumbnail grid and pick the sort key/order, via the **view** button in the `Files` header. See the [View Settings](#view-settings) section.

- **Search** search across all page names (folder names) in the wiki, accessible from the navigation bar.

- **Wikilinks** link between pages with `[[Page Name]]` syntax. When a page is renamed or moved, all wikilinks pointing to it are rewritten automatically to reflect the new path.

- **Movie import** import movie entries via the OMDb API. Fetches title, year, runtime, genre, director, cast, plot, and poster, and pre-fills a new page with that metadata.

- **Special folder types** folders can opt into custom rendering (e.g. a photo diary with calendar navigation). See the [Special Folder Types](#special-folder-types) section for details.

- **Quick-add bookmarklet** save the current browser tab to a predetermined wiki page (e.g. `/Topics/Bookmarks/`) with one click. See the [Quick-Add Bookmarklet](#quick-add-bookmarklet) section.

## Build

```bash
# local
go build -o datascape .

# QNAP NAS (linux/arm)
GOOS=linux GOARCH=arm go build -o datascape .
```

## Usage

```bash
go run . -dir ./wiki -addr :8080
go run . -dir ./wiki -addr :8080 -user me -pass secret
```

| Flag | Default | Description |
|------|---------|-------------|
| `-addr` | `:8080` | Listen address |
| `-dir` | `./wiki` | Wiki root directory |
| `-cache` | `./cache` | Thumbnail cache directory |
| `-user` | _(none)_ | Basic auth username — omit to disable auth |
| `-pass` | _(none)_ | Basic auth password |
| `-reindex-interval` | `30m` | Periodic search index rebuild interval (`0` disables) |

## View Settings

The **view** button in a folder's `Files` header sets how its listing renders,
persisting three keys to `.page-settings`:

| Key | Values (default first) |
|------|------------------------|
| `view` | `list`, `thumbnail` |
| `sort` | `name`, `modified`, `size` (folders always sort by name, grouped first) |
| `order` | `asc`, `desc` |

## Special Folder Types

A folder can opt into special rendering by adding a `.page-settings` file. The
same file also holds the [View Settings](#view-settings) keys; only the `type`
key selects a special renderer:

```
type = diary
```

### Diary

Designed for a chronological photo diary. The whole year lives in a single
file as ISO-headed sections; photos are loose JPEGs named with a date prefix.

```
FolderName/
  .page-settings        ← type = diary
  YYYY/
    index.md            ← `# YYYY` + `## YYYY-MM` + `### YYYY-MM-DD` sections
    YYYY-MM-DD Desc.jpg ← photos named with the date they belong to
```

The year page (`YYYY/`) renders every section in the file with photos
attached to each `### YYYY-MM-DD` heading. Months and days the file doesn't
yet contain are rendered as **virtual** headings with an `[edit]` button that
splices a new section into the year file at the right chronological position;
virtual day headings still carry photos for that date. Past years render
every month/day slot; the current year stops at today; future years skip
virtual entries entirely. The file may contain non-date headings (e.g.
`## Events` → `### Festival` between `# YYYY` and `## YYYY-01`); these keep
their document position.

A sidebar calendar widget shows one month grid at a time; the month-name
button opens a dropdown of all twelve months, and a separate year dropdown
jumps between years. Day cells link to the matching anchor on the year page
regardless of whether the date has a real section yet.

#### Persistent date links

Each diary root exposes three stable paths intended for browser bookmarks.
They resolve against the year page rather than separate per-day URLs:

| Path | Redirects to |
|------|-------------|
| `<diary>/today/` | `<diary>/YYYY/#YYYY-MM-DD` (or the year file's insert-section editor when today's section doesn't exist yet) |
| `<diary>/this-month/` | `<diary>/YYYY/#YYYY-MM` |
| `<diary>/this-year/` | `<diary>/YYYY/` |

Legacy `YYYY/MM/` and `YYYY/MM/DD/` URLs (no longer the canonical form) redirect to the matching anchor on the year page.

## Quick-Add Bookmarklet

Replace `wiki.host` with your wiki host and `/Topics/Bookmarks/` with the destination page (one bookmarklet per target):

```javascript
javascript:(function(){var s=window.getSelection().toString().trim();var t=s||document.title;var u=location.href;var to='/Topics/Bookmarks/';var q='?to='+encodeURIComponent(to)+'&url='+encodeURIComponent(u)+'&title='+encodeURIComponent(t);window.open('https://wiki.host/quickadd'+q,'quickadd','width=480,height=320');})();
```

Each save appends an entry of the following form to the destination page's `index.md`:

```markdown
- [Example Page](https://example.com)
  2026-05-11 14:30
  optional comment
```
