Merge pull request #31950 from elpaso/bugfix-server-wfs3-API-template

Server fix openapi HTML template and improve styling
This commit is contained in:
Alessandro Pasotti 2019-09-23 20:32:57 +02:00 committed by GitHub
commit ea7b27ef3e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 204 additions and 163 deletions

View File

@ -5,7 +5,32 @@ a { color: green; }
height: 400px;
}
.card-header span.small {
font-size: 70%;
}
.path-button {
text-transform: uppercase;
}
.path-path {
font-weight: bold;
}
.model-toggle {
font-weight: bold;
}
.model-toggle::after {
display: inline-block;
vertical-align: bottom;
width: 20px;
height: 20px;
content: "";
background: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24'%3E%3Cpath d='M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z'/%3E%3C/svg%3E") 50% no-repeat;
background-size: 100%;
}
.top-buffer {
margin-top:20px;
}

View File

@ -1,170 +1,180 @@
<!-- template for the WFS3 API description page -->
{% include "header.html" %}
<h1>API description</h1>
<div class="row">
<div class="col">
<h1>API description</h1>
<h2>Info</h2>
<dl class="row">
<dt class="col-sm-3">Description</dt>
<dd class="col-sm-9">{{ info.description }}</dd>
<dt class="col-sm-3">Title</dt>
<dd class="col-sm-9">{{ info.title }}</dd>
<dt class="col-sm-3">Contact email</dt>
<dd class="col-sm-9">{{ info.contact.email }}</dd>
<dt class="col-sm-3">Contact name</dt>
<dd class="col-sm-9">{{ info.contact.name }}</dd>
</dl>
</div> <!-- // .col-->
</div> <!-- // .row -->
<h2>Info</h2>
<dl class="row">
<dt class="col-sm-3">Description</dt>
<dd class="col-sm-9">{{ info.description }}</dd>
<dt class="col-sm-3">Title</dt>
<dd class="col-sm-9">{{ info.title }}</dd>
<dt class="col-sm-3">Contact email</dt>
<dd class="col-sm-9">{{ info.contact.email }}</dd>
<dt class="col-sm-3">Contact name</dt>
<dd class="col-sm-9">{{ info.contact.name }}</dd>
</dl>
<h2>Paths</h2>
<div id="accordion">
<div class="card">
{% for path, path_info in paths %}
{% for method, method_data in path_info %}
<div class="card-header" id="heading_{{ method_data.operationId }}">
<h5 class="mb-0">
<span class="badge badge-info">{{ method }}</span>
<button class="btn btn-link" data-toggle="collapse"
data-target="#collapse_{{ method_data.operationId }}"
aria-expanded="true"
aria-controls="collapse_{{ method_data.operationId }}">
{{ path }}
</button>
<span class="small">{{ method_data.summary }}</span>
</h5>
</div>
<div id="collapse_{{ method_data.operationId }}"
class="collapse"
aria-labelledby="heading_{{ method_data.operationId }}"
data-parent="#accordion">
<div class="card-body">
<dl class="row">
<dt class="col-sm-3">OperationId</dt>
<dd class="col-sm-9">{{ method_data.operationId }}</dt>
<dt class="col-sm-3">Tags</dt>
<dd class="col-sm-9">{{ method_data.tags }}</dt>
<dt class="col-sm-3">Description</dt>
<dd class="col-sm-9">{{ method_data.description }}</dd>
{% if existsIn(method_data, "parameters") %}
<dt class="col-sm-3">Parameters</dt>
<dd class="col-sm-9">
<table class="table table-sm">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Description</th>
<th scope="col">Type</th>
</tr>
</thead>
<tbody>
{% for param in method_data.parameters %}
{% if existsIn(param, "name") %}
<tr>
<td>{{ param.name }}</td>
<td>{{ param.description }}</td>
<td>{{ param.schema.type }}</td>
</tr>
{% else %}
<tr>
<td colspan=3 class="jref">
{{ param }}
</td>
<div class="row top-buffer">
<div class="col">
<h2>Paths</h2>
<div id="accordion">
<div class="card">
{% for path, path_info in paths %}
{% for method, method_data in path_info %}
<div class="card-header" id="heading_{{ method_data.operationId }}">
<h5 class="mb-0">
<span class="path-button btn btn-primary" data-toggle="collapse"
data-target="#collapse_{{ method_data.operationId }}"
aria-expanded="true"
aria-controls="collapse_{{ method_data.operationId }}">{{ method }}</span>
<button class="path-path btn btn-link" data-toggle="collapse"
data-target="#collapse_{{ method_data.operationId }}"
aria-expanded="true"
aria-controls="collapse_{{ method_data.operationId }}">
{{ path }}
</button>
<span class="small">{{ method_data.summary }}</span>
</h5>
</div>
<div id="collapse_{{ method_data.operationId }}"
class="collapse"
aria-labelledby="heading_{{ method_data.operationId }}"
data-parent="#accordion">
<div class="card-body">
<dl class="row">
<dt class="col-sm-3">OperationId</dt>
<dd class="col-sm-9">{{ method_data.operationId }}</dt>
<dt class="col-sm-3">Tags</dt>
<dd class="col-sm-9">{{ method_data.tags }}</dt>
<dt class="col-sm-3">Description</dt>
<dd class="col-sm-9">{{ method_data.description }}</dd>
{% if existsIn(method_data, "parameters") %}
<dt class="col-sm-3">Parameters</dt>
<dd class="col-sm-9">
<table class="table table-sm">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Description</th>
<th scope="col">Type</th>
</tr>
</thead>
<tbody>
{% for param in method_data.parameters %}
{% if existsIn(param, "name") %}
<tr>
<td>{{ param.name }}</td>
<td>{{ param.description }}</td>
<td>{{ param.schema.type }}</td>
</tr>
{% else %}
<tr>
<td colspan=3 class="jref">
{{ param }}
</td>
{% endif %}
{% endfor %}
</tbody>
</table>
</dt>
{% endif %}
{% endfor %}
</tbody>
</table>
</dt>
{% endif %}
<dt class="col-sm-3">Responses</dt>
<dd class="col-sm-9 jref">{{ method_data.responses}}</dd>
</dl>
</div>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
<h2>Models</h2>
<div id="accordion">
<div class="card">
{% for schema_name, schema_model in components.schemas %}
<div class="card-header" id="heading_{{ schema_name }}">
<a name="{{ schema_name }}" />
<h5 class="mb-0">
<span class="badge badge-info">{{ schema_name }}</span>
<button class="btn btn-link" data-toggle="collapse"
data-target="#collapse_{{ schema_name }}"
aria-expanded="true"
aria-controls="collapse_{{ schema_name }}">
{{ schema_name }}
</button>
</h5>
</div>
<div id="collapse_{{ schema_name }}"
class="collapse"
aria-labelledby="heading_{{ schema_name }}"
data-parent="#accordion">
<div class="card-body">
<dl class="row">
<dt class="col-sm-3">Type</dt>
<dd class="col-sm-9">{{ schema_model.type }}</dt>
<dt class="col-sm-3">Properties</dt>
<dd class="col-sm-9">
<table class="table table-sm">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Description</th>
<th scope="col">Type</th>
<th scope="col">Example</th>
</tr>
</thead>
<tbody>
{% for property_name, property_data in schema_model.properties %}
{% if existsIn(property_data, "example") and existsIn(property_data, "description") %}
<tr>
<td>{{ property_name }}</td>
<td>{{ property_data.description }}</td>
<td>{{ property_data.type }}</td>
<td>
{% if isArray(property_data.example) %}
<ul>
{% for example in property_data.example %}
<li>{{ example }}</li>
{% endfor %}
</ul>
{% else %}
{{ property_data.example }}
{% endif %}
</td>
</tr>
{% else %}
<tr>
<td>{{ property_name }}</td>
<td colspan=3 class="jref">
{{ property_data }}
</td>
{% endif %}
{% endfor %}
</tbody>
</table>
</dt>
<dt class="col-sm-3">Required</dt>
<dd class="col-sm-9">
<ul>
{% for req in schema_model.required %}
<li>{{ req }}</li>
{% endfor %}
</ul>
</dd>
</dl>
</div>
</div>
{% endfor %}
</div>
</div>
<dt class="col-sm-3">Responses</dt>
<dd class="col-sm-9 jref">{{ method_data.responses}}</dd>
</dl>
</div>
</div>
{% endfor %}
{% endfor %}
</div>
</div>
</div>
</div> <!-- // .row -->
<div class="row top-buffer">
<div class="col">
<h2>Models</h2>
<div id="accordion">
<div class="card">
{% for schema_name, schema_model in components.schemas %}
<div class="card-header" id="heading_{{ schema_name }}">
<a name="{{ schema_name }}" />
<h5 class="mb-0">
<button class="model-toggle btn btn-link" data-toggle="collapse"
data-target="#collapse_{{ schema_name }}"
aria-expanded="true"
aria-controls="collapse_{{ schema_name }}">
{{ schema_name }}
</button>
</h5>
</div>
<div id="collapse_{{ schema_name }}"
class="collapse"
aria-labelledby="heading_{{ schema_name }}"
data-parent="#accordion">
<div class="card-body">
<dl class="row">
<dt class="col-sm-3">Type</dt>
<dd class="col-sm-9">{{ schema_model.type }}</dt>
<dt class="col-sm-3">Properties</dt>
<dd class="col-sm-9">
<table class="table table-sm">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Description</th>
<th scope="col">Type</th>
<th scope="col">Example</th>
</tr>
</thead>
<tbody>
{% for property_name, property_data in schema_model.properties %}
{% if existsIn(property_data, "example") and existsIn(property_data, "description") %}
<tr>
<td>{{ property_name }}</td>
<td>{{ property_data.description }}</td>
<td>{{ property_data.type }}</td>
<td>
{% if isArray(property_data.example) %}
<ul>
{% for example in property_data.example %}
<li>{{ example }}</li>
{% endfor %}
</ul>
{% else %}
{{ property_data.example }}
{% endif %}
</td>
</tr>
{% else %}
<tr>
<td>{{ property_name }}</td>
<td colspan=3 class="jref">
{{ property_data }}
</td>
{% endif %}
{% endfor %}
</tbody>
</table>
</dt>
<dt class="col-sm-3">Required</dt>
<dd class="col-sm-9">
<ul>
{% for req in schema_model.required %}
<li>{{ req }}</li>
{% endfor %}
</ul>
</dd>
</dl>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
</div>
{% include "footer.html" %}

View File

@ -98,6 +98,12 @@ void QgsWfs3APIHandler::handleRequest( const QgsServerApiContext &context ) cons
}
};
// Add links only if not OPENAPI3 to avoid validation errors
if ( QgsServerOgcApiHandler::contentTypeFromRequest( context.request() ) != QgsServerOgcApi::ContentType::OPENAPI3 )
{
data["links"] = links( context );
}
// Gather path information from handlers
json paths = json::array();
for ( const auto &h : mApi->handlers() )