Skip to content
This repository has been archived by the owner on Nov 12, 2017. It is now read-only.

Commit

Permalink
Sync with bitbucket repo
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidZidar committed Aug 26, 2012
1 parent 515785d commit 1352c58
Show file tree
Hide file tree
Showing 36 changed files with 264 additions and 150 deletions.
15 changes: 8 additions & 7 deletions .gitignore
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
bin/ bin/
obj/ obj/


_ReSharper\.[\w\d\.]+/ _ReSharper.*/
packages/ packages/


\.user$ *.user
\.suo$ *.suo
\.sln\.cache$ *.sln.cache
\.dotCover$ *.dotCover
\.docstates$ *.docstates
\.Publish\.xml$ *.Publish.xml
*.ncrunchsolution
8 changes: 4 additions & 4 deletions NuGet/CacheTag.nuspec
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@
<package > <package >
<metadata> <metadata>
<id>CacheTag</id> <id>CacheTag</id>
<version>1.0.0-beta3</version> <version>1.0.0-beta5</version>
<authors>Steamcore</authors> <authors>Steamcore</authors>
<owners>Steamcore</owners> <owners>Steamcore</owners>
<projectUrl>http://cachetag.net/</projectUrl> <projectUrl>http://cachetag.net/</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance> <requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Simple and efficient JavaScript and CSS minification for ASP.NET MVC</description> <description>Simple and efficient JavaScript and CSS minification for ASP.NET MVC</description>
<releaseNotes>Fixed concurrency issue, updated AjaxMin to v4.54</releaseNotes> <releaseNotes>Updated AjaxMin to v4.62, behavioural changes regarding file extensions and hashes in debug mode</releaseNotes>
<dependencies> <dependencies>
<dependency id="AjaxMin" version="4.54.4533.37029" /> <dependency id="AjaxMin" version="4.62.4618.15628" />
<dependency id="dotless" version="1.3.0.3" /> <dependency id="dotless" version="1.3.0.5" />
<dependency id="Microsoft.Web.Infrastructure" version="1.0.0.0" /> <dependency id="Microsoft.Web.Infrastructure" version="1.0.0.0" />
<dependency id="WebActivator" version="1.5.1" /> <dependency id="WebActivator" version="1.5.1" />
</dependencies> </dependencies>
Expand Down
115 changes: 55 additions & 60 deletions README.md
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -27,37 +27,32 @@ CacheTag provides a number of benefits compared to other similar frameworks.
How to get started How to get started
------------------ ------------------


Add project references to `CacheTag.Core` and the modules you need, `CacheTag.Mvc` is a required module for now. Add project references to **`CacheTag.Core`** and the modules you need, **`CacheTag.Mvc`** is a required module for now.


ASP.NET MVC Razor example ASP.NET MVC Razor example
------------------------- -------------------------


Try something like this in a view: Try something like this in a view:


```csharp :::csharp
@Html.RenderStyles(new [] @Html.RenderStyles(new []
{ {
"~/CSS/Reset.css", "~/CSS/Reset.css",
"~/CSS/Site.less" "~/CSS/Site.less"
}) })
@Html.RenderScripts(new [] @Html.RenderScripts(new []
{ {
"~/Scripts/jquery-1.7.1.js", "~/Scripts/jquery-1.7.1.js",
"~/Scripts/app.coffee" "~/Scripts/app.coffee"
}) })
```


You can also reference scripts or styles mid page like this: You can also reference scripts or styles mid page like this:


```csharp @Html.ReferenceScript("~/Scripts/flot.js")
@Html.ReferenceScript("~/Scripts/flot.js")
```


And then render all referenced scripts at once at the end of the page: And then render all referenced scripts at once at the end of the page:


```csharp @Html.RenderReferencedScripts()
@Html.RenderReferencedScripts()
```


If you want, you can render scripts or styles inline as well, just add Inline to any render method. If you want, you can render scripts or styles inline as well, just add Inline to any render method.


Expand All @@ -66,22 +61,20 @@ Advanced examples


Or you can build your scripts and styles manually: Or you can build your scripts and styles manually:


