CSS styling hooks as classes on the body

Refs #153

Every template now gets CSS classes in the body designed to support custom
styling.

The index template (the top level page at /) gets this:

    <body class="index">

The database template (/dbname/) gets this:

    <body class="db db-dbname">

The table template (/dbname/tablename) gets:

    <body class="table db-dbname table-tablename">

The row template (/dbname/tablename/rowid) gets:

    <body class="row db-dbname table-tablename">

The db-x and table-x classes use the database or table names themselves IF
they are valid CSS identifiers. If they aren't, we strip any invalid
characters out and append a 6 character md5 digest of the original name, in
order to ensure that multiple tables which resolve to the same stripped
character version still have different CSS classes.

Some examples (extracted from the unit tests):

    "simple" => "simple"
    "MixedCase" => "MixedCase"
    "-no-leading-hyphens" => "no-leading-hyphens-65bea6"
    "_no-leading-underscores" => "no-leading-underscores-b921bc"
    "no spaces" => "no-spaces-7088d7"
    "-" => "336d5e"
    "no $ characters" => "no--characters-59e024"
This commit is contained in:
Simon Willison 2017-11-29 23:09:54 -08:00
commit 8ab3a169d4
No known key found for this signature in database
GPG key ID: FBB38AFE227189DB
9 changed files with 72 additions and 1 deletions

View file

@ -1,6 +1,7 @@
from datasette.app import Datasette
import os
import pytest
import re
import sqlite3
import tempfile
import time
@ -421,6 +422,25 @@ def test_empty_search_parameter_gets_removed(app_client):
)
@pytest.mark.parametrize('path,expected_classes', [
('/', ['index']),
('/test_tables', ['db', 'db-test_tables']),
('/test_tables/simple_primary_key', [
'table', 'db-test_tables', 'table-simple_primary_key'
]),
('/test_tables/table%2Fwith%2Fslashes.csv', [
'table', 'db-test_tables', 'table-tablewithslashescsv-fa7563'
]),
('/test_tables/simple_primary_key/1', [
'row', 'db-test_tables', 'table-simple_primary_key'
]),
])
def test_css_classes_on_body(app_client, path, expected_classes):
response = app_client.get(path, gather_request=False)
classes = re.search(r'<body class="(.*)">', response.text).group(1).split()
assert classes == expected_classes
TABLES = '''
CREATE TABLE simple_primary_key (
pk varchar(30) primary key,

View file

@ -161,3 +161,16 @@ def test_detect_fts():
])
def test_is_url(url, expected):
assert expected == utils.is_url(url)
@pytest.mark.parametrize('s,expected', [
('simple', 'simple'),
('MixedCase', 'MixedCase'),
('-no-leading-hyphens', 'no-leading-hyphens-65bea6'),
('_no-leading-underscores', 'no-leading-underscores-b921bc'),
('no spaces', 'no-spaces-7088d7'),
('-', '336d5e'),
('no $ characters', 'no--characters-59e024'),
])
def test_to_css_class(s, expected):
assert expected == utils.to_css_class(s)