mvc bundle and css management strategy - css

I developed a website, which can be used by different customers. As a result, we want to give different CSS styles and images to individual customers.
What we want is to manage CSS and images separately, so we won't need to deploy the site again just because we added some new CSS or images. As the site is under MVC, when accessing URLs such as:
www.mysite.com/customerA/myPage
www.mysite.com/customerB/myPage
we can find the customer id and find the right CSS and image to return.
The problem is that we want to bundle CSS, when the CSS or images are bundled, two issues will occur:
How the bundle detect underlying CSS file change? Is it possible?
Some users may already visited the URL and cached the bundled CSS, how can we disable the cached CSS, so it will get the new version?

The .NET bundling strategy is very intelligent in solving both of your issues. Once you create a bundle - example below:
bundles.Add(new StyleBundle("~/Content/css").Include(
"~/Content/bootstrap.css",
"~/Content/site.css"));
And render this bundle out on your website, the output looks something like this:
<link href="/Content/css?v=xUfHQEnjwMk9UEexrvHPdvPxJduGrgz0bbI5qy5BGHY1" rel="stylesheet"/>
Notice the ?v=bigTextstring. Anytime a file in your bundle changes, the bundling framework will change the bigTextString after the ?v=. So, for your first question, yes, it will automatically detect file changes. You can get more information about how all of that process works if you visit this SO question. For your second question, the ?v= parameter, when changed, signals the client's browser that this is a different file than you had, you need to download it again.

Tommy has a great answer. I just wanted to elaborate on a few points.
First, as long as the bundle itself hasn't changed (added/removed scripts/styles or changed the location of those files), then you can freely update the files themselves without republishing the whole site. The bundler runs at runtime and looks at the last modified timestamp of the included files. If any of the files has changed, a new bundle will be generated with an updated cache-busting querystring param.
However, since the actual bundle configuration is code-based, if you add/remove items from the bundle or change the location of the file(s), such that you have to update the bundle configuration in BundleConfig.cs then you must republish, or at least also update the project DLL. This is because the code compiled within that DLL has changed.

Related

Can't change the css in SuiteCRM

I am working on SuiteCRM, and i want to change the CSS of my website in order to personalize it but there is an issue.
When i am changing the "style.css" of the SuiteP Theme, the pages aren't changing at all. Here is my question:
Does someone know how to change the css of this CRM and can help me to fix it ?
Thanks a lot
Make sure that your active theme is "SuiteP".
You need to know that SuiteCRM store things inside "cache" folder and you are doing changes without refreshing cache files. Cache files location will be cache/themes/SuiteP/css/style.css. So for quick changes, you can use browser developer tools.
Moreover, if you change core style.css then empty cache directory and (hard)refresh your browser. If cache files don't exist then Suite will build new using core file.
Like Star previously mentioned, Suite does cache the CSS.
Though, if you're not updating the SASS file, and just updating the CSS directly, your changes will be temporary for when the CRM next re-builds the CSS (I believe this is part of the Repair and Rebuild process in the admin section), your changes will be lost as the CSS file constructed from the style.scss file.
I'd recommend installing sass (via a gem or other means, however you choose), making changes to the scss then recompiling the css (or watching for changes if working locally, which I hope you are for working with Suite) when you've applied your changes.
If you still don't experience changes, try a repair and re-build or delete the cache directory and let it recompile on the next page load.
there are 2 options:
change core file and then delete cache contents. Refresh your page twice.
made changes in cache file. Make sure developer mood is off. Once you are done then copy it core file.
Create a new subfolder CUSTOM, copy the CSS files that are under suiteP (or the current theme) into the new custom. copy the whole path with folders, even if the folders are empty.
So the new path for the sytle.css with be /costum/theme/....../css/sytle.css
Change the file under the custom folder. The previous answers are not correct. This is well documented under the suite CRM docs.
Sometimes it doesn't work. Try next steps:
SuiteCRM better to use in development mode.
Not always the cache files deleting works for me. Better to use the tool in Admin panel - Quick Repair.
Sometimes good to clear browser cache (in dev mode reload a page by right clicking the refresh button).

ASP.NET MVC - Make Cached Styles Expired upon Release using Bundling

This is how I include JavaScript files in my ASP.NET MVC application,
Bundles.Add(new ScriptBundle(ConfigBundles.Scripts).Include
(
"~/Content/Scripts/Libraries/framework-{version}.js",
"~/Content/Scripts/Libraries/controls-{version}.js"
));
My understanding is that whenever I do a new release where the referenced JavaScript files have changed, i just need to increment the version number so that user's web browsers know that they need to clear the existing cache and request the new file.
However, this same process does not seem to work for stylesheets - this is how I load them:
Bundles.Add(new StyleBundle(ConfigBundles.Styles)
.Include("~/Content/Styles/Site-{version}.css", new CssRewriteUrlTransform()));
However, this does not seem to work - when I change the name of the Site.css to include a version, the bundling doesn't seem to detect it. Furthermore, in most guides on bundling they just talk about using this feature with Scripts - I haven't seen anyone confirm that it can used with styles as well...
Am I going about this the right way?

Referencing files minified by Web Essentials in Visual Studio 2013