```csharp :::csharp
var styleTags = new StyleList(new [] { "~/CSS/Reset.css", "~/CSS/Site.less" }).Compile().RenderHtml(); var styleTags = new StyleList(new [] { "~/CSS/Reset.css", "~/CSS/Site.less" }).Compile().RenderHtml();
var scriptTags = new ScriptList(new [] { "~/Scripts/jquery-1.7.1.js", "~/Scripts/app.coffee" }).Compile().RenderHtml(); var scriptTags = new ScriptList(new [] { "~/Scripts/jquery-1.8.0.js", "~/Scripts/app.coffee" }).Compile().RenderHtml();
```


`ScriptList` and `StyleList` are just there for convenience, they only inherit from `List<IScriptList>` and `List<IStyleList>` respectively and do a bit of magic to resolve the type of resources based on the file name. `ScriptList` and `StyleList` are just there for convenience, they only inherit from `List<IScriptList>` and `List<IStyleList>` respectively and do a bit of magic to resolve the type of resources based on the file name.


Since we are working with lists, it's easy to do what you want with it. Since we are working with lists, it's easy to do what you want with it.


```csharp :::csharp
var scriptUrls = var scriptUrls =
new [] { new [] {
new ScriptFile("~/Scripts/jquery-1.7.1.js"), new ScriptFile("~/Scripts/jquery-1.8.0.js"),
new CoffeeScript("~/Scripts/app.coffee") new CoffeeScript("~/Scripts/app.coffee")
}.Compile().Select(x => x.Url); }.Compile().Select(x => x.Url);
```


The code snippet above will load two scripts, compile them if in release mode, and return a list of their resulting URLs. This might be useful for lazy loading scripts via yepnope or something similar. The code snippet above will load two scripts, compile them if in release mode, and return a list of their resulting URLs. This might be useful for lazy loading scripts via yepnope or something similar.


Expand All @@ -90,22 +83,19 @@ Example of resulting HTML in release mode


In release mode resources are combined, and minified if a minification module is referenced, to reduce the number of HTTP requests the client has to make. In release mode resources are combined, and minified if a minification module is referenced, to reduce the number of HTTP requests the client has to make.


```html <link rel="stylesheet" type="text/css" href="/_cachetag/e4dddf2cdd91d693e023cdc5dc0b56d8664766db.css" />
<link rel="stylesheet" type="text/css" href="/_cachetag/e4dddf2cdd91d693e023cdc5dc0b56d8664766db" /> <script src="/_cachetag/80e9e6fc43c6644ea9badec99eb5c6cbec87c4b0.js" type="text/javascript"></script>
<script src="/_cachetag/80e9e6fc43c6644ea9badec99eb5c6cbec87c4b0" type="text/javascript"></script>
```


Example of resulting HTML in debug mode Example of resulting HTML in debug mode
--------------------------------------- ---------------------------------------


When Web.config is configured for debug mode, resources ar linked individually with a SHA1-hash to ease debugging and prevent any browser cache issues. When Web.config is configured for debug mode, resources ar linked individually with a SHA1-hash to ease debugging and prevent any browser cache issues.


```html :::html
<link rel="stylesheet" type="text/css" href="/CSS/Reset.css?f49b5e57ac2258bd3c980f30271554fa4731f26d" /> <link rel="stylesheet" type="text/css" href="/CSS/Reset.css" />
<link rel="stylesheet" type="text/css" href="/CSS/Site.less?b8193c8e87d1b1f3cc6b8ad5ef3d9a1ac2b68961" /> <link rel="stylesheet" type="text/css" href="/CSS/Site.less" />
<script src="/Scripts/jquery-1.7.1.js?b47730ffaec4272a8a01756af2ef13ecea1c4e92" type="text/javascript"></script> <script src="/Scripts/jquery-1.8.0.js" type="text/javascript"></script>
<script src="/Scripts/app.coffee?57818a7855d3931d2884ff32e0949888a225f0d1" type="text/javascript"></script> <script src="/Scripts/app.coffee" type="text/javascript"></script>
```


