0

I have tried both squshit and rejuicer to try and combine and minify some css and js from within a view. So far no luck. What I have done is in a filter I put

#region using
    using System;
    using Castle.MonoRail.Framework;
    using campusMap.Models;
    using MonoRailHelper;
    using Rejuicer;
#endregion

namespace campusMap.Filters
{
    public class scriptFilter : IFilter
    {
        public bool Perform(ExecuteWhen exec, IEngineContext context, IController controller, IControllerContext controllerContext)
        {
            controllerContext.PropertyBag["adminRejuicer_css"] = OnRequest.ForCss("~/Content/css/min/Combined.css").Compact;
            controllerContext.PropertyBag["adminRejuicer_js"] = OnRequest.ForJs("~/Content/js/min/Combined.js");
            //controllerContext.PropertyBag["JavaScriptBundle"] = new JavaScriptBundle();
            return true;
        }
    }
}

then on the base controller

#region Directives
    using Castle.MonoRail.Framework;
    using campusMap.Services;
    using System.Text.RegularExpressions;
    using System;
    using campusMap.Models;
    using Castle.ActiveRecord;
    using MonoRailHelper;
    using campusMap.Filters;
    using log4net;
    using log4net.Config;
    using System.Text;

#endregion
namespace campusMap.Controllers
{
    [Filter(ExecuteWhen.BeforeAction, typeof(scriptFilter))]
    [Layout("default"), Rescue("generalerror")]
    public abstract class BaseController : MonoRailHelper.HelperBaseController
    {
    }

And then lastly from with in the view

    $adminRejuicer_css.File("~/Content/css/admin_styles.css").File("~/Content/js/colorpicker/css/jpicker-1.1.6.min.css")

But nothing. If I do basically the same thing with squshit but in the filter its

    controllerContext.PropertyBag["cssBundle"] = Bundle.Css();

and in the veiw

    $cssBundle.Add("~/Content/css/admin_styles.css").Add("~/Content/js/colorpicker/css/jpicker-1.1.6.min.css").Render("~/Content/css/min/admin.css")

This time it at least just outputs the tags for the two scripts, not minified or bundled but at the least it's doing something.

Any ideas on how to do this? thank you -Jeremy

Quantum
  • 1,456
  • 3
  • 26
  • 54

2 Answers2

0

You need to put this in the Global.asax.cs file within the Application_OnStart method

OnRequest.ForCss("~/Content/css/min/Combined.css")

See this blog post (not mine) adding the global.asax.cs file in aspnet web site

Patrick McEvoy
  • 682
  • 6
  • 10
  • Ok. I'll try that.. but how you you tell the difference between lets say side for the admin and one for the front public faceing side.. I would think doing one OnRequest.ForCss("~/Content/css/min/Combined.css") and OnRequest.ForCss("~/Content/css/min/admin_Combined.css") would cause trouble? I'll get back shortly on seeing if that works. tk -- – Quantum Jul 13 '12 at 00:58
  • simply adding OnRequest.ForCss("~/Content/css/min/Combined.css") does not work. And you can't use controllerContext.PropertyBag["adminRejuicer_css"] = OnRequest.ForCss("~/Content/css/min/Combined.css") there either. Hey you don't a castle app with this before? I would think if you know how to do it it'd be much fast to just copy paste to help out. Thank you for the help.. Cheers -- – Quantum Jul 13 '12 at 01:04
0

So this is how it's done. this is using squshit but rejucier is done the same way.

BaseController.cs

#region Directives 
    using Castle.MonoRail.Framework; 
    using campusMap.Services; 
    using campusMap.Models; 
    using Castle.ActiveRecord; 
    using MonoRailHelper; 
    using campusMap.Filters; 
    //any others you'd need
#endregion 
namespace campusMap.Controllers 
{ 
    [Filter(ExecuteWhen.BeforeAction, typeof(scriptFilter))] 
    [Layout("default"), Rescue("generalerror")] 
    public abstract class BaseController : MonoRailHelper.HelperBaseController 
    { 
        protected ScriptsService ScriptsService = new ScriptsService();
    } 
}

Then in the filter

scriptFilter.cs

#region using
    using System;
    using Castle.MonoRail.Framework;
    using campusMap.Models;
    using MonoRailHelper;
    using campusMap.Services;
#endregion

namespace campusMap.Filters
{
    public class scriptFilter : IFilter
    {
        protected ScriptsService scriptsService = new ScriptsService();
        public bool Perform(ExecuteWhen exec, IEngineContext context, IController controller, IControllerContext controllerContext)
        {
            controllerContext.PropertyBag["scriptsService"] = scriptsService;
            return true;
        }
    }
}

You'll see that at this point you are attaching a filter to each call everything is rendered and placing a reference to a service in to the Property bag so we can gain access to it. Next is the service so we may provide the methods to access.

ScriptsService.cs

#region Directives
    using System;
    using campusMap.Models;
    using MonoRailHelper;
    using campusMap.Services;
    using Castle.MonoRail.Framework;
    using campusMap.Filters;

    using SquishIt.Framework;
    using SquishIt.Framework.Css;
    using SquishIt.Framework.JavaScript;
    using System.Security.Cryptography;

#endregion

namespace campusMap.Services
{
    public class ScriptsService
    {
        public static string CalculateMD5Hash(string input)
        {
            // step 1, calculate MD5 hash from input
            MD5 md5 = MD5.Create();
            byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
            byte[] hash = md5.ComputeHash(inputBytes);

            // step 2, convert byte array to hex string
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < hash.Length; i++)
            {
                sb.Append(hash[i].ToString("X2"));
            }
            return sb.ToString();
        }

        public static String Css(string files)
        {
            String name = CalculateMD5Hash(files);
            String path = @"/cache/script/css/";
            String FilePath = path + name + ".css";

            if (!HelperService.DirExists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }
            CSSBundle css = new CSSBundle();     
            foreach (string fl in files.Split(','))
            {
                css.Add(fl);
            }
            return css.ForceRelease().Render(FilePath);
        }
        public static String Js(string files)
        {

            String name = CalculateMD5Hash(files);
            String path = @"/cache/script/js/";
            String FilePath = path + name + ".js" ;

            if (!HelperService.DirExists(path))
            {
                System.IO.Directory.CreateDirectory(path);
            }
            JavaScriptBundle js = new JavaScriptBundle();
            foreach (string fl in files.Split(','))
            {
                js.Add(fl);
            }
            return js.ForceRelease().Render(FilePath);
        }
    }
}

So what you'll want to note in the service is that we are calling a md5 hash of the method argument that gives us a base name.

That is it!! .. View easy to set up. Now how do you use it?

someView.vm

//CSS
$scriptsService.Css("~/Content/css/jquery-ui-1.8.19.custom.css,~/Content/css/central_main.css,~/Content/css/map_admin.css,~/Content/css/colorbox.css?")

//JS
$scriptsService.Js("~/Content/js/modernizr-2.0.6/modernizr.min.js,~/Content/js/jquery.defaultvalue.js,~/Content/js/utilities_general.js,~/Content/js/infobox.js,~/Content/js/jquery.ui.map.js")

One thing to note is never just clear the cache by hand. Squshit will break the client for you so don't worry about touching the files.

That's all there is to it.

Quantum
  • 1,456
  • 3
  • 26
  • 54