Mechanism for adding a default URL fragment to a canned query

Closes #767
pull/783/head
Simon Willison 2020-05-27 14:52:03 -07:00
rodzic af5702220c
commit ad88c9b3f3
4 zmienionych plików z 56 dodań i 6 usunięć

Wyświetl plik

@ -48,7 +48,7 @@
{% endif %}
{% if views %}
<h2>Views</h2>
<h2 id="views">Views</h2>
<ul>
{% for view in views %}
<li><a href="{{ database_url(database) }}/{{ view|urlencode }}">{{ view }}</a></li>
@ -57,10 +57,10 @@
{% endif %}
{% if queries %}
<h2>Queries</h2>
<h2 id="queries">Queries</h2>
<ul>
{% for query in queries %}
<li><a href="{{ database_url(database) }}/{{ query.name|urlencode }}" title="{{ query.description or query.sql }}">{{ query.title or query.name }}</a></li>
<li><a href="{{ database_url(database) }}/{{ query.name|urlencode }}{% if query.fragment %}#{{ query.fragment }}{% endif %}" title="{{ query.description or query.sql }}">{{ query.title or query.name }}</a></li>
{% endfor %}
</ul>
{% endif %}

Wyświetl plik

@ -72,7 +72,9 @@ Canned queries
--------------
As an alternative to adding views to your database, you can define canned
queries inside your ``metadata.json`` file. Here's an example::
queries inside your ``metadata.json`` file. Here's an example:
.. code-block:: json
{
"databases": {
@ -86,7 +88,7 @@ queries inside your ``metadata.json`` file. Here's an example::
}
}
Then run datasette like this::
Then run Datasette like this::
datasette sf-trees.db -m metadata.json
@ -104,6 +106,11 @@ title and description on the canned query page. As with regular table metadata
you can alternatively specify ``"description_html"`` to have your description
rendered as HTML (rather than having HTML special characters escaped).
.. _canned_queries_named_parameters:
Named parameters
~~~~~~~~~~~~~~~~
Canned queries support named parameters, so if you include those in the SQL you
will then be able to enter them using the form fields on the canned query page
or by adding them to the URL. This means canned queries can be used to create
@ -117,7 +124,9 @@ Here's an example of a canned query with a named parameter:
from facetable join facet_cities on facetable.city_id = facet_cities.id
where neighborhood like '%' || :text || '%' order by neighborhood;
In the canned query JSON it looks like this::
In the canned query JSON it looks like this:
.. code-block:: json
{
"databases": {
@ -139,6 +148,31 @@ https://latest.datasette.io/fixtures/neighborhood_search?text=town
Note that we are using SQLite string concatenation here - the ``||`` operator -
to add wildcard ``%`` characters to the string provided by the user.
.. _canned_queries_default_fragment:
Setting a default fragment
~~~~~~~~~~~~~~~~~~~~~~~~~~
Some plugins, such as `datasette-vega <https://github.com/simonw/datasette-vega>`__, can be configured by including additional data in the fragment hash of the URL - the bit that comes after a ``#`` symbol.
You can set a default fragment hash that will be included in the link to the canned query from the database index page using the ``"fragment"`` key:
.. code-block:: json
{
"databases": {
"fixtures": {
"queries": {
"neighborhood_search": {
"sql": "select neighborhood, facet_cities.name, state\nfrom facetable join facet_cities on facetable.city_id = facet_cities.id\nwhere neighborhood like '%' || :text || '%' order by neighborhood;",
"fragment": "fragment-goes-here"
}
}
}
}
`See here <https://latest.datasette.io/fixtures#queries>`__ for a demo of this in action.
.. _pagination:
Pagination

Wyświetl plik

@ -327,6 +327,7 @@ METADATA = {
),
"title": "Search neighborhoods",
"description_html": "<b>Demonstrating</b> simple like search",
"fragment": "fragment-goes-here",
},
},
}

Wyświetl plik

@ -85,6 +85,21 @@ def test_database_page_redirects_with_url_hash(app_client_with_hash):
assert "fixtures" in response.text
def test_database_page(app_client):
response = app_client.get("/fixtures")
soup = Soup(response.body, "html.parser")
queries_ul = soup.find("h2", text="Queries").find_next_sibling("ul")
assert queries_ul is not None
assert [
(
"/fixtures/%F0%9D%90%9C%F0%9D%90%A2%F0%9D%90%AD%F0%9D%90%A2%F0%9D%90%9E%F0%9D%90%AC",
"𝐜𝐢𝐭𝐢𝐞𝐬",
),
("/fixtures/pragma_cache_size", "pragma_cache_size"),
("/fixtures/neighborhood_search#fragment-goes-here", "Search neighborhoods"),
] == [(a["href"], a.text) for a in queries_ul.find_all("a")]
def test_invalid_custom_sql(app_client):
response = app_client.get("/fixtures?sql=.schema")
assert response.status == 400