**Note**: To serve .less and .coffee-files individually in debug mode, you need to add their respective HTTP handlers manually (or via NuGet) to your web project. **Note**: To serve .less and .coffee-files individually in debug mode, you need to add their respective HTTP handlers manually (or via NuGet) to your web project.


Expand All @@ -114,70 +104,75 @@ Available modules


To use a module, simply make a project reference, it will be configured automatically. To use a module, simply make a project reference, it will be configured automatically.


`CacheTag.Mvc` **`CacheTag.Mvc`**
Registers routes and an MVC controller for serving scripts Registers routes and an MVC controller for serving scripts


`CacheTag.Modules.AjaxMin` **`CacheTag.Modules.AjaxMin`**
Minifies scripts and stylesheets using AjaxMin, depends on `AjaxMin` Minifies scripts and stylesheets using AjaxMin, depends on `AjaxMin`


`CacheTag.Modules.DotLess` **`CacheTag.Modules.DotLess`**
Support for .less style sheets files, depends on `dotless.Core` Support for .less style sheets files, depends on `dotless.Core`


`CacheTag.Modules.SassAndCoffee` **`CacheTag.Modules.SassAndCoffee`**
Provides support for .coffee-scripts for now, depends on `SassAndCoffee.Core` and `SassAndCoffee.JavaScript` Provides support for .coffee-scripts for now, depends on `SassAndCoffee.Core` and `SassAndCoffee.JavaScript`


Configuration Configuration
------------- -------------


The idea is sane defaults and zero configuration, but there are some things you can configure if you want. The idea is sane defaults and zero configuration, but there are some things you can configure if you want.


`CacheTag.Core.Configuration.Settings.HashAlgorithm` `CacheTagSettings`.**`HashAlgorithm`**
MD5 is used by default MD5 is used by default


`CacheTag.Core.Configuration.Settings.RuntimeMode` `CacheTagSettings`.**`RuntimeMode`**
Default mode is Dynamic, other options are ForceDebug or ForceRelease Default mode is Dynamic, other options are ForceDebug or ForceRelease


`CacheTag.Mvc.MvcSettings.RouteUrl` `CacheTagSettings`.**`HashFilesInDebugMode`**
If true, then CacheTag will append hash of files includeded in debug mode to force browsers to reload changed resources. Default is off because this confuses debuggers

`CacheTagSettings`.**`HideFileExtensions`**
Set to true if you think file extensions are unnecessary

`CacheTagMvcSettings`.**`RouteUrl`**
Default value is `"_cachetag/{id}"` Default value is `"_cachetag/{id}"`


Create your own module Create your own module
---------------------- ----------------------


Implement ICacheTagModule and it will automatically be run on startup. Implement ICacheTagModule and it will automatically be run on startup.


```csharp :::csharp
public class ModuleConfiguration : ICacheTagModule public class ModuleConfiguration : ICacheTagModule
{
public void Initialize()
{ {
CacheTag.Core.Configuration.Settings.RuntimeMode = RuntimeMode.ForceRelease; public void Initialize()
{
CacheTag.Core.Configuration.Settings.RuntimeMode = RuntimeMode.ForceRelease;
}
} }
}
```


Extension methods Extension methods
----------------- -----------------


Most of CacheTag is based around a couple of extension methods operating on either `IEnumerable<IScriptResource>` or `IEnumerable<IStyleResource>`, these are explained here. Most of CacheTag is based around a couple of extension methods operating on either `IEnumerable<IScriptResource>` or `IEnumerable<IStyleResource>`, these are explained here.


`Compile()` **`Compile()`**
When operating in debug mode, Compile() does nothing, it just returns the same list it was passed. When in release mode however, it will compile the list of resources using whatever resource compiler is registered for that type of resource. For instance, when using the AjaxMin module, Compile() will minify the list and return a list of one item. When operating in debug mode, Compile() does nothing, it just returns the same list it was passed. When in release mode however, it will compile the list of resources using whatever resource compiler is registered for that type of resource. For instance, when using the AjaxMin module, Compile() will minify the list and return a list of one item.


In release mode Compile() also calls Store(), see below. In release mode Compile() also calls Store(), see below.


