Close

changing path for content resources that images, css and scripts

digitalmbs
9 years ago
#8409 Quote
Avatar
  • 17
Hi,

We are using CDN and it will be good to have one configurable option to specify url path for all the resource i.e. images, css and scripts for Motion themes and plugins. Currently it works fine with Nop Core resource as we are using Accelerator CDN plugin which overloads the GetPictureURL method of core nop to replace with configured path however, it doesn't work with Motion theme and plugins because they are all hardcoded. Is it possible to change this to system variable instead of hardcoding it please? 
iliyan.tanev
9 years ago
#8424 Quote
Avatar
  • Moderator
  • 347
Hi,

We are using only what nopCommerce provides for linking scripts and resources, which is bundling. The bundling of nopCommerce does not provide a way to work with CDNs, but it provides a way to override the methods that are responsible for the scripts bundling.
You could easily override the methods and refer to this StackOverflow question to make the bundling work with CDNs .

Regarding the images: all images specific to our themes are linked through the css, because they are mostly background images. If you want to use load them through CDN you will have to change the paths from the css file. 
Regards,
Iliyan Tanev
Nop-Templates Dev Team
ehubcap
8 years ago
#10747 Quote
Avatar
  • 43
iliyan.tanev wrote:
Hi,

We are using only what nopCommerce provides for linking scripts and resources, which is bundling. The bundling of nopCommerce does not provide a way to work with CDNs, but it provides a way to override the methods that are responsible for the scripts bundling.
You could easily override the methods and refer to this StackOverflow question to make the bundling work with CDNs .

Regarding the images: all images specific to our themes are linked through the css, because they are mostly background images. If you want to use load them through CDN you will have to change the paths from the css file. 


Iliyan, I'm struggling with getting my bundles uploaded to my Azureedge end point
Can you indicate or give a heads up on how override these methods on the PageHeadBuilder.cs but is not working, This Friday I opened a ticket Support ID: 3494 that contains a succinct info on the issue
Could you give me some help with that, I'm stuck on this last barrier before starting migrating my live website to my Azure web app site
Thank you
Jose Plunkett
ehubcap  
iliyan.tanev
8 years ago
#10750 Quote
Avatar
  • Moderator
  • 347
Hi,

Take a look at this article.

In your ticket, you have replaced the path in GetBundleVirtualPath method with your CDN URL, but this method accepts only relative paths. According to the above article the place to specify your CDN path is the bundle constructor:

var bundle = new StyleBundle(bundleVirtualPath, "//cdn4-st1.azureedge.net/bundles/styles/");


Another important point is the UseCdn option:

BundleTable.Bundles.UseCdn = true;   //enable CDN support


In this case, my example is with style bundle, but for the JS is the same only the bundle type is ScriptBundle.

Hope this helps!
Regards,
Iliyan Tanev
Nop-Templates Dev Team
ehubcap
8 years ago
#10752 Quote
Avatar
  • 43
Thank you Iliyan for you response
i tried that iteration as well with no success
here is exactly what i did:

  if (bundleFiles.Value)
            {
                //bundling is enabled
                var result = new StringBuilder();
                var partsToBundle = distinctParts.ToArray();
                if (partsToBundle.Length > 0)
                {
                    //IMPORTANT: Do not use CSS bundling in virtual categories
                    string bundleVirtualPath = GetBundleVirtualPath("~/bundles/styles/", ".css", partsToBundle);
                    //create bundle
                    lock (s_lock)
                    {                   
                    var bundleCdnPath = "https//cdn4-st1.azureedge.net{0}";
                        var bundleFor = BundleTable.Bundles.GetBundleFor(bundleVirtualPath);
                        if (bundleFor == null)
                        {
                            var bundle = new StyleBundle(bundleVirtualPath, bundleCdnPath);
                            //bundle.Transforms.Clear();


                            //"As is" ordering
                            bundle.Orderer = new AsIsBundleOrderer();
                            //disable file extension replacements. renders scripts which were specified by a developer
                            bundle.EnableFileExtensionReplacements = false;
                            foreach (var ptb in partsToBundle)
                            {
                                bundle.Include(ptb, GetCssTranform());
                            }
                            BundleTable.Bundles.Add(bundle);
                            BundleTable.Bundles.UseCdn = true;
                            BundleTable.EnableOptimizations = true;
                        }
                    }


                    //parts to bundle
                    result.AppendLine(Styles.RenderFormat("bundleVirtualPath", "bundleCdnPath").ToString());
                }

                return result.ToString();
            }