I have minified CSS and JS files that are auto-generated by Web Essentials, and auto-updated every time I update and save the original files.
What would be the best way to automatically toggle the actual (script/import) references within HTML between original (in Dev/Test) and minified (in Production) files?
This is within an MVC ASP.NET web app.
One idea would be to have server-side tags that render either ".min" or empty string based on an environment variable. But I'm wondering if there's a better, smarter, easier, more efficient way of handling this.
Thanks in advance.
Update:
My style bundle is defined like this:
bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site{version}.css"));
And I reference it like this:
#Styles.Render("~/Content/css")
However, this renders the following:
<link href="/Content/css?v=" rel="stylesheet"/>
It works fine if I take "{version}" out of bundle definition, but renders an empty "v=" if I include "{version}".
Update 2:
I just realized that due to certain complexities of the application, I can't use the bundling solution. What other options do I have?
Bundling will help you in this instance. You should already be able to see an example in your BundleConfig.cs file in App_Start.
Here is a tutorial on how to conifgure it http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification
From that tutorial, this is how you actually configure the bundles themselves, the files that will be in them, etc. This includes any jquery in the scripts folder into a bundle called ~/bundles/jquery.
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js"));
// Code removed for clarity.
BundleTable.EnableOptimizations = true; // <-- this line overrides the debug check to show you the minified version even in debug mode... remove it for normal .min in debug/un-minned when not in debug behaviour
}
You then reference these from your views using
#Scripts.Render("~/bundles/jquery")
This will then render a script tag with the .min version of the jquery if you're not in debug or leave it out if you are. There needs to be a .min version and an un-minified version in the same scripts folder (which you should have if Web Essentials is creating the .min for you.
You could actually stop using Web Essentials to do the minification if you use ScriptBundles as they will minify the javascript for you when it packages it into the bundle.
For your update
The "~/Scripts/jquery-{version}.js" means match any file in the scripts folder that starts with jquery- and ends with .js and has some version number between. If the files don't have a version number in them, then don't try and use the {version} substitution.
They do it with jquery in this case so that if you upgrade the version of jquery that you are using, you don't have to go back into your BundleConfig and manually change the file name for your jquery reference.
If your file was named site1.3.7.css, then this would probably work.
bundles.Add(new StyleBundle("~/Content/css")
.Include("~/Content/site{version}.css"));
but it sounds more likely that you just need site.css.
bundles.Add(new StyleBundle("~/Content/css")
.Include("~/Content/site.css"));
I'm not sure what you think prevents you from using them but you can link to files in CDNs and minify or not minify. Even just have individual files in a bundle to get the benefit of minification outside of debug without "bundling" them. So there's probably a way.

CSS/JS bundle in single file in mvc when publish with release option

I have created MVC application. When I publish the application on Azure with release option, all css and js file load in a single bundle in page. (Open view source of page then displays a single link for css).
When I publish a site with Debug option in publish profile then all CSS load individual.
My problem is when publish site with release option theme not load correctly, but with debug option theme loads correctly. I want to publish my application with Release option only. If anyone face this issue before and get any solution then please help me.
I have experienced this before when using bundling.
Say for instance your css file is located at: /Content/css/css.css
This css file then makes a reference to another file, or for example an image at /Content/images/image1.png via url('../images/image1.png').
You then set up your css bundle # /bundles/css.
All appears great in debug mode. However, when you set <compilation debug="false" .... in your web.config, suddenly the references made in the css file breaks. If you open your console in Firebug/Chrome dev tools and check the network tabs, you'll see resources failing to load, from an incorrect URL.
This happens because when debug mode is off, all the files are bundled and minified like they would be in production. In this case, the CSS file would be bundled and served from the URL /bundles/css. This results in the relative URL reference breaking. Where it once referenced /Content/images/image1.png, it now references /images/image1.png.
You have a few options to solve this:
Serve your bundled css files from the same folder as the actual css files. eg. /Content/css/cssbundle. This can become very tedious quickly.
Change all relative references in your css files to absolute references. eg. ../images/image1.png would become /Content/images/image1.png. This does mean you can't use a lot third party CSS bundled out of the box, you would have to check/change relative references if you wanted to bundle them.
Use the BundleTransformer nuget package. It automatically transforms relative urls to absolute ones during the bundling process.
The main differences of StyleTransformer and ScriptTransformer classes from a standard implementations: ability to exclude unnecessary assets when adding assets from a directory, does not produce the re-minification of pre-minified assets, support automatic transformation of relative paths to absolute in CSS-code (by using UrlRewritingCssPostProcessor), etc.
I personally recommend 3 as it is the easiest to maintain long term.

The changes not updating on server

I have build MVC 5 application which works fine when running via VS. When I publish it to the server first time it also works. Now I have made few correction to my css file and publish whole project again but website still see the old css file. I have removed all files from the server and tried few more times but it is still the same. When I check the css file on the server, the changes are inside the file.
I think it is related to MVC bundling as when I check the source it says that is accessing different file which is not even located on the server:
<link href="/Content/cssmain?v=Ikj7NnMg3q9kTHR7ynWOJDQFGMZl3mtVMi_2EkOJxc41" rel="stylesheet"/>
How can I force VS to minificate my css file again?
I've tried cleaning, rebuilding but no luck
Edit:
My bundle set up look like below and all files are located on the server in Content folder.
bundles.Add(new StyleBundle("~/Content/cssmain").Include(
"~/Content/bootstrap.css",
"~/Content/site.css",
"~/Content/ilightbox.css",
"~/Content/bannerscollection_zoominout.css"));
Many thanks
I think it is related to MVC bundling as when I check the source it says that is accessing different file which is not even located on the server:
CDN location? External Css lib (yours or 3rd party)? unsure what you meant by "not located on server"?
Yup, it does (look like ASP.net Bundling in action) - check your Global.asax, App_Start/BundleConfig or _AppStart and see if the bundle configuration setup point to/reference the "correct" locations for your css (and or script).
Is it just you experiencing getting the old css file loaded? Or anyone who views the site?

Resources