`RenderHtml()` **`RenderHtml()`**
Renders HTML script tags with items linked as external resources. Renders HTML script tags with items linked as external resources.


`RenderHtmlInline()` **`RenderHtmlInline()`**
Renders HTML script tags with the resource content inlined. Renders HTML script tags with the resource content inlined.


`RenderMvcHtml()` **`RenderMvcHtml()`**
Calls RenderHtml() but wraps the result in a IHtmlString. Calls RenderHtml() but wraps the result in a IHtmlString.


`RenderMvcHtmlInline()` **`RenderMvcHtmlInline()`**
Calls RenderHtmlInline() but wraps the result in a IHtmlString. Calls RenderHtmlInline() but wraps the result in a IHtmlString.


`Store()` **`Store()`**
When serving items as external resources they have to be stored somewhere so they can be retrieved when the browser next requests them. Therefore Store() saves the list of resources in a static Dictionary<> in the class ResourceStorage. When serving items as external resources they have to be stored somewhere so they can be retrieved when the browser next requests them. Therefore Store() saves the list of resources in a static Dictionary<> in the class ResourceStorage.


When running a site in production, scripts and styles tend to be static, so storing your compiled resources in a static dictionary should not be a problem. When running a site in production, scripts and styles tend to be static, so storing your compiled resources in a static dictionary should not be a problem.
3 changes: 2 additions & 1 deletion Source/CacheTag.Core/CacheTag.Core.csproj
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@
<Compile Include="Cache\ICacheProvider.cs" /> <Compile Include="Cache\ICacheProvider.cs" />
<Compile Include="Configuration\Container.cs" /> <Compile Include="Configuration\Container.cs" />
<Compile Include="Configuration\IUrlResolver.cs" /> <Compile Include="Configuration\IUrlResolver.cs" />
<Compile Include="Configuration\MimeTypeMap.cs" />
<Compile Include="Configuration\RuntimeMode.cs" /> <Compile Include="Configuration\RuntimeMode.cs" />
<Compile Include="Configuration\Settings.cs" /> <Compile Include="Configuration\CacheTagSettings.cs" />
<Compile Include="Extensions\HashAlgorithmExtensions.cs" /> <Compile Include="Extensions\HashAlgorithmExtensions.cs" />
<Compile Include="Extensions\ResourceExtensions.cs" /> <Compile Include="Extensions\ResourceExtensions.cs" />
<Compile Include="Extensions\StreamExtensions.cs" /> <Compile Include="Extensions\StreamExtensions.cs" />
Expand Down
31 changes: 31 additions & 0 deletions Source/CacheTag.Core/Configuration/CacheTagSettings.cs
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,31 @@
// ReSharper disable FieldCanBeMadeReadOnly.Global
// ReSharper disable ConvertToConstant.Global

using System.Web;

namespace CacheTag.Core.Configuration
{
public static class CacheTagSettings
{
public const string AssemblyVersion = "1.0.*";

public static string HashAlgorithm = "System.Security.Cryptography.MD5";
public static RuntimeMode RuntimeMode = RuntimeMode.Dynamic;
public static bool HashFilesInDebugMode = false;
public static bool HideFileExtensions = false;

public static string ImageTagFormat = @"<img src=""{0}"" width=""{1}"" height=""{2}"" alt=""{3}"" />";
public static string ScriptTagFormat = @"<script src=""{0}"" type=""text/javascript""></script>";
public static string StyleTagFormat = @"<link rel=""stylesheet"" type=""text/css"" href=""{0}"" />";
public static string InlineScriptTagFormat = @"<script type=""text/javascript"">{0}</script>";
public static string InlineStyleTagFormat = @"<style type=""text/css"">{0}</style>";

public static bool IsReleaseMode
{
get
{
return RuntimeMode == RuntimeMode.ForceRelease || HttpContext.Current.IsDebuggingEnabled == false;
}
}
}
}
59 changes: 59 additions & 0 deletions Source/CacheTag.Core/Configuration/MimeTypeMap.cs
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.Linq;

