mirror of
https://github.com/simonw/datasette.git
synced 2026-06-24 01:34:41 +02:00
Clarify template context metadata names
This commit is contained in:
parent
a43e76c31a
commit
59ab0c0ca0
7 changed files with 65 additions and 63 deletions
|
|
@ -7,7 +7,7 @@ the documentation lives next to the code it describes:
|
|||
- Every page renders a Context dataclass defined in its view module
|
||||
(DatabaseContext, QueryContext in views/database.py, TableContext in
|
||||
views/table.py, RowContext in views/row.py). Fields added by view code
|
||||
carry ``help`` metadata; fields declared with extra_field() take their
|
||||
carry ``help`` metadata; fields declared with from_extra() take their
|
||||
documentation from the description on the matching Extra class in
|
||||
views/table_extras.py.
|
||||
- The keys render_template() adds to every page are documented in
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class ContextField:
|
|||
from_extra: bool = False
|
||||
|
||||
|
||||
def extra_field():
|
||||
def from_extra():
|
||||
"""
|
||||
Declare a Context dataclass field whose value comes from a registered
|
||||
Extra of the same name - its documentation is the Extra description,
|
||||
|
|
@ -23,7 +23,7 @@ def extra_field():
|
|||
class Context:
|
||||
"Base class for all documented contexts"
|
||||
|
||||
# Set on subclasses whose extra_field() fields should be resolved
|
||||
# Set on subclasses whose from_extra() fields should be resolved
|
||||
# against the extras registry for this scope
|
||||
extras_scope = None
|
||||
|
||||
|
|
@ -34,8 +34,8 @@ class Context:
|
|||
for f in dataclasses.fields(cls):
|
||||
if f.name.startswith("_"):
|
||||
continue
|
||||
from_extra = bool(f.metadata.get("from_extra"))
|
||||
if from_extra:
|
||||
is_from_extra = bool(f.metadata.get("from_extra"))
|
||||
if is_from_extra:
|
||||
help_text = cls._extra_description(f.name)
|
||||
else:
|
||||
help_text = f.metadata.get("help", "")
|
||||
|
|
@ -44,7 +44,7 @@ class Context:
|
|||
name=f.name,
|
||||
type_name=getattr(f.type, "__name__", str(f.type)),
|
||||
help=help_text,
|
||||
from_extra=from_extra,
|
||||
from_extra=is_from_extra,
|
||||
)
|
||||
)
|
||||
return documented
|
||||
|
|
@ -59,14 +59,14 @@ class Context:
|
|||
extra_class = table_extra_registry.classes_by_name[name]
|
||||
except KeyError:
|
||||
raise KeyError(
|
||||
"{}.{} is declared with extra_field() but there is no "
|
||||
"{}.{} is declared with from_extra() but there is no "
|
||||
"registered extra of that name".format(cls.__name__, name)
|
||||
)
|
||||
if cls.extras_scope is not None and not extra_class.available_for(
|
||||
cls.extras_scope
|
||||
):
|
||||
raise ValueError(
|
||||
"{}.{} is declared with extra_field() but the {} extra is "
|
||||
"{}.{} is declared with from_extra() but the {} extra is "
|
||||
"not available for scope {}".format(
|
||||
cls.__name__, name, name, cls.extras_scope
|
||||
)
|
||||
|
|
|
|||
|
|
@ -258,7 +258,7 @@ class DatabaseView(View):
|
|||
class DatabaseContext(Context):
|
||||
"The page listing the tables, views and queries in a database, e.g. /fixtures."
|
||||
|
||||
template = "database.html"
|
||||
documented_template = "database.html"
|
||||
|
||||
database: str = field(metadata={"help": "The name of the database"})
|
||||
private: bool = field(
|
||||
|
|
@ -341,7 +341,7 @@ class DatabaseContext(Context):
|
|||
class QueryContext(Context):
|
||||
"The page for arbitrary SQL queries (/database/-/query?sql=...) and stored queries (/database/query-name)."
|
||||
|
||||
template = "query.html"
|
||||
documented_template = "query.html"
|
||||
|
||||
database: str = field(metadata={"help": "The name of the database being queried"})
|
||||
database_color: str = field(metadata={"help": "The color of the database"})
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ from datasette.utils import (
|
|||
)
|
||||
from datasette.plugins import pm
|
||||
from datasette.extras import extra_names_from_request, ExtraScope
|
||||
from . import Context, extra_field
|
||||
from . import Context, from_extra
|
||||
from .table import (
|
||||
display_columns_and_rows,
|
||||
_table_page_data,
|
||||
|
|
@ -43,19 +43,19 @@ from .table_extras import RowExtraContext, resolve_row_extras, table_extra_regis
|
|||
class RowContext(Context):
|
||||
"The page showing an individual row, e.g. /fixtures/facetable/1."
|
||||
|
||||
template = "row.html"
|
||||
documented_template = "row.html"
|
||||
extras_scope = ExtraScope.ROW
|
||||
|
||||
# Fields resolved by registered extras - their documentation comes
|
||||
# from the description on each Extra class in table_extras.py
|
||||
columns: list = extra_field()
|
||||
database: str = extra_field()
|
||||
database_color: str = extra_field()
|
||||
foreign_key_tables: list = extra_field()
|
||||
metadata: dict = extra_field()
|
||||
primary_keys: list = extra_field()
|
||||
private: bool = extra_field()
|
||||
table: str = extra_field()
|
||||
columns: list = from_extra()
|
||||
database: str = from_extra()
|
||||
database_color: str = from_extra()
|
||||
foreign_key_tables: list = from_extra()
|
||||
metadata: dict = from_extra()
|
||||
primary_keys: list = from_extra()
|
||||
private: bool = from_extra()
|
||||
table: str = from_extra()
|
||||
|
||||
# Fields added by the view code
|
||||
ok: bool = field(
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ import sqlite_utils
|
|||
from dataclasses import dataclass, field, fields
|
||||
|
||||
from datasette.extras import ExtraScope
|
||||
from . import Context, extra_field
|
||||
from . import Context, from_extra
|
||||
from .base import BaseView, DatasetteError, _error, stream_csv
|
||||
from .database import QueryView
|
||||
from .table_create_alter import (
|
||||
|
|
@ -73,40 +73,40 @@ from .table_extras import (
|
|||
class TableContext(Context):
|
||||
"The page showing the rows in a table or SQL view, e.g. /fixtures/facetable."
|
||||
|
||||
template = "table.html"
|
||||
documented_template = "table.html"
|
||||
extras_scope = ExtraScope.TABLE
|
||||
|
||||
# Fields resolved by registered extras - their documentation comes
|
||||
# from the description on each Extra class in table_extras.py
|
||||
actions: callable = extra_field()
|
||||
all_columns: list = extra_field()
|
||||
columns: list = extra_field()
|
||||
count: int = extra_field()
|
||||
count_sql: str = extra_field()
|
||||
custom_table_templates: list = extra_field()
|
||||
database: str = extra_field()
|
||||
database_color: str = extra_field()
|
||||
display_columns: list = extra_field()
|
||||
display_rows: list = extra_field()
|
||||
expandable_columns: list = extra_field()
|
||||
facet_results: dict = extra_field()
|
||||
facets_timed_out: list = extra_field()
|
||||
filters: Filters = extra_field()
|
||||
form_hidden_args: list = extra_field()
|
||||
human_description_en: str = extra_field()
|
||||
is_view: bool = extra_field()
|
||||
metadata: dict = extra_field()
|
||||
next_url: str = extra_field()
|
||||
primary_keys: list = extra_field()
|
||||
private: bool = extra_field()
|
||||
query: dict = extra_field()
|
||||
renderers: dict = extra_field()
|
||||
set_column_type_ui: dict = extra_field()
|
||||
sorted_facet_results: list = extra_field()
|
||||
suggested_facets: list = extra_field()
|
||||
table: str = extra_field()
|
||||
table_definition: str = extra_field()
|
||||
view_definition: str = extra_field()
|
||||
actions: callable = from_extra()
|
||||
all_columns: list = from_extra()
|
||||
columns: list = from_extra()
|
||||
count: int = from_extra()
|
||||
count_sql: str = from_extra()
|
||||
custom_table_templates: list = from_extra()
|
||||
database: str = from_extra()
|
||||
database_color: str = from_extra()
|
||||
display_columns: list = from_extra()
|
||||
display_rows: list = from_extra()
|
||||
expandable_columns: list = from_extra()
|
||||
facet_results: dict = from_extra()
|
||||
facets_timed_out: list = from_extra()
|
||||
filters: Filters = from_extra()
|
||||
form_hidden_args: list = from_extra()
|
||||
human_description_en: str = from_extra()
|
||||
is_view: bool = from_extra()
|
||||
metadata: dict = from_extra()
|
||||
next_url: str = from_extra()
|
||||
primary_keys: list = from_extra()
|
||||
private: bool = from_extra()
|
||||
query: dict = from_extra()
|
||||
renderers: dict = from_extra()
|
||||
set_column_type_ui: dict = from_extra()
|
||||
sorted_facet_results: list = from_extra()
|
||||
suggested_facets: list = from_extra()
|
||||
table: str = from_extra()
|
||||
table_definition: str = from_extra()
|
||||
view_definition: str = from_extra()
|
||||
|
||||
# Fields added by the view code
|
||||
ok: bool = field(
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ def template_context(cog):
|
|||
for klass in PAGES.values():
|
||||
title = "{} page".format(klass.__name__.removesuffix("Context"))
|
||||
intro = "{} Rendered using the ``{}`` template.".format(
|
||||
klass.__doc__, klass.template
|
||||
klass.__doc__, klass.documented_template
|
||||
)
|
||||
_section(cog, title, intro)
|
||||
if klass.extras_scope is not None:
|
||||
|
|
|
|||
|
|
@ -40,20 +40,22 @@ def test_context_class_fields_all_have_help(klass):
|
|||
|
||||
|
||||
@pytest.mark.parametrize("klass", PAGES.values(), ids=lambda klass: klass.__name__)
|
||||
def test_context_class_has_docstring_and_template(klass):
|
||||
def test_context_class_has_docstring_and_documented_template(klass):
|
||||
assert klass.__doc__, "{} is missing a docstring".format(klass.__name__)
|
||||
assert klass.template, "{} is missing a template".format(klass.__name__)
|
||||
assert klass.documented_template, "{} is missing a documented_template".format(
|
||||
klass.__name__
|
||||
)
|
||||
|
||||
|
||||
def test_extra_field_documentation_comes_from_the_extra_class():
|
||||
from datasette.views import extra_field
|
||||
def test_from_extra_documentation_comes_from_the_extra_class():
|
||||
from datasette.views import from_extra
|
||||
from datasette.views.table_extras import CountExtra
|
||||
|
||||
@dataclass
|
||||
class DemoContext(Context):
|
||||
extras_scope = ExtraScope.TABLE
|
||||
|
||||
count: int = extra_field()
|
||||
count: int = from_extra()
|
||||
name: str = field(metadata={"help": "The name"})
|
||||
|
||||
fields = {f.name: f for f in DemoContext.documented_fields()}
|
||||
|
|
@ -63,28 +65,28 @@ def test_extra_field_documentation_comes_from_the_extra_class():
|
|||
assert not fields["name"].from_extra
|
||||
|
||||
|
||||
def test_extra_field_must_match_a_registered_extra():
|
||||
from datasette.views import extra_field
|
||||
def test_from_extra_must_match_a_registered_extra():
|
||||
from datasette.views import from_extra
|
||||
|
||||
@dataclass
|
||||
class BadContext(Context):
|
||||
extras_scope = ExtraScope.TABLE
|
||||
|
||||
not_a_real_extra: str = extra_field()
|
||||
not_a_real_extra: str = from_extra()
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
BadContext.documented_fields()
|
||||
|
||||
|
||||
def test_extra_field_must_be_available_for_the_scope():
|
||||
from datasette.views import extra_field
|
||||
def test_from_extra_must_be_available_for_the_scope():
|
||||
from datasette.views import from_extra
|
||||
|
||||
@dataclass
|
||||
class WrongScopeContext(Context):
|
||||
extras_scope = ExtraScope.ROW
|
||||
|
||||
# count is a TABLE-scope extra, not available for ROW
|
||||
count: int = extra_field()
|
||||
count: int = from_extra()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
WrongScopeContext.documented_fields()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue