Modifications to Swagger UI header - asp.net-web-api

I have created a personal WEB API using Swashbuckle and Swagger API.
While I am able to integrate this successfully, I would like to modify the default UI for Swagger. Changing the color of the header and replacing the swagger image.
Is this possible by modifying existing files?

These are the steps I took:
Create a new file SwaggerHeader.css
Right click on SwaggerHeader.css, select Properties. Set Build action to Embedded Resource.
In SwaggerConfig.cs, add the below line of code:
EnableSwaggerUi("Document/{*assetPath}", c =>
{
c.InjectStylesheet(typeof(SwaggerConfig).Assembly,
"ProjectName.FolderName.SwaggerHeader.css");
}
SwaggerHeader.css looks like the below:
/* swagger ui customization */
body.swagger-section #header {
background-color: white;
background: url(your-new-logo.png) no-repeat;
background-position-x: 250px;
height: 50px;
}
body.swagger-section #header .swagger-ui-wrap #logo {
display: none;
}

First step is to add a new css file in your project, with your custom rules.
For example :
.swagger-section #header { background-color: #fadc00; }
Right click on the new file and go Properties. In "Build Actions" select "Embedded Ressources".
Inside the SwaggerConfig file, inject the stylesheet. The resource name should be the "Logical Name" for the resource. That is where I got stuck, but thanks to this Swashbuckle doc I could infer the logical name following the rule :
Default Namespace for your project "dot" folder containing the resource "dot" file name with extension.
It's based on the Project's default namespace, file location and file
extension. For example, given a default namespace of
"YourWebApiProject" and a file located at
"/SwaggerExtensions/index.html", then the resource will be assigned
the name - "YourWebApiProject.SwaggerExtensions.index.html"
For example :
.EnableSwaggerUi(c =>
{
c.InjectStylesheet(thisAssembly, "Some.Default.Namespace.App_Start.swagger.css");
});

Startup
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseStaticFiles();
.....................
.....................
app.UseSwagger();
app.UseSwaggerUI(c =>
{
c.SwaggerEndpoint("/swagger/v1/swagger.json", "API V1");
c.InjectStylesheet("/css/swagger-custom.css");
});
}
Swagger custom css
img[alt="Swagger UI"] {
display: block;
-moz-box-sizing: border-box;
box-sizing: border-box;
content: url('../images/logo.png');
max-width: 100%;
max-height: 100%;
}
.swagger-section #header {
background-color: #fff !important;
}
.swagger-ui .topbar {
padding: 10px 0;
background-color: #fff !important;
border-bottom: 1px solid #dee2e6 !important;
}
.swagger-ui .topbar .download-url-wrapper .select-label {
display: flex;
align-items: center;
width: 100%;
max-width: 600px;
margin: 0;
color: #121416 !important;
}

To change the color, you can inject a new stylesheet
Qoute from the SwaggerConfig.cs file
Use the "InjectStylesheet" option to enrich the UI with one or more a dditional CSS stylesheets.
The file must be included in your project as an "Embedded Resource", and then the resource's
"Logical Name" is passed to the method as shown below.
c.InjectStylesheet(containingAssembly,"Swashbuckle.Dummy.SwaggerExtensions.testStyles1.css");
Remember to set Build Action of the stylesheet to "Embedded Resource".

Alternativelly, I have created a custom.css in my wwwroot folder and just added
options.InjectStylesheet("/custom.css");
and it worked as well.

Related

Laravel mix - Change production CSS output options

I am trying to change the CSS output style in webpack.mix.js, however it only seems to affect the Development build. How do I apply outpoutStyle options to the Production build?
Here, is my code in the webpack.mix.js file, changing the value of "outputstyle" only affects the Development build.
mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css', {
outputStyle : 'expanded'
})
.copy(`resources/images`, `public/images`, false);
laravel-mix: version 5.0.4
sass-loader: version 7.1.0
EDIT - Additional Information:
The problem I'm trying to solve is that my code works fine with a developer build, but then goes pear-shaped when I run a production build. I suspect it has something to do with how the production build takes something like this:
.selector-1 {
background-color: green;
color: red;
}
.selector-2 {
background-color: blue;
color: red;
}
and compiles it to this:
.selector-1 {
background-color: green;
}
.selector-1, .selector-2 {
color: red;
}
.selector-2 {
background-color: blue;
}
In my case, that's undesirable behavior and I believe it's causing scoping issues with my CSS Custom Properties. The compiled code is thousands of lines long so I haven't been able to pinpoint the exact problem - but I notice the development build doesn't do that and everything works fine.
Basically, I’ve got something like this, which I’m using for theming:
:root {
—theme-base: red;
}
.theme-green {
—theme-base: green;
}
everything works fine in Dev mode… but in Prod some of the elements are inheriting the wrong colour value.
So turns out the specific CSS you're trying to output is quite key. From private messaging you I found out it's to do with borders, and your original code is this:
.selector-1 {
border-top-width: 2px;
border-top-style: solid;
border-color: get-color(base, body);
}
In production mode that compiles to
.selector-1 {
border-color: var(--color-base-body)
}
.selector-1 {
border-top: 2px solid;
}
The problem is that if those border properties are in different class selectors, even though they're the same the browser doesn't know what to do with it. We need a way to have all of the relevant border properties in one selectors. Like so:
.selector-1 {
border: 2px solid get-color(base, body);
border-width: 2px 0 0;
}
That compiles to
.u-border-top-2 {
border: solid var(--color-base-body);
border-width: 2px 0 0;
}
...which renders correctly in the browser.
I'm not sure if this is a bug in sass-loader or if a new version fixes it - on first view it looks like the correct behaviour but the cases of borders not so much.

How to stop Opencart v3 SCSS compiler

I am trying to create a theme for OpenCart v3 and like its default theme I am also using bootstrap framework. There are no files with SCSS/SASS extension but every time I refresh the page it looks into bootstrap.min.css file and somehow breaks it down into scss files and compiles it again. Due to this the default bootstrap over rides all my styles.
I remember I once accidentally clicked the scss clean cache button but this does not mean I allowed it to keep on breaking and recompiling bootstrap again and again even the scss make cache option is on.
It comes up with these kind of links.
Here is a sample to explain the problem copied from inspect element about having no border radius anywhere on the theme:
// ...opencart/catalog/view/javascript/bootstrap4/css/bootstrap.min.css
.dropdown-menu {
position: absolute;
top: 100%;
left: 0;
z-index: 1000;
display: none;
float: left;
min-width: 10rem;
padding: .5rem 0;
margin: .125rem 0 0;
font-size: 1rem;
color: #212529;
text-align: left;
list-style: none;
background-color: #fff;
background-clip: padding-box;
border: 1px solid rgba(0,0,0,.15);
border-radius: .25rem;
}
// .. opencart/catalog/view/theme/alpha/stylesheet/theme.css
.dropdown-menu, * {
border-radius: 0;
}
How can I stop scss compiler permanently? or on the other hand if I prefer to write my own Scss file instead of CSS then will OpenCart compile that too for the development phase of do I need to use terminal for that as I always do?
Found the following code in OpenCart but I don't understand this:
class ControllerStartupSass extends Controller {
public function index() {
$file = DIR_APPLICATION . 'view/theme/' . $this->config->get('theme_directory') . '/stylesheet/bootstrap.css';
if (!is_file($file) || (is_file(DIR_APPLICATION . 'view/theme/' . $this->config->get('theme_directory') . '/stylesheet/sass/_bootstrap.scss') && !$this->config->get('developer_sass'))) {
include_once(DIR_STORAGE . 'vendor/scss.inc.php');
$scss = new Scssc();
$scss->setImportPaths(DIR_APPLICATION . 'view/theme/' . $this->config->get('theme_directory') . '/stylesheet/sass/');
$output = $scss->compile('#import "_bootstrap.scss"');
$handle = fopen($file, 'w');
flock($handle, LOCK_EX);
fwrite($handle, $output);
fflush($handle);
flock($handle, LOCK_UN);
fclose($handle);
}
}
}
Just turn off SASS and theme cache:
Go to admin panel
Click the blue button with gearwheel
Click "off" buttons
And clear cache

How to replace Swagger UI header logo in Swashbuckle