namespace CacheTag.Core.Configuration
{
public static class FileExtensions
{
public static string GetMimeType(string extension)
{
switch (extension.ToLowerInvariant())
{
case ".jpg":
case ".jpeg":
return "image/jpeg";

case ".gif":
return "image/gif";

case ".png":
return "image/png";

default:
throw new ArgumentException("Unknown file extension");
}
}
}

public static class MimeTypes
{
public static string GetFileExtension(string mimeType)
{
switch (mimeType.ToLowerInvariant())
{
case "application/x-javascript":
case "application/javascript":
case "application/ecmascript":
case "text/javascript":
case "text/ecmascript":
return ".js";

case "text/css":
return ".css";

case "image/jpeg":
return ".jpg";

case "image/gif":
return ".gif";

case "image/png":
return ".png";

default:
throw new ArgumentException("Unknown mime type");
}
}
}
}
2 changes: 1 addition & 1 deletion Source/CacheTag.Core/Extensions/ResourceExtensions.cs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static class ResourceExtensions
public static IEnumerable<T> Compile<T>(this IEnumerable<T> items) public static IEnumerable<T> Compile<T>(this IEnumerable<T> items)
where T : IResource where T : IResource
{ {
return Settings.IsReleaseMode ? Container.Resolve<IResourceCompiler<T>>().Compile(items).Store() : items; return CacheTagSettings.IsReleaseMode ? Container.Resolve<IResourceCompiler<T>>().Compile(items).Store() : items;
} }


public static T Store<T>(this T item) public static T Store<T>(this T item)
Expand Down
2 changes: 1 addition & 1 deletion Source/CacheTag.Core/Properties/AssemblyInfo.cs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@
// Build Number // Build Number
// Revision // Revision
// //
[assembly: AssemblyVersion(Settings.AssemblyVersion)] [assembly: AssemblyVersion(CacheTagSettings.AssemblyVersion)]
8 changes: 5 additions & 3 deletions Source/CacheTag.Core/Resources/BaseFileResource.cs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -61,14 +61,16 @@ protected BaseFileResource(string path, string mimeType, IFileProvider fileProvi


protected virtual void LoadFileProperties(Dictionary<string, object> properties) protected virtual void LoadFileProperties(Dictionary<string, object> properties)
{ {
using (var hashAlgorithm = HashAlgorithm.Create(Settings.HashAlgorithm)) using (var hashAlgorithm = HashAlgorithm.Create(CacheTagSettings.HashAlgorithm))
{ {
var binaryContent = fileProvider.ReadContent(); var binaryContent = fileProvider.ReadContent();
properties["BinaryContent"] = binaryContent; properties["BinaryContent"] = binaryContent;
properties["Hash"] = hashAlgorithm.ComputeStringHash(binaryContent); properties["Hash"] = hashAlgorithm.ComputeStringHash(binaryContent);
properties["Url"] = Settings.IsReleaseMode properties["Url"] = CacheTagSettings.IsReleaseMode
? Container.Resolve<IUrlResolver>().GetResourceUrl(this) ? Container.Resolve<IUrlResolver>().GetResourceUrl(this)
: string.Format("{0}?{1}", fileProvider.AppRelativePath, Hash); : CacheTagSettings.HashFilesInDebugMode
? string.Format("{0}?{1}", fileProvider.AppRelativePath, Hash)
: fileProvider.AppRelativePath;
} }
} }
} }
Expand Down
2 changes: 1 addition & 1 deletion Source/CacheTag.Core/Resources/BaseSnippet.cs
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public abstract class BaseSnippet : IPlainTextResource


protected BaseSnippet(string snippet) protected BaseSnippet(string snippet)
{ {
using (var hashAlgorithm = HashAlgorithm.Create(Settings.HashAlgorithm)) using (var hashAlgorithm = HashAlgorithm.Create(CacheTagSettings.HashAlgorithm))
{ {
Content = snippet; Content = snippet;
Hash = hashAlgorithm.ComputeStringHash(snippet); Hash = hashAlgorithm.ComputeStringHash(snippet);
Expand Down
Loading

0 comments on commit 1352c58

Please sign in to comment.