Skip to content

Commit

Permalink
Various enhancements to html2 docsgen (OpenAPITools#643)
Browse files Browse the repository at this point in the history
This commit includes the following changes:

- Fix docs not generating parameter descriptions, add rust sample.
- Add example to doc output.
- Add basic scope reporting.
- Stringify the JSON "Example" objects for response schemas.
- Prettify JSON examples in response schemas.
- Parse and present multiline response descriptions.
- Add API error details to docsgen.
- Add read only markers to read only properties.
- Fix up style document indentation.
- Add support for `x-shared-errors`, an extension to define common error types that can be shared across a microservice framework.
  • Loading branch information
bjgill authored and wing328 committed Jul 26, 2018
1 parent 0394dda commit 2e0f433
Show file tree
Hide file tree
Showing 10 changed files with 1,769 additions and 448 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@

package org.openapitools.codegen.languages;

import io.swagger.v3.core.util.Json;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.media.ArraySchema;
import io.swagger.v3.oas.models.media.Schema;

import com.fasterxml.jackson.databind.JsonNode;
import org.apache.commons.lang3.StringUtils;
import org.openapitools.codegen.CliOption;
import org.openapitools.codegen.CodegenConfig;
Expand Down Expand Up @@ -175,6 +177,22 @@ public void preprocessOpenAPI(OpenAPI openAPI) {
additionalProperties.put("jsModuleName", jsModuleName);

preparHtmlForGlobalDescription(openAPI);

Map<String, Object> vendorExtensions = openAPI.getExtensions();
if (vendorExtensions != null) {
for(Map.Entry<String, Object> vendorExtension: vendorExtensions.entrySet()) {
// Vendor extensions could be Maps (objects). If we wanted to iterate through them in our template files
// without knowing the keys beforehand, the default `toString` method renders them unusable. Instead, we
// convert them to JSON strings now, which means we can easily use them later.
if (vendorExtension.getValue() instanceof Map) {
this.vendorExtensions().put(vendorExtension.getKey(), Json.mapper().convertValue(vendorExtension.getValue(), JsonNode.class));
} else {
this.vendorExtensions().put(vendorExtension.getKey(), vendorExtension.getValue());
}
}
}
openAPI.setExtensions(this.vendorExtensions);

}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@import url('https://fonts.googleapis.com/css?family=Source+Code+Pro');
156 changes: 114 additions & 42 deletions modules/openapi-generator/src/main/resources/htmlDocs2/index.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -103,20 +103,31 @@
});
</script>
<style type="text/css">
{{>css_bootstrap}}
{{>css_prettify}}
{{>styles}}
{{>fonts}}
{{>css_bootstrap}}
{{>css_prettify}}
{{>styles}}
</style>
</head>
<body>
<script>
// Script section to load models into a JS Var
var defs = {}
{{#models}}
{{#model}}
defs.{{name}} = {{{modelJson}}};
{{/model}}
{{#models}}
{{#model}}
defs["{{name}}"] = {{{modelJson}}};
{{/model}}
{{/models}}
var errs = {};
{{#swagger.vendorExtensions.x-shared-errors}}
{
let err = {{{.}}};
errs[err.errorID] = err;
}
{{/swagger.vendorExtensions.x-shared-errors}}
</script>

<div class="container-fluid">
Expand Down Expand Up @@ -162,7 +173,9 @@
<div class="app-desc">Version: {{{version}}}</div>
{{/version}}
<hr>
<div>{{{appDescription}}}</div>
<div id="app-description" class="app-desc">
{{{appDescription}}}
</div>
</div>
</div>
<div id="sections">
Expand Down Expand Up @@ -200,6 +213,7 @@
<li class=""><a href="#examples-{{baseName}}-{{nickname}}-0-php">PHP</a></li>
<li class=""><a href="#examples-{{baseName}}-{{nickname}}-0-perl">Perl</a></li>
<li class=""><a href="#examples-{{baseName}}-{{nickname}}-0-python">Python</a></li>
<li class=""><a href="#examples-{{baseName}}-{{nickname}}-0-rust">Rust</a></li>
</ul>

<div class="tab-content">
Expand Down Expand Up @@ -243,8 +257,22 @@
<div class="tab-pane" id="examples-{{baseName}}-{{nickname}}-0-python">
<pre class="prettyprint"><code class="language-python">{{>sample_python}}</code></pre>
</div>

<div class="tab-pane" id="examples-{{baseName}}-{{nickname}}-0-rust">
<pre class="prettyprint"><code class="language-rust">{{>sample_rust}}</code></pre>
</div>
</div>

<h2>Scopes</h2>
<table>
{{#authMethods}}{{#scopes}}
<tr>
<td>{{scope}}</td>
<td>{{description}}</td>
</tr>
{{/scopes}}{{/authMethods}}
</table>

<h2>Parameters</h2>

{{#hasPathParams}}
Expand Down Expand Up @@ -314,31 +342,77 @@

<h2>Responses</h2>
{{#responses}}
<h3> Status: {{code}} - {{message}} </h3>

<ul class="nav nav-tabs nav-tabs-examples" >
<h3 id="examples-{{baseName}}-{{nickname}}-title-{{code}}"></h3>
<p id="examples-{{baseName}}-{{nickname}}-description-{{code}}" class="marked"></p>
<script>
var response{{baseName}}{{code}}_description = `{{{message}}}`;
var response{{baseName}}{{code}}_description_break = response{{baseName}}{{code}}_description.indexOf('\n');
if (response{{baseName}}{{code}}_description_break == -1) {
$("#examples-{{baseName}}-{{nickname}}-title-{{code}}").text("Status: {{code}} - " + response{{baseName}}{{code}}_description);
} else {
$("#examples-{{baseName}}-{{nickname}}-title-{{code}}").text("Status: {{code}} - " + response{{baseName}}{{code}}_description.substring(0, response{{baseName}}{{code}}_description_break));
$("#examples-{{baseName}}-{{nickname}}-description-{{code}}").html(response{{baseName}}{{code}}_description.substring(response{{baseName}}{{code}}_description_break));
}
</script>


<ul id="responses-detail-{{baseName}}-{{nickname}}-{{code}}" class="nav nav-tabs nav-tabs-examples" >
{{#schema}}
<li class="active">
<a data-toggle="tab" href="#responses-{{nickname}}-{{code}}-schema">Schema</a>
<a data-toggle="tab" href="#responses-{{baseName}}-{{nickname}}-{{code}}-schema">Schema</a>
</li>

{{#examples}}
<li class="">
<a data-toggle="tab" href="#responses-{{nickname}}-{{code}}-example">Response Example</a>
<a data-toggle="tab" href="#responses-{{baseName}}-{{nickname}}-{{code}}-example">Response Example</a>
</li>
{{/examples}}

{{/schema}}

{{#hasHeaders}}
<li class="">
<a data-toggle="tab" href="#responses-{{nickname}}-{{code}}-headers">Headers</a>
</li>
{{/hasHeaders}}

{{#vendorExtensions}}
{{#x-shared-errors}}
<script>
$(document).ready(function()
{
var errRef = "{{{$ref}}}";
var errorID = errRef.substring(errRef.lastIndexOf("/") + 1);
var errorDef = errs[errorID];
var tabID = 'responses-detail-{{baseName}}-{{nickname}}-{{code}}-' + errorID;
var contentID = tabID + "-content";
$('#responses-detail-{{baseName}}-{{nickname}}-{{code}}').append("<li><a href='#" + tabID + "' data-toggle='tab'>" + errorID + "</a></li>");
var contentWrapper = $('#responses-{{baseName}}-{{nickname}}-{{code}}-wrapper');
contentWrapper.append('<div class="tab-pane" id="' + tabID + '"><div id="' + contentID + '" class="exampleStyle"></div></div>');
var contentPane = $('#' + contentID);
contentPane.append('<p>' + errorDef.message + '</p>');
if (errorDef.variables)
{
contentPane.append('<h4>Variables</h4>');
var lVars = $('<ol></ol>').appendTo(contentPane);
for (lii = 0; lii < errorDef.variables.length; lii++)
{
$("<li></li>").appendTo(lVars).text(errorDef.variables[lii]);
}
}
});
</script>
{{/x-shared-errors}}
{{/vendorExtensions}}
</ul>

<div class="tab-content" style='margin-bottom: 10px;'>

<div class="tab-content" id="responses-{{baseName}}-{{nickname}}-{{code}}-wrapper" style='margin-bottom: 10px;'>
{{#schema}}
<div class="tab-pane active" id="responses-{{nickname}}-{{code}}-schema">
<div id='responses-{{nickname}}-{{code}}-schema-{{code}}' style="padding: 30px; border-left: 1px solid #eee; border-right: 1px solid #eee; border-bottom: 1px solid #eee;">
<div class="tab-pane active" id="responses-{{baseName}}-{{nickname}}-{{code}}-schema">
<div id="responses-{{baseName}}-{{nickname}}-schema-{{code}}" class="exampleStyle">
<script>
$(document).ready(function() {
var schemaWrapper = {{{jsonSchema}}};
Expand All @@ -352,45 +426,43 @@
});
}
//console.log(JSON.stringify(schema));
var view = new JSONSchemaView(schema, 3);
$('#responses-{{nickname}}-{{code}}-schema-data').val(stringify(schema));
var result = $('#responses-{{nickname}}-{{code}}-schema-{{code}}');
$('#responses-{{baseName}}-{{nickname}}-{{code}}-schema-data').val(JSON.stringify(schema));
var result = $('#responses-{{baseName}}-{{nickname}}-schema-{{code}}');
result.empty();
result.append(view.render());
});
</script>
</div>
<input id='responses-{{nickname}}-{{code}}-schema-data' type='hidden' value=''></input>
<input id='responses-{{baseName}}-{{nickname}}-{{code}}-schema-data' type='hidden' value=''></input>
</div>
{{#examples}}
<div class="tab-pane" id="responses-{{nickname}}-{{code}}-example">
<pre class="prettyprint"><code class="json">{{example}}</code></pre>
</div>
<div class="tab-pane" id="examples-{{baseName}}-{{nickname}}-{{code}}-example">
<pre class="prettyprint"><code class="json">{{example}}</code></pre>
</div>
{{/examples}}
{{/schema}}
{{#hasHeaders}}
<div class="tab-pane" id="responses-{{nickname}}-{{code}}-headers">
<table>
<tr>
<th width="150px">Name</th>
<th width="100px">Type</th>
<th width="100px">Format</th>
<th>Description</th>
</tr>
{{#headers}}
<tr>
<td>{{#name}}{{name}}{{/name}}</td>
<td>{{#datatype}}{{dataType}}{{/datatype}}</td>
<td>{{#dataFormat}}{{dataFormat}}{{/dataFormat}}</td>
<td>{{#description}}{{description}}{{/description}}</td>
</tr>
{{/headers}}
</table>
</div>
<div class="tab-pane" id="responses-{{nickname}}-{{code}}-headers">
<table>
<tr>
<th width="150px">Name</th>
<th width="100px">Type</th>
<th width="100px">Format</th>
<th>Description</th>
</tr>
{{#headers}}
<tr>
<td>{{#name}}{{name}}{{/name}}</td>
<td>{{#datatype}}{{dataType}}{{/datatype}}</td>
<td>{{#dataFormat}}{{dataFormat}}{{/dataFormat}}</td>
<td>{{#description}}{{description}}{{/description}}</td>
</tr>
{{/headers}}
</table>
</div>
{{/hasHeaders}}
</div>

{{/responses}}
</article>
</div>
Expand Down
Loading

0 comments on commit 2e0f433

Please sign in to comment.