=============================================================================================
I went beyond that and also registered the bundles in Global.asax.cs by including these code snipets:
[code]
      public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("favicon.ico");
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            
            //register custom routes (plugins, etc)
            var routePublisher = EngineContext.Current.Resolve<IRoutePublisher>();
            routePublisher.RegisterRoutes(routes);
            
            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                new[] { "Nop.Web.Controllers" }
            );
        }
        public class BundleConfig
        {
            public static void RegisterBundles(BundleCollection bundles)
            {
                BundleTable.EnableOptimizations = true;
                bundles.UseCdn = true;
            }
        }


        protected void Application_Start()
        {
            //disable "X-AspNetMvc-Version" header name
            MvcHandler.DisableMvcResponseHeader = true;


            //initialize engine context
            EngineContext.Initialize(false);


            bool databaseInstalled = DataSettingsHelper.DatabaseIsInstalled();
            if (databaseInstalled)
            {
                //remove all view engines
                ViewEngines.Engines.Clear();
                //except the themeable razor view engine we use
                ViewEngines.Engines.Add(new ThemeableRazorViewEngine());
            }




            //Add some functionality on top of the default ModelMetadataProvider
 
ehubcap
8 years ago
#10756 Quote
Avatar
  • 43
Sorry for the duplicates, tried by can't delete them
ehubcap
8 years ago
#10757 Quote
Avatar
  • 43
This override code doesn't work either


                  string bundleVirtualPath = GetBundleVirtualPath("~/bundles/styles/", ".css", partsToBundle);
                    //create bundle
                    lock (s_lock)
                    {                   
                        var bundleFor = BundleTable.Bundles.GetBundleFor(bundleVirtualPath);
                        //var bundleCdnPath = "//cdn4-st1.azureedge.net/bundles/styles/";
                        if (bundleFor == null)
                        {
                            var bundle = new StyleBundle(bundleVirtualPath, "https//cdn4-st1.azureedge.net");
                            //bundle.Transforms.Clear();




                            //"As is" ordering
                            bundle.Orderer = new AsIsBundleOrderer();
                            //disable file extension replacements. renders scripts which were specified by a developer
                            bundle.EnableFileExtensionReplacements = false;
                            foreach (var ptb in partsToBundle)
                            {
                                bundle.Include(ptb, GetCssTranform());
                            }
                            BundleTable.Bundles.Add(bundle);
                            BundleTable.Bundles.UseCdn = true;
                        }
                    }


                    //parts to bundle
                    result.AppendLine(Styles.Render("bundleVirtualPath", "https//cdn4-st1.azureedge.net").ToString());
                }


                return result.ToString();
            }


Question: Which is the correct override way to configure ASP.Net MVC bundleConfig class to bundles from Azure CDN?
iliyan.tanev
8 years ago
#10758 Quote
Avatar
  • Moderator
  • 347
Hi,

Are you running your site in debug mode? Make sure you are running it in release.

Can you elaborate more on what do you mean by bundleConfig class?
Regards,
Iliyan Tanev
Nop-Templates Dev Team
ehubcap
8 years ago
#10759 Quote
Avatar
  • 43
The site is being developed locally in debug mode so the bundling only apply to the release thru a config transform (flag <compilation xdt:Transform="RemoveAttributes(debug)" />)
when publishing to Azure 
The public class BundleConfig was an attempt to register the bundles in Globalasax.cs that I later deleted
I was trying to check all the possible options with this 

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.IgnoreRoute("favicon.ico");
            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            
            //register custom routes (plugins, etc)
            var routePublisher = EngineContext.Current.Resolve<IRoutePublisher>();
            routePublisher.RegisterRoutes(routes);
            
            routes.MapRoute(
                "Default", // Route name
                "{controller}/{action}/{id}", // URL with parameters
                new { controller = "Home", action = "Index", id = UrlParameter.Optional },
                new[] { "Nop.Web.Controllers" }
            );
        }
        //public class BundleConfig
        //{
        //    public static void RegisterBundles(BundleCollection bundles)
        //    {
        //        BundleTable.EnableOptimizations = true;
        //        bundles.UseCdn = true;
        //    }
        //}




        protected void Application_Start()
        {
            //disable "X-AspNetMvc-Version" header name
            MvcHandler.DisableMvcResponseHeader = true;




            //initialize engine context
            EngineContext.Initialize(false);


            bool databaseInstalled = DataSettingsHelper.DatabaseIsInstalled();
            if (databaseInstalled)
            {
                //remove all view engines
                ViewEngines.Engines.Clear();
                //except the themeable razor view engine we use
                ViewEngines.Engines.Add(new ThemeableRazorViewEngine());
            }




            //Add some functionality on top of the default ModelMetadataProvider
            ModelMetadataProviders.Current = new NopMetadataProvider();




            //Registering some regular mvc stuff
            AreaRegistration.RegisterAllAreas();
            RegisterRoutes(RouteTable.Routes);
            //BundleConfig.RegisterBundles(BundleTable.Bundles);

iliyan.tanev
8 years ago
#10762 Quote
Avatar
  • Moderator
  • 347
Hi,

You can not use the BundleConfig class in nopCommerce because the bundle registration is in PageHeadBuilder.

After some research, I found that the bundling for multiple files does not work with CDN. You can have only one file bundled from CDN. Actually, if you think about it, it doesn't make sense to create a bundle of multiple files that come from CDN.

In your case, it would be best to bundle all your files, upload the bundle to your CDN and use this file.

Note: The EnableOptimizations option is needed when you want to test your bundling in Debug mode.

Please take a look at the following screenshot:

.
Regards,
Iliyan Tanev
Nop-Templates Dev Team