Persisting Data

Every plugin instance gets its own data_dir — a directory on disk for storing files. Use read_json() and write_json() for convenient JSON persistence.

Save and load release notes

def _on_save(self) -> None:
    version = self.version_input.text().strip()
    if not version:
        self.notify("Please enter a version number.", level="warning")
        return

    # Load existing notes
    all_notes = self.read_json("notes.json")

    # Save this version's notes
    all_notes[version] = {
        "text": self.editor.toPlainText(),
        "published": False,
    }
    self.write_json("notes.json", all_notes)
    self.notify(f"Draft for v{version} saved.", level="success")

def on_ready(self) -> None:
    # ... (UI setup from previous chapter) ...

    # Load last draft
    all_notes = self.read_json("notes.json")
    if all_notes:
        last_version = list(all_notes.keys())[-1]
        self.version_input.setText(last_version)
        self.editor.setPlainText(all_notes[last_version]["text"])

How it works

  • write_json() uses atomic writes (write to temp file, then rename) — safe even if the app crashes mid-save

  • read_json() returns an empty dict if the file doesn’t exist yet

  • Files are stored in ~/.forkbit/projects/<project_id>/plugins/<instance_id>/

  • Each plugin instance has its own directory — two instances of the same plugin in different projects don’t share data

Custom files

For non-JSON data, use data_dir directly:

# Write a text file
path = self.data_dir / "export.md"
path.write_text(markdown_content, encoding="utf-8")

# Read binary data
image_data = (self.data_dir / "icon.png").read_bytes()

Next: Git Integration.