I am using the Swashbuckle package for WebAPI and am attempting to customize the look and feel of the swagger ui default page.
I would like to customize the default swagger logo/header. I have added the following to SwaggerConfig
.EnableSwaggerUi(c =>
{
c.InjectJavaScript(thisAssembly,
typeof(SwaggerConfig).Namespace + ".SwaggerExtensions.custom-js.js");
}
The contents of custom-js.js are as follows:
$("#logo").replaceWith("<span id=\"test\">test</span>");
This works for the most part but the visual is a bit jarring, in that the default swagger header is visible while the page loads and after a brief delay the jquery below kicks and the content of the #logo element is updated
Is there a way to avoid this so that the jquery kicks in as part of the initial load/render and it appears seamless?
Here are the steps instead of using the index.html
Step 1:
Create your logo en put it into a folder, in my case I created a separate folder(I am not using the wwwroot) and I named Content. Use StaticFiles for stream content from this folder access via /Content
app.UseStaticFiles(); // For the wwwroot folder if you need it
app.UseStaticFiles(new StaticFileOptions()
{
FileProvider = new PhysicalFileProvider(
Path.Combine(Directory.GetCurrentDirectory(), "Content")),
RequestPath = "/Content"
});
Stem #2:
Create an image folder inside Content and place your logo.jpg file. Right-click over the file and change the Build Action to Embedded resource
Step #3:
Create a css folder inside Content and place a new file swagger-mycustom.css and change the Build Action to Content
On your Startup Configure method add this code
app.UseSwaggerUI(setupAction =>
{
....
setupAction.InjectStylesheet("/Content/css/swagger-mycustom.css");
...
}
Step #4:
Add this to your css:
img[alt="Swagger UI"] {
display: block;
-moz-box-sizing: border-box;
box-sizing: border-box;
content: url('/Content/images/logo.jpg');
max-width: 100%;
max-height: 100%;
}
The output looks like this:
This worked for me with the last version of Swagger UI in Swashbuckle
.swagger-ui img {
content: url([logo_path]);
width: 140px; /* width of your logo */
height: 40px; /* height of your logo */
}
If you don't want to create the index.html, you can also update the logo with injected css, this is a lot faster than js injection.
In swagger config enable the c.InjectStylesheet and point to the css you created
In the css itself:
.logo__img {
background: url([PathToLogo]) no-repeat;
display: block;
-moz-box-sizing: border-box;
box-sizing: border-box;
width: 64px; /* Width of new image */
height: 25px; /* Height of new image */
padding-left: 64px; /* Equal to width of new image */
}
credits for css trick:
https://css-tricks.com/replace-the-image-in-an-img-with-css/
I ended up adding a new "index.html" based off this version
instead of trying to modify the behavior of the default generated one
To replace logo in swagger in api for .net core, you have to add the custom.js file.
Follow below steps to change logo.
Step 1 - Create custom.js file and add following code in it
(function () {
window.addEventListener("load", function () {
setTimeout(function () {
var logo = document.getElementsByClassName('link');
logo[0].children[0].alt = "Logo";
logo[0].children[0].src = "/logo.png";
});
}); })();
Step 2 - Inject thar custom.js file in startup.cs file. See below
app.UseSwaggerUI(c =>
{
c.InjectJavascript("/custom.js");
});
Step 3 - Enable static file in the api if not enabled. Add below line of code in Configure method of startup.cs.
app.UseStaticFiles();
#MichaelD can simply do the following instead:
.logo__img {
content: url([PathToLogo]);
width: 72px; /* Width of new image */
height: 31px; /* Height of new image */
}
The custom-js.js need to be placed after all js file.

How to add a class to Laravel next and previous pagination links

I am using the built in Laravel 5.2 pagination with the ->render() function to output the pagination links. I need to add a class to the next and previous links in order to style them. Is there a simple way to do it?
If you want to change pagination links style just a little bit (for example, just change some colors), easiest way to do that is overriding some of the pagination related CSS classes. For example, you can add this code to your CSS file and see how links style will be changed:
.pagination>li>a, .pagination>li>span {
color: #6db91c;
border: 1px solid #000;
}
.pagination>li>a:hover, .pagination>li>span:hover, .pagination>li>a:focus, .pagination>li>span:focus {
color: #fff;
background-color: #6db91c;
border-color: #6db91c
}
.pagination>.active>a, .pagination>.active>span, .pagination>.active>a:hover, .pagination>.active>span:hover, .pagination>.active>a:focus, .pagination>.active>span:focus {
z-index: 2;
color: #fff;
background-color: #6db91c;
border-color: #6db91c
}
.pagination>.disabled>span, .pagination>.disabled>span:hover, .pagination>.disabled>span:focus, .pagination>.disabled>a, .pagination>.disabled>a:hover, .pagination>.disabled>a:focus {
color: #000; background-color: #fff; border-color: #000; cursor: not-allowed
}
If you don't want to do that for some reason, you can create custom pagination.
for front end css framework like i use bulma i simply create jQuery Dom select pagination child li and add class pagination-link example
$(document).ready(function(){
// Setting Pagination Bulma Class
$('.pagination>li').addClass("pagination-link");
});

jqGrid Pager Area - Using Font Awesome Icons

I would like to use Font Awesome icons:
<i class="icon-edit"></i>
in the jqGrid pager area instead of the physical images by default.
.navButtonAdd('#vw_ComplaintSearchGridPager', { caption: '', buttonicon: 'ui-icon-disk', title: 'Save Grid Settings', onClickButton: function () { $(this).SaveGridSetting(); } })
Does anyone know how to achieve this?
It's very interesting question! I never used Font Awesome icons before, but it seems very interesting project.
jqGrid has currently no direct support of Font Awesome icons, but I prepared the simple demo which shows how to replace the standard jQuery UI navigator icons with the corresponding icons from Font Awesome.
One can see mostly clear the difference to the original navigator icons after zoom of the page. I included below the navigator displayed with zoom 400%:
The original navigator using jQuery UI icons
The navigator with Font Awesome icons:
The code which I used is very simple. Instead of usage
$grid.jqGrid("navGrid", "#pager", {view: true});
I used
$grid.jqGrid("navGrid", "#pager", {editicon: "icon-pencil",
addicon: "icon-plus", delicon: "icon-trash", searchicon: "icon-search",
refreshicon: "icon-refresh", viewicon: "icon-file",view: true});
$("#pager .navtable .ui-pg-div>span").removeClass("ui-icon");
I added the CSS
.ui-jqgrid .ui-jqgrid-pager .ui-pg-div>span { margin: 0 5px; font-size: 12px; }
I think it's possible to replace more jQuery UI icons to Font Awesome icons, but it's not very simple. I will think about the problem more and will contact the developer of jqGrid (Tony Tomov) to consider to make jqGrid more friendly to Font Awesome icons, so that it could be possible very simple switch to Font Awesome icons.
UPDATED: I added the code which allows top replace more icons from the pager:
var $pager = $grid.closest(".ui-jqgrid").find(".ui-pg-table");
$pager.find(".ui-pg-button>span.ui-icon-seek-first")
.removeClass("ui-icon ui-icon-seek-first")
.addClass("icon-step-backward");
$pager.find(".ui-pg-button>span.ui-icon-seek-prev")
.removeClass("ui-icon ui-icon-seek-prev")
.addClass("icon-backward");
$pager.find(".ui-pg-button>span.ui-icon-seek-next")
.removeClass("ui-icon ui-icon-seek-next")
.addClass("icon-forward");
$pager.find(".ui-pg-button>span.ui-icon-seek-end")
.removeClass("ui-icon ui-icon-seek-end")
.addClass("icon-step-forward");
As the result one get the following pager:
instead of
UPDATED 2: The code for changing minimizing icon looks a little completer. One should first change the icon initially
$grid.closest(".ui-jqgrid")
.find(".ui-jqgrid-titlebar>.ui-jqgrid-titlebar-close>.ui-icon-circle-triangle-n")
.removeClass("ui-icon ui-icon-circle-triangle-n")
.addClass("icon-circle-arrow-down");
and then change it after every click on the icon:
onHeaderClick: function (gridstate) {
if (gridstate === "visible") {
$(this.grid.cDiv).find(">.ui-jqgrid-titlebar-close>span")
.removeClass("icon-circle-arrow-up ui-icon-circle-triangle-n")
.addClass("icon-circle-arrow-down");
} else if (gridstate === "hidden") {
$(this.grid.cDiv).find(">.ui-jqgrid-titlebar-close>span")
.removeClass("icon-circle-arrow-down ui-icon-circle-triangle-s")
.addClass("icon-circle-arrow-up");
}
}
Additionally one need to add the CSS
.ui-jqgrid .ui-jqgrid-titlebar-close>span { margin: 0 3px; font-size: 16px; }
.ui-jqgrid .ui-jqgrid-titlebar-close { text-decoration: none; }
To fix the sorting icons I used the code
var $sortables = $grid.closest(".ui-jqgrid")
.find(".ui-jqgrid-htable .ui-jqgrid-labels .ui-jqgrid-sortable span.s-ico");
$sortables.find(">span.ui-icon-triangle-1-s")
.removeClass("ui-icon ui-icon-triangle-1-s")
.addClass("icon-sort-down");
$sortables.find(">span.ui-icon-triangle-1-n")
.removeClass("ui-icon ui-icon-triangle-1-n")
.addClass("icon-sort-up");
and the CSS
.ui-jqgrid .ui-icon-asc { height: auto; margin-top: 0; }
.ui-jqgrid .ui-icon-asc, .ui-jqgrid .ui-icon-desc {
height: auto; margin-top: 0; margin-left: 5px;
}
.ui-jqgrid .s-ico>.ui-state-disabled, .s-ico>.ui-state-disabled { padding: 0; }
As the result one will get the following:
UPDATED 3: In the next demo one can find more full replacement of jQuery UI icons to Font Awesome icons.
UPDATED 4: The answer provides solution for Font Awesome version 4.x.
Figured I would put a CSS alternative answer for those interested. One of our developers implemented a JS option, which did functionally work, however, there was a delay before it rendered correctly (not ideal).
We used font-awesome icons for our paging options, and here is how we implemented it.
Found the four classes that jqGrid was using for the paging icons we desired to customize and created the following css to apply base font awesome styles
.ui-icon-seek-next, .ui-icon-seek-prev, .ui-icon-seek-end, .ui-icon-seek-first
{
display: inline-block;
font-family: FontAwesome;
font-style: normal;
font-weight: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
Then it is simply a matter of grabbing the content from font-family icon and using them as your own.
.ui-icon-seek-next:before
{
content: "\f105";
}
.ui-icon-seek-prev:before
{
content: "\f104";
}
.ui-icon-seek-end:before
{
content: "\f101";
}
.ui-icon-seek-first:before
{
content: "\f100";
}
So the entire CSS together looks like this
.ui-icon-seek-next, .ui-icon-seek-prev, .ui-icon-seek-end, .ui-icon-seek-first
{
display: inline-block;
font-family: FontAwesome;
font-style: normal;
font-weight: normal;
line-height: 1;
-webkit-font-smoothing: antialiased;
}
.ui-icon-seek-next:before
{
content: "\f105";
}
.ui-icon-seek-prev:before
{
content: "\f104";
}
.ui-icon-seek-end:before
{
content: "\f101";
}
.ui-icon-seek-first:before
{
content: "\f100";
}
And the output on our grid without JS and without delay
By looking at answer from Oleg above, I did the following to simplify things.
Additional CSS
.ui-jqgrid .ui-jqgrid-pager .ui-pg-div>span.fntawsm { margin: 0 5px; font-size: 12px; padding-left:2px;padding-right:2px;}
** padding-left:2px;padding-right:2px; is optional
And this only works with icons only with no caption ...
And then just start adding fontawesome icons in navButtonAdd like
caption:"", // important for above
title:"Give any",
buttonicon:"fntawsm icon-remove"
buttonicon:"fntawsm icon-eject icon-rotate-90"
etc .. You can use all extra functionality from font-awesome like icon-rotate-XX too.
Thisway i did`nt have to remove ui-icon class from spans.
Inspired by #afreeland answer, I created a css available on github which allows you to convert your icons to Font-Awesome icons.
The performance advantage of this over the jquery method that #Oleg described is important in my opinion.
It is also a very elegant solution in my opinion.
You are welcome to use it: https://github.com/guylando/ToAF
Note: you must give priority for this ToAF.css file styles over your other icons styles so that can be achieved for example by copying the css content into a tag in your document.

Resources