Metadata-Version: 2.4
Name: wagtail-tinytableblock
Version: 0.5.0
Summary: A Wagtail StreamField block powered by TinyMCE and its table plugin
Keywords: Wagtail,Django,StreamField,TinyMCE,Tables
Author-email: Dan Braghis <dan.braghis@torchbox.com>
Maintainer-email: Dan Braghis <dan.braghis@torchbox.com>
Requires-Python: >=3.12
Description-Content-Type: text/markdown
License-Expression: GPL-3.0-or-later
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Classifier: Framework :: Django
Classifier: Framework :: Django :: 4.2
Classifier: Framework :: Django :: 5.1
Classifier: Framework :: Django :: 5.2
Classifier: Framework :: Django :: 6.0
Classifier: Framework :: Wagtail
Classifier: Framework :: Wagtail :: 6
Classifier: Framework :: Wagtail :: 7
License-File: LICENSE
Requires-Dist: Django>=4.2
Requires-Dist: Wagtail>=6.3
Requires-Dist: nh3>=0.3,<1
Requires-Dist: dj-database-url>=3.0,<4 ; extra == "testing"
Requires-Dist: coverage>=7.10,<8.0 ; extra == "testing"
Project-URL: Changelog, https://github.com/torchbox/wagtail-tinytableblock/blob/main/CHANGELOG.md
Project-URL: Source, https://github.com/torchbox/wagtail-tinytableblock
Provides-Extra: testing

# A table block for Wagtail StreamField powered by TinyMCE

[![License: BSD-3-Clause](https://img.shields.io/badge/License-BSD--3--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![PyPI version](https://img.shields.io/pypi/v/wagtail-tinytableblock.svg?style=flat)](https://pypi.org/project/wagtail-tinytableblock)
[![Build status](https://img.shields.io/github/actions/workflow/status/torchbox/wagtail-tinytableblock/test.yml?branch=main)](https://github.com/torchbox/wagtail-tinytableblock/actions)

## Links

- [Documentation](https://github.com/torchbox/wagtail-tinytableblock/blob/main/README.md)
- [Changelog](https://github.com/torchbox/wagtail-tinytableblock/blob/main/CHANGELOG.md)
- [Contributing](https://github.com/torchbox/wagtail-tinytableblock/blob/main/CONTRIBUTING.md)
- [Discussions](https://github.com/torchbox/wagtail-tinytableblock/discussions)
- [Security](https://github.com/torchbox/wagtail-tinytableblock/security)

TinyTableBlock is a StreamField block powered by [TinyMCE](https://www.tiny.cloud/) and its [table plugin](https://www.tiny.cloud/docs/tinymce/latest/table/).

Wagtail provides [`TableBlock`](https://docs.wagtail.org/en/stable/reference/contrib/table_block.html) and
[`TypedTableBlock`](https://docs.wagtail.org/en/stable/reference/contrib/typed_table_block.html)
which are good options if you want basic tables with some cell merging capability or StreamField-powered cell, but they have their limitations:

- `TableBlock` is using an old version of [handsontable](https://github.com/handsontable/handsontable/tree/6.2.2). It doesn't support multi-row header, column headers, nor pasting complex tables.
- `TypedTableBlock` gets complex quickly depending on the types of blocks you add, and pasting is limited to single cells.
-

Wagtail TinyTableBlock (this package) provides the TinyMCE table editor which has improved copy/paste, multi-row and column headers, external link support and more.
It does not currently support the Wagtail rich text [data format](https://docs.wagtail.org/en/stable/extending/rich_text_internals.html#data-format) for page and document links,
nor does it support embedding images.

## Installation

In your project's Django settings, add the app your `INSTALLED_APPS` list (at the end is fine):

```python
INSTALLED_APPS = [
  # ...
  "wagtail_tinytableblock",
]
```

Add the `TinyTableBlock` model to your StreamField definition. For example

```python
# yourapp/models.py
from wagtail.fields import StreamField
from wagtail.models import Page

from wagtail_tinytableblock.blocks import TinyTableBlock


class WonderfulPage(Page):
    body = StreamField([
        # ...
        ("table", TinyTableBlock()),
    ])
```

Finally, run Django's `makemigrations` and `migrate` commands to apply any model field changes to your project

```sh
$ python manage.py makemigrations
$ python manage.py migrate
```

## Configuration

`TinyTableBlock` accepts an `allow_links` keyword argument which allows enabling the TinyMCE link
plugin. Note: this currently only works with external URLs.

```python
from wagtail.blocks import StreamBlock
from wagtail_tinytableblock.blocks import TinyTableBlock

class ContentBlocks(StreamBlock):
    table_block = TinyTableBlock(allow_links=True)
```

By default, we disable the TinyMCE contextual menu to allow the browser native one. If you want to use TinyMCE one,
pass `enable_context_menu=True`:

```python
from wagtail.blocks import StreamBlock
from wagtail_tinytableblock.blocks import TinyTableBlock

class ContentBlocks(StreamBlock):
    table_block = TinyTableBlock(enable_context_menu=True)
```

### Configuring rich text features allowed in table cells

You can customize which text formatting tools are available inside the table cells. By default, formatting features are turned **off** to keep table content clean. You can enable them per block or globally across your entire site.

#### Supported features

The following formatting identifiers can be passed to the configuration arrays:

- `bold`
- `italic`
- `strikethrough`
- `subscript`
- `superscript`
- `blockquote`

#### Block configuration

To enable per-block configuration, pass a `features` list directly to the `TinyTableBlock` definition in your `models.py`. This aligns directly with standard Wagtail [`RichTextField` formatting controls](https://docs.wagtail.org/en/stable/advanced_topics/customization/page_editing_interface.html#limiting-features-in-a-rich-text-field).


#### Global configuration (Django settings)

If you want to define a fallback list of formatting features for all tables across your website without repeating the code in every model, define `WAGTAIL_TINYTABLE` in your `settings.py`:

```python
# settings.py

WAGTAIL_TINYTABLE = {
    "features": ["bold", "italic", "strikethrough"]
}
```

*Note: If no global settings are defined and no per-block features are provided, the features list defaults to empty (`[]`), disabling rich text formatting choices completely.*

### Content Security Policy

For [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) configuration guidance,
follow the [TinyMCE documentation](https://www.tiny.cloud/docs/tinymce/latest/security/#configuring-content-security-policy-csp-for-tinymce) with
the self-hosted option.

## Data representation

The table data is saved as a JSON-serialized dictionary with the following keys:

```python
{
   "headers": [],
   "rows": [],
   "html": the_sanitised_html
}
```

`headers` / `rows` are lists of lists with cell values. Each cell is a dictionary with the following keys

 key | value notes
-----|---------
`value` | The cell value
`type` | "td" or "th"
`rowspan` | if set
`colspan` | if set
`scope` | if set
`align` | if set

## Contributing

All contributions are welcome! See [CONTRIBUTING.md](https://github.com/torchbox/wagtail-tinytableblock/blob/main/CONTRIBUTING.md)

Supported versions:

- Python 3.12, 3.13, 3.14
- Django 4.2, 5.2, 6.0
- Wagtail 6.3 (LTS), 7.0 (LTS), 7.3

