This document captures the current repository state and proposes a Python packaging plan for a future olloweditor PyPI package with optional integrations for:
- Django
- Django REST Framework
- Flask
- FastAPI
This phase does not implement runtime features. It only documents findings and the next implementation path.
The current repository checkout is not a full source tree. It is primarily a built/browser distribution plus docs and demo files.
Observed top-level files and directories:
README.mdollow.jsollow.cssollow.htmldist/website/codefortify-olloweditor-0.1.0.tgz
Not present in the current checkout:
package.jsonat repo root- Vite config files
- Rollup config files
tsconfig.jsonsrc/- test directories
.github/workflows/
Because those files are missing from the working tree, the npm package tarball was inspected to recover package metadata and exported build targets.
codefortify-olloweditor-0.1.0.tgz contains:
package/package.jsonpackage/dist/index.d.tspackage/dist/react.d.tspackage/dist/olloweditor.es.jspackage/dist/olloweditor.cjspackage/dist/olloweditor-react.es.jspackage/dist/olloweditor-react.cjspackage/dist/olloweditor.css
Recovered npm package facts:
- package name:
@codefortify/olloweditor - version:
0.1.0 main:./dist/olloweditor.cjsmodule:./dist/olloweditor.es.jstypes:./dist/index.d.ts- CSS export:
./dist/olloweditor.css - React subpath export:
./react
The tarball metadata references Vite and TypeScript scripts, but the actual config files are not present in this checkout.
Current build/distribution artifacts visible in the repo:
- Browser global build:
ollow.jsollow.css
- npm
dist/module outputs:dist/olloweditor.es.jsdist/olloweditor.cjsdist/olloweditor-react.es.jsdist/olloweditor-react.cjsdist/olloweditor.cssdist/index.d.tsdist/react.d.ts
README.mdis the main usage and API reference.ollow.htmlis a browser demo showing textarea binding.website/contains marketing/docs site files.
No automated test files are present in the current checkout.
No .github/workflows/ directory is present in the current checkout.
There are two related public surfaces today.
ollow.js is a browser-ready IIFE bundle. It exposes globals:
window.OllowEditorwindow.NationWireEditor
The API object supports:
registerPlugin(name, factory)initAll(root, options)init(target, options)get(target)instances()
Initialization examples:
OllowEditor.init("#ollo-editor", {
theme: "dark",
persistTheme: true
});Or auto-bind multiple textareas:
NationWireEditor.initAll(document, {
persistTheme: true
});Textarea selectors auto-detected by initAll:
textarea[data-nw-editor]textarea[data-ollow-editor]
The ESM/CJS package exports:
createOllowEditor(selector, options)OllowEditorCore- default export =
createOllowEditor
This module API wraps the textarea-based browser editor and can mount into either:
- an existing
<textarea> - a host HTMLElement, where the wrapper creates/manages a textarea internally
The underlying editor runtime is textarea-centered.
- The main editor instance is
EditorInstance. api.init(...)only accepts a<textarea>.- The editor hides or augments the textarea and inserts the editor UI after it.
- The textarea remains the synchronization boundary for saved HTML.
Yes. This is the native integration model.
The editor sync method writes generated HTML back into the original textarea:
this.textarea.value = this.isSourceMode() ? this.getSourceHTML() : this.getHTML();The synced textarea value is what form submission sends to the backend.
The editor also auto-binds form submission behavior so the textarea is current at submit time.
Yes.
- Instances are stored in a
Map. initAll(...)binds all matching textareas in a root.instances()returns all live instances.
Yes.
Observed option categories:
placeholderautosaveDelaythemepersistThemethemeStorageKeyreadOnlyuploaduploadHeadersuploadMethoddocxplugins- module-wrapper-only options such as
initialHTML,className,onChange,uploadImage
Yes. Plugins are registered globally before initialization and enabled per editor with options.plugins.
Observed custom events and internal emitter hooks include:
nationwire-editor:readynationwire-editor:syncnationwire-editor:changenationwire-editor:autosaveollow-editor:themechangeollow-editor:import-docxollow-editor:export-htmlollow-editor:export-docxollow-editor:export-pdf
Instance methods include:
getTheme()setTheme(theme)
The runtime supports upload configuration for:
- images
- galleries
- attachments
The client can send CSRF headers and respects cross-origin credential restrictions.
- A browser-ready IIFE exists:
ollow.js - No UMD build was found
- The npm
dist/directory only exposes ESM/CJS module builds plus CSS
This matters for Python framework integrations because server-rendered templates usually want a simple static asset that can be included with:
<script src="..."></script><link rel="stylesheet" href="...">
The existing ollow.js/ollow.css pair is the most direct asset set for Python framework static-file packaging.
Minimum viable Python static assets:
ollow.jsollow.css
Possible optional secondary asset set for completeness:
dist/olloweditor.es.jsdist/olloweditor.cjsdist/olloweditor.css
Recommendation: package only the browser-global asset pair first.
Reason:
- Django/Flask/FastAPI/DRF template integrations want browser-consumable static assets.
- ESM/CJS artifacts are not directly useful for normal server-rendered integration.
- Shipping both root CSS and
dist/olloweditor.cssrisks duplicate or confusing asset choices.
Observed requirements:
- icons are embedded inline in JS as generated SVG markup
- no standalone icon assets are required
- no workers were found
- no font files were found in the repo
External/optional runtime dependencies:
- DOCX import can use
window.mammoth - DOCX export can use
window.OllowDocxExporter
The editor remains functional without bundling those optional adapters, but DOCX features degrade accordingly.
ollow.css appears self-contained. No local @font-face or bundled font assets were found.
Demo files import Google Fonts, but the editor runtime itself does not require packaged local font files to function.
Use the browser-global assets as the canonical Python payload:
python/src/olloweditor/static/olloweditor/ollow.jspython/src/olloweditor/static/olloweditor/ollow.css
Keep the Python package responsible for:
- distributing static assets
- rendering HTML tags/snippets for those assets
- rendering framework form/widget helpers
- exposing config serialization helpers
Do not attempt to port editor behavior into Python.
Exact proposed layout under python/:
python/
├── IMPLEMENTATION_PLAN.md
├── pyproject.toml
├── README.md
├── MANIFEST.in
├── src/
│ └── olloweditor/
│ ├── __init__.py
│ ├── _version.py
│ ├── assets.py
│ ├── html.py
│ ├── config.py
│ ├── static/
│ │ └── olloweditor/
│ │ ├── ollow.js
│ │ └── ollow.css
│ ├── templates/
│ │ └── olloweditor/
│ │ ├── _assets.html
│ │ ├── _init.html
│ │ ├── django_widget.html
│ │ ├── flask_widget.html
│ │ └── fastapi_widget.html
│ ├── django/
│ │ ├── __init__.py
│ │ ├── apps.py
│ │ ├── widgets.py
│ │ ├── fields.py
│ │ ├── forms.py
│ │ ├── views.py
│ │ ├── urls.py
│ │ └── templatetags/
│ │ ├── __init__.py
│ │ └── olloweditor.py
│ ├── drf/
│ │ ├── __init__.py
│ │ ├── fields.py
│ │ ├── serializers.py
│ │ └── renderers.py
│ ├── flask/
│ │ ├── __init__.py
│ │ ├── blueprint.py
│ │ ├── forms.py
│ │ └── helpers.py
│ └── fastapi/
│ ├── __init__.py
│ ├── assets.py
│ ├── forms.py
│ └── helpers.py
└── tests/
├── test_assets.py
├── test_html.py
├── test_config.py
├── django/
│ ├── test_widget.py
│ └── test_template_tags.py
├── drf/
│ └── test_serializer_field.py
├── flask/
│ └── test_blueprint.py
└── fastapi/
└── test_helpers.py
Core Python responsibilities should be framework-agnostic:
- asset path discovery
- HTML tag generation for CSS/JS includes
- serialization of editor options into safe JSON
- textarea attribute generation
- helper to build an initialization script against a known textarea selector/id
Recommended shared API shape:
asset_urls(...)render_assets(...)render_init(textarea_id, options)textarea_attrs(...)
Recommended components:
- Django app config
OllowEditorWidget(forms.Textarea)- optional
OllowEditorField - template tags to render assets and init blocks
Behavior:
- widget renders a normal
<textarea> - widget adds
data-ollow-editorby default - widget Media class includes packaged CSS/JS
- options become
data-*attributes where possible and inline init JSON where needed
DRF does not need a browser editor runtime in API responses. The integration should stay narrow:
- serializer field that documents/stores HTML editor content
- optional Browsable API form widget integration by reusing Django widget classes when DRF renders HTML forms
Do not make DRF a hard dependency of the base package.
Recommended components:
- Blueprint serving static files from package data
- Jinja helper/macros for assets and init blocks
- WTForms-compatible widget/helper if feasible
Behavior:
- allow
{{ olloweditor_assets() }} - allow
{{ olloweditor_init("field_id", options=...) }} - serve packaged
ollow.jsandollow.cssthrough the blueprint
Recommended components:
- helper for mounting packaged static assets
- Jinja2 helpers for templates
- form helper for textarea rendering
Behavior:
- FastAPI itself does not provide a form/widget system like Django
- keep the FastAPI integration thin and template-oriented
Current repo state already has usable browser assets, but a Python package will need a reproducible way to obtain them.
Recommended changes for a later phase:
- Define a canonical source of truth for distributable browser assets.
- Add a copy/sync step that places the exact release assets into
python/src/olloweditor/static/olloweditor/. - Prefer copying from one canonical output only.
Recommendation:
- treat
ollow.jsandollow.cssas the Python-target assets initially - avoid packaging both root assets and
dist/olloweditor.cssunless there is a verified reason
If the full JS source tree is restored later, add a non-breaking build target such as:
npm run build:python-assets
That target should only:
- rebuild current browser assets
- copy them into the Python package staging directory
It should not change existing npm public exports.
Package-level tests:
- packaged files exist
- asset helpers produce correct URLs/tags
- option serialization is stable and escaped safely
Django tests:
- widget renders textarea plus expected attributes
- static/media references resolve
- form submission preserves synced HTML value
Flask and FastAPI tests:
- static assets served correctly
- helper output renders correct tags and init script
DRF tests:
- serializer field behavior
- browsable API widget integration if implemented
If later added, use a real browser runner to verify:
- multiple editors on one page
- textarea sync after typing
- initialization via
data-ollow-editor - initialization via explicit
OllowEditor.init(...)
Use a modern Python package build with:
pyproject.toml- setuptools or hatchling
Recommendation: use setuptools first because static files, templates, and optional extras are straightforward and conservative.
Base install:
pip install olloweditorOptional extras:
djangodrfflaskfastapiall
Recommended extras mapping:
django:Django>=4.2drf:Django>=4.2,djangorestframework>=3.15flask:Flask>=3.0fastapi:fastapi>=0.115,jinja2>=3.1all: union of the above
The base package should have no framework dependency.
Versioning recommendation:
- keep Python package version aligned with the npm/editor asset version where possible
- if Python-only changes are released without asset changes, use a local convention only if truly necessary
Preferred rule:
- Python package
0.1.0ships OllowEditor asset version0.1.0 - avoid letting npm and PyPI drift semantically without documenting the asset version embedded in the Python package
Recommended metadata:
olloweditor.__version__= Python package versionolloweditor.__asset_version__= bundled editor asset version
Risk:
- the npm
dist/outputs are ESM/CJS, but Python template integrations need a browser-ready script
Mitigation:
- use
ollow.jsas the packaged browser asset - do not rely on ESM/CJS files for server-rendered integration
Risk:
- each framework resolves static assets differently
Mitigation:
- Django: rely on app staticfiles discovery
- Flask: ship a blueprint
- FastAPI: provide
StaticFilesmounting helper
Risk:
- both
ollow.cssanddist/olloweditor.cssexist
Mitigation:
- pick one canonical CSS file for Python packaging
- document that choice clearly
Risk:
- base install becomes bloated or fragile if every framework is a hard dependency
Mitigation:
- use extras for all framework integrations
- keep base package framework-agnostic
Risk:
- users may assume Python package sanitizes HTML server-side
Mitigation:
- document clearly that the package distributes a client-side editor
- require host applications to keep server-side validation/policy enforcement
Risk:
olloweditormay already exist or be reserved on PyPI
Mitigation:
- verify availability before publication phase
- if unavailable, decide on an alternate name before implementation hardens around it
Risk:
- Python wrapper and bundled JS assets drift
Mitigation:
- store bundled asset version explicitly
- require release checklist validation before packaging
Risk:
- consumers may expect DOCX import/export to work automatically from the Python package
Mitigation:
- document that DOCX adapter globals are optional and not bundled by default unless later packaged explicitly
Risk:
- current repo checkout contains built root assets but not the build configuration that produces them
Mitigation:
- before implementation, recover or restore canonical frontend build config
- if unavailable, treat the current browser assets as frozen inputs until the JS build pipeline is restored
- Create
python/pyproject.toml - Create package metadata and extras
- Add
src/olloweditor/ - Add packaged static assets copied from canonical browser outputs
- Add shared asset and HTML helper APIs
- Add package tests for asset discovery and HTML generation
- Add Django app config
- Add
OllowEditorWidget - Add template tags
- Add Django static/media integration tests
- Add Flask blueprint and helpers
- Add FastAPI static mount and Jinja helpers
- Add framework-specific tests
- Add optional DRF field/serializer helpers
- Reuse Django widget behavior for browsable API where useful
- Add DRF tests
- Add asset copy/sync script
- Add version sync checks
- Add CI for Python tests
- Add packaging smoke tests for sdists/wheels
Proceed to Phase 1 with a conservative implementation:
- scaffold the Python package under
python/ - package only
ollow.jsandollow.css - implement the shared helpers and Django integration first
- keep Flask/FastAPI/DRF behind extras
This keeps the work aligned with the current repository reality: the browser asset pair already exists and the editor is already designed to work with a normal textarea.