How to hide select a spec in swagger-ui.html
Development environment: springboot+swagger2.9.2
To be able to customize parts of the Swagger UI provided by Springfox you have to provide your own version of a JS, HTML or CSS file. In your case, only a custom CSS file is needed.
Put a CSS file (e.g. springfox.css) in the resources folder. The content of the CSS file should be:
.select-label {
display: none !important;
}
select-label is class name of "Select a spec" label area.
Now you have to make your CSS file accessible for Springfox. Therefore, create a simple Controller that provides your CSS file as a Resource at /webjars/springfox-swagger-ui/springfox.css path.
#Controller
#Log4j2
public class CustomizedSwaggerUI {
#Value("classpath:springfox.css")
private Resource cssFile;
#ApiIgnore
#GetMapping(value = "/webjars/springfox-swagger-ui/springfox.css")
public void resourceCSS(HttpServletResponse response) {
try {
response.setHeader("content-type", "text/css;charset=UTF-8");
byte[] file = IOUtils.toByteArray(Objects.requireNonNull(cssFile.getURI()));
response.getOutputStream().write(file);
} catch(Exception e) {
log.error("Error loading customized springfox css file.", e);
}
}
}
That's it.
Related
I want to let user to download a file from server.
I looked up for the solution and when trying to make an example - ended up with this:
#Route("test-download")
public class Download extends VerticalLayout {
public Download() {
Anchor downloadLink = new Anchor(createResource(), "Download");
downloadLink.getElement().setAttribute("download", true);
add(downloadLink);
}
private AbstractStreamResource createResource() {
return new StreamResource("/home/johny/my/important-file.log", this::createExportr);
}
private InputStream createExportr(){
return null;
}
}
Which is giving java.lang.IllegalArgumentException: Resource file name parameter contains '/' when I go to the page in browser.
How do I make a download button (or anchor) knowing file location on disk?
Have a look at the documentation, paragraph "Using StreamResource". The first parameter is just a file name that will be used by the browser to propose that file name to the user when downloading. So you could pass it like "important-file.log". The content of the download is provided by the InputStream parameter. For instance, you could read from your file, see here:
File initialFile = new File("src/main/resources/sample.txt");
InputStream targetStream = new FileInputStream(initialFile);
How do I include external GSPs or template in the GSP file when the template to be included is not under views folder?
Yes, you can easily do that. Here you go:
import grails.gsp.PageRenderer
class MyLib {
static namespace = "foo"
static defaultEncodeAs = "raw"
PageRenderer groovyPageRenderer
def externalTemplate = { attrs, body ->
String externalFilePath = attrs.externalPath
/*
* Put content of that external template to a file inside grails-app/views folder
* with a temporary unique name appended by current timestamp
*/
String temporaryFileName = "_external-" + System.currentTimeMillis() + ".gsp"
File temporaryFile = new File("./grails-app/views/temp/$temporaryFileName")
/*
* Copy content of external file path to the temporary file in views folder.
* This is required since the groovyPageRenderer can compile any GSP located inside
* the views folder.
*/
temporaryFile.text << new File(externalFilePath).text
/*
* Now compile the content of the external GSP code and render it
*/
out << groovyPageRenderer.render([template: "/temp/$temporaryFileName", model: attrs.model])
// Delete the file finally
temporaryFile.delete()
}
}
Now in your actual GSP where you want to include the external GSP, you can write so:
<body>
<foo:externalTemplate externalPath="/home/user/anyExternalFile.gsp" model="${[status: 1}" />
</body>
I know I am late for this reply but I encountered this problem when we tried to put report views outside of the views folder.
We couldn't use the above method because we are running a jar package and we couldn't create files inside views folder.
Here is the solution on Grails 4
first inject
def groovyPagesTemplateEngine
def groovyPageLayoutFinder
then in your controller
File externalFile = new File("/path/to/file.gsp")
if(externalFile && externalFile.exists()){
GroovyPageView groovyPageView = new GroovyPageView()
LinkedHashMap model = [:]
Template template = groovyPagesTemplateEngine.createTemplate(externalFile.text, externalFileName)
groovyPageView.setServletContext(getServletContext())
groovyPageView.setTemplate(template)
groovyPageView.setApplicationContext(getApplicationContext())
groovyPageView.setTemplateEngine(groovyPagesTemplateEngine)
groovyPageView.afterPropertiesSet()
request.setAttribute GrailsLayoutDecoratorMapper.LAYOUT_ATTRIBUTE, null
GrailsLayoutView grailsLayoutView = new GrailsLayoutView(groovyPageLayoutFinder, groovyPageView)
grailsLayoutView.render model, webRequest.getCurrentRequest(), webRequest.getResponse()
webRequest.renderView = false
return
}
else {
// something that shows error
render "not found"
}
I have a multi-tenant application and I'm trying to determine the simplest means of controlling which CSS files are bundled based on the url of any incoming request.
I'm thinking I can have some conditional logic inside RegisterBundles() that takes the Url as a string, and bundles accordingly:
public static void RegisterBundles(BundleCollection bundles, string tenant = null) {
if (tenant == "contoso"){
bundles.Add(new StyleBundle("~/contoso.css")
}
}
But I don't know how to pass the string into RegisterBundles, nor even if it's possible, or the right solution. Any help here would be awesome.
It is not possible to do it in RegisterBundles right now. Dynamically generating the bundle content per request will prevent ASP.net from caching the minified CSS (it's cached in HttpContext.Cache).
What you can do is create one bundle per tenant in RegisterBundles then select the appropriate bundle in the view.
Example code in the view:
#Styles.Render("~/Content/" + ViewBag.TenantName)
Edit:
As you said, setting the TenantName in a ViewBag is problematic since you have to do it per view. One way to solve this is to create a static function like Styles.Render() that selects the correct bundle name based from the current tenant.
public static class TenantStyles
{
public static IHtmlString Render(params string[] paths)
{
var tenantName = "test"; //get tenant name from where its currently stored
var tenantExtension = "-" + tenantName;
return Styles.Render(paths.Select(i => i + tenantExtension).ToArray());
}
}
Usage
#TenantStyles.Render("~/Content/css")
The bundle names will need to be in the this format {bundle}-{tenant} like ~/Content/css-test. But you can change the format ofcourse.
I think you are after a solution that allows you to dynamically control the BundleCollection. As far as I know this is currently not possible.
The bundles are configured during app start/configured per the application domain.
A future version of ASP.NET may support this feature i,e using VirtualPathProvider.
Here is some discussion.
See also this SO question.
i'm not good in english, but if you mean you need to handle which CSS file load when you run any URL in your page, i can handle css file in a controler.
First, create a controller name : ResourceController
// CREATE PATH TO CSS FOLDER, I store in webconfig <add key="PathToStyles" value="/Content/MyTheme/" />
private static string _pathToStyles = ConfigurationManager.AppSettings["PathToStyles"];
public void Script(string resourceName)
{
if (!String.IsNullOrEmpty(resourceName))
{
var pathToResource = Server.MapPath(Path.Combine(_pathToScripts, resourceName));
TransmitFileWithHttpCachePolicy(pathToResource, ContentType.JavaScript.GetEnumDescription());
}
}
public void Style(string resourceName)
{
if (!String.IsNullOrEmpty(resourceName))
{
var pathToResource = Server.MapPath(Path.Combine(_pathToStyles, resourceName));
TransmitFileWithHttpCachePolicy(pathToResource, ContentType.Css.GetEnumDescription());
}
}
private void TransmitFileWithHttpCachePolicy(string pathToResource, string contentType)
{
//DO WHAT YOU WANT HERE;
Response.ContentType = contentType;
Response.TransmitFile(pathToResource);
}
//You can handle css or js file...
private enum ContentType
{
[EnumDescription("text/css")]
Css,
[EnumDescription("text/javascript")]
JavaScript
}
In file Global.asax.cs, make sure in application start medthod, in contain the route config
protected void Application_Start()
{
RouteConfig.RegisterRoutes(RouteTable.Routes);
}
Go to routeConfig, add below map to this file (must be add in top of this file) :
routes.MapRoute(
name: "Resource",
url: "resource/{action}/{resourceName}",
defaults: new { controller = "Resource" }
);
Now, create a UrlHelperExtensions class, same path with webconfig file
public static class UrlHelperExtensions
{
public static string Style(this UrlHelper urlHelper, string resourceName)
{
return urlHelper.Content(String.Format("~/resource/style/{0}", resourceName));
}
}
And from now, you can define css file in your view like :
..."<"link href="#Url.Style("yourcss.css")" rel="stylesheet" type="text/css"
/>
Hope this help
I'm testing ui and themes for new Grails web-app I need to develop.
I would like to know if it's possibile to override theme zones (http://grailsrocks.github.io/grails-platform-ui/guide/creatingThemes.html#themeRequiredZones) in my app.
I know it's possible for theme layouts and ui sets templates (http://grailsrocks.github.io/grails-platform-ui/guide/advanced.html#advancedOverridingThemeLayouts).
In concrete in my test app I would like to override:
<theme:layoutTemplate name="header"/>
/grails-app/views/_themes/Bootstrap/_header.gsp
and
<theme:layoutZone name="navigation"/>
/grails-app/views/_themes/Bootstrap/default/_navigation.gsp
Here is my Config.groovy:
compile ":platform-ui:1.0.RC3"
runtime ':bootstrap-theme:1.0.RC3'
grails.plugin.location.'grails-platform-ui-scaffolding' = "../grails-platform-ui-scaffolding"
Next version of platform-ui plugin will fix this https://github.com/MerryCoders/grails-platform-ui/pull/7
In the meantime here is a custom TagLib used as a workaround, at least for layoutTemplate tag.
class OwnThemeTagLib extends org.grails.plugin.platform.ThemeTagLib {
def layoutTemplate = { attrs ->
def templateView = grailsThemes.getRequestThemeTemplateView(request, attrs.name)
// Location of app's standard content for theme layout templates
// /grails-app/views/_themes/<ThemeName>/<templateName>
def layoutTemplatePath = "/_themes/${templateView.owner}/${attrs.name}"
// First see if the application provides default content for this template
if (grailsViewFinder.templateExists(layoutTemplatePath)) {
if (log.debugEnabled) {
log.debug "Resolved current request's theme template for [${attrs.name}] to [${layoutTemplatePath}]"
}
delegate.out << g.render(template:layoutTemplatePath)
} else {
if (log.debugEnabled) {
log.debug "Resolved current request's theme template for [${attrs.name}] to [${templateView}]"
}
delegate.out << g.render(template:templateView.path, plugin:templateView.plugin)
}
}
}
I've got a pop-up textarea, where the user writes some lengthy comments. I would like to store the content of the textarea to a file on the server on "submit". What is the best way to do it and how?
THanks,
This would be very easy to do. The text could be just a string or stringBuffer for size and formatting, then just pass that to your java code and use file operations to write to a file.
This is some GWT code, but it's still Ajax, so it will be similar. Get a handler for an event to capture the button submittal, then get the text in the text area.
textArea.addChangeHandler(new ChangeHandler() {
public void onChange(ChangeEvent changeEvent) {
String text = textArea.getText();
}
});
The passing off mechanism I don't know because you don't show any code, but I just created a file of filenames, line by line by reading filenamesout of a list of files with this:
private void writeFilesListToFile(List<File> filesList) {
for(File file : filesList){
String fileName = file.getName();
appendToFile(fileName);
}
}
private void appendToFile(String text){
try {
BufferedWriter out = new BufferedWriter(new FileWriter<file path andfile name>));
out.write(text);
out.newLine();
out.close();
} catch (IOException e) {
System.out.println("Error appending file with filename: " + text);
}
}
You could do something similar, only write out the few lines you got from the textarea. Without more to go on I can't really get more specific.
HTH,
James