diff --git a/DancingGoat/App_Data/DancingGoat.es-ES.Designer.cs b/DancingGoat/App_Data/DancingGoat.es-ES.Designer.cs new file mode 100644 index 0000000..e69de29 diff --git a/DancingGoat/App_Data/DancingGoat.es-ES.resx b/DancingGoat/App_Data/DancingGoat.es-ES.resx new file mode 100644 index 0000000..352c944 --- /dev/null +++ b/DancingGoat/App_Data/DancingGoat.es-ES.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Sobre Nosotros + + + Artículo + + \ No newline at end of file diff --git a/DancingGoat/App_Start/RouteConfig.cs b/DancingGoat/App_Start/RouteConfig.cs index f450cbb..9b26983 100644 --- a/DancingGoat/App_Start/RouteConfig.cs +++ b/DancingGoat/App_Start/RouteConfig.cs @@ -1,5 +1,6 @@ using System.Web.Mvc; using System.Web.Routing; +using DancingGoat.Infrastructure; namespace DancingGoat { @@ -9,19 +10,52 @@ public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); - routes.MapMvcAttributeRoutes(); + var route = routes.MapRoute( + name: "CoffeesCatalog", + url: "{language}/product-catalog/coffees/{action}/{urlSlug}", + defaults: new { language = "en-us", controller = "Coffees", action = "Index", urlSlug = UrlParameter.Optional }, + constraints: new { language = @"\w\w-\w\w" } + ); + route.RouteHandler = new LocalizedMvcRouteHandler("en-US"); - routes.MapRoute( - name: "Default", - url: "{controller}/{action}/{urlSlug}", - defaults: new { controller = "Home", action = "Index", urlSlug = UrlParameter.Optional } + route = routes.MapRoute( + name: "BrewersCatalog", + url: "{language}/product-catalog/brewers/{action}/{urlSlug}", + defaults: new { language = "en-us", controller = "Brewers", action = "Index", urlSlug = UrlParameter.Optional }, + constraints: new { language = @"\w\w-\w\w" } + ); + route.RouteHandler = new LocalizedMvcRouteHandler("en-US"); + + route = routes.MapRoute( + name: "Articles", + url: "{language}/articles", + defaults: new { language = "en-us", controller = "Articles", action = "Index" }, + constraints: new { language = @"\w\w-\w\w" } ); + route.RouteHandler = new LocalizedMvcRouteHandler("en-US"); + route = routes.MapRoute( + name: "Article", + url: "{language}/articles/{urlSlug}", + defaults: new { language = "en-us", controller = "Articles", action = "Show", urlSlug = ""}, + constraints: new { language = @"\w\w-\w\w" } +); + route.RouteHandler = new LocalizedMvcRouteHandler("en-US"); + route = routes.MapRoute( + name: "LocalizedContent", + url: "{language}/{controller}/{action}/{urlSlug}", + defaults: new { language = "en-us", controller = "Home", action = "Index", urlSlug = UrlParameter.Optional}, + constraints: new { language = @"\w\w-\w\w"} + ); + route.RouteHandler = new LocalizedMvcRouteHandler("en-US"); + + // Display a custom view when no route is found routes.MapRoute( name: "Error", - url: "Errors/{error}", - defaults: new { controller = "Error", action = "NotFound" } + url: "{*url}", + defaults: new { language = "en-US", controller = "Errors", action = "NotFound" } ); + } } } \ No newline at end of file diff --git a/DancingGoat/Controllers/AboutController.cs b/DancingGoat/Controllers/AboutController.cs index 73c786f..37c9940 100644 --- a/DancingGoat/Controllers/AboutController.cs +++ b/DancingGoat/Controllers/AboutController.cs @@ -5,10 +5,8 @@ namespace DancingGoat.Controllers { - [RoutePrefix("about")] public class AboutController : ControllerBase { - [Route] public async Task Index() { var response = await client.GetItemAsync("about_us"); diff --git a/DancingGoat/Controllers/ArticlesController.cs b/DancingGoat/Controllers/ArticlesController.cs index 0b6deea..292f7aa 100644 --- a/DancingGoat/Controllers/ArticlesController.cs +++ b/DancingGoat/Controllers/ArticlesController.cs @@ -8,22 +8,19 @@ namespace DancingGoat.Controllers { - [RoutePrefix("articles")] public class ArticlesController : ControllerBase { - [Route] public async Task Index() { var response = await client.GetItemsAsync
( new EqualsFilter("system.type", "article"), new OrderParameter("elements.post_date", SortOrder.Descending), - new ElementsParameter("teaser_image", "post_date", "summary", "url_pattern") + new ElementsParameter("teaser_image", "post_date", "summary", "url_pattern", "title") ); return View(response.Items); } - [Route("{urlSlug}")] public async Task Show(string urlSlug) { var response = await client.GetItemsAsync
(new EqualsFilter("elements.url_pattern", urlSlug), new EqualsFilter("system.type", "article")); diff --git a/DancingGoat/Controllers/BrewersController.cs b/DancingGoat/Controllers/BrewersController.cs index dac439e..7feeb95 100644 --- a/DancingGoat/Controllers/BrewersController.cs +++ b/DancingGoat/Controllers/BrewersController.cs @@ -7,10 +7,8 @@ namespace DancingGoat.Controllers { - [RoutePrefix("product-catalog/brewers")] public class BrewersController : ControllerBase { - [Route] public async Task Index() { var response = await client.GetItemsAsync( diff --git a/DancingGoat/Controllers/CafesController.cs b/DancingGoat/Controllers/CafesController.cs index ce3a6bb..6fd5653 100644 --- a/DancingGoat/Controllers/CafesController.cs +++ b/DancingGoat/Controllers/CafesController.cs @@ -6,10 +6,8 @@ namespace DancingGoat.Controllers { - [RoutePrefix("cafes")] public class CafesController : ControllerBase { - [Route] public async Task Index() { var response = await client.GetItemsAsync( diff --git a/DancingGoat/Controllers/CoffeesController.cs b/DancingGoat/Controllers/CoffeesController.cs index 78248fd..1d3cd5a 100644 --- a/DancingGoat/Controllers/CoffeesController.cs +++ b/DancingGoat/Controllers/CoffeesController.cs @@ -7,10 +7,8 @@ namespace DancingGoat.Controllers { - [RoutePrefix("product-catalog/coffees")] public class CoffeesController : ControllerBase { - [Route] public async Task Index() { var response = await client.GetItemsAsync( diff --git a/DancingGoat/Controllers/ContactsController.cs b/DancingGoat/Controllers/ContactsController.cs index a7650ce..168aff7 100644 --- a/DancingGoat/Controllers/ContactsController.cs +++ b/DancingGoat/Controllers/ContactsController.cs @@ -6,10 +6,8 @@ namespace DancingGoat.Controllers { - [RoutePrefix("contacts")] public class ContactsController : ControllerBase { - [Route] public async Task Index() { var response = await client.GetItemsAsync( diff --git a/DancingGoat/Controllers/ControllerBase.cs b/DancingGoat/Controllers/ControllerBase.cs index bcd86aa..dff720e 100644 --- a/DancingGoat/Controllers/ControllerBase.cs +++ b/DancingGoat/Controllers/ControllerBase.cs @@ -1,14 +1,26 @@ -using DancingGoat.Models; +using System; +using DancingGoat.Models; using KenticoCloud.Delivery; using System.Configuration; +using System.Globalization; +using System.Threading; using System.Web.Mvc; +using DancingGoat.Infrastructure; using DancingGoat.InlineContentItemResolver; namespace DancingGoat.Controllers { public class ControllerBase : AsyncController { - protected static readonly DeliveryClient client = CreateDeliveryClient(); + protected static readonly DeliveryClient baseClient = CreateDeliveryClient(); + public readonly LanguageClient client; + + public ControllerBase() + { + var currentCulture = CultureInfo.CurrentUICulture.Name; + client = new LanguageClient(baseClient, currentCulture); + } + public static DeliveryClient CreateDeliveryClient() { @@ -24,8 +36,8 @@ public static DeliveryClient CreateDeliveryClient() clientInstance.ContentLinkUrlResolver = new CustomContentLinkUrlResolver(); clientInstance.InlineContentItemsProcessor.RegisterTypeResolver(new HostedVideoResolver()); clientInstance.InlineContentItemsProcessor.RegisterTypeResolver(new TweetResolver()); - return clientInstance; } } -} \ No newline at end of file +} + diff --git a/DancingGoat/Controllers/HomeController.cs b/DancingGoat/Controllers/HomeController.cs index 377df32..0453059 100644 --- a/DancingGoat/Controllers/HomeController.cs +++ b/DancingGoat/Controllers/HomeController.cs @@ -23,7 +23,6 @@ public HomeController() } } - [Route] public async Task Index() { var response = await client.GetItemAsync("home"); diff --git a/DancingGoat/Controllers/PartnershipController.cs b/DancingGoat/Controllers/PartnershipController.cs index df21e5c..3fc63af 100644 --- a/DancingGoat/Controllers/PartnershipController.cs +++ b/DancingGoat/Controllers/PartnershipController.cs @@ -2,10 +2,8 @@ namespace DancingGoat.Controllers { - [RoutePrefix("partnership")] public class PartnershipController : AsyncController { - [Route] public ActionResult Index() { ViewBag.PartnershipRequested = TempData["formApplied"] ?? false; @@ -15,7 +13,6 @@ public ActionResult Index() /// /// Dummy action; form information is being handed over to Kentico Cloud Engagement management service through JavaScript. /// - [Route] [HttpPost] public ActionResult Application() { diff --git a/DancingGoat/Controllers/ProductController.cs b/DancingGoat/Controllers/ProductController.cs index 31ca75f..a94326e 100644 --- a/DancingGoat/Controllers/ProductController.cs +++ b/DancingGoat/Controllers/ProductController.cs @@ -7,10 +7,8 @@ namespace DancingGoat.Controllers { - [RoutePrefix("products")] public class ProductController : ControllerBase { - [Route("{urlSlug}")] public async Task Detail(string urlSlug) { var item = (await client.GetItemsAsync(new EqualsFilter("elements.url_pattern", urlSlug), new InFilter("system.type", "brewer", "coffee"))).Items.FirstOrDefault(); diff --git a/DancingGoat/DancingGoat.csproj b/DancingGoat/DancingGoat.csproj index df08fca..f78a679 100644 --- a/DancingGoat/DancingGoat.csproj +++ b/DancingGoat/DancingGoat.csproj @@ -184,6 +184,11 @@ True DancingGoat.resx + + DancingGoat.es-ES.resx + True + True + @@ -204,6 +209,8 @@ + + @@ -359,6 +366,12 @@ Resources Designer + + PublicResXFileCodeGenerator + DancingGoat.es-ES.Designer.cs + Resources + Designer + 10.0 @@ -395,10 +408,10 @@ - \ No newline at end of file diff --git a/DancingGoat/Infrastructure/LanguageClient.cs b/DancingGoat/Infrastructure/LanguageClient.cs new file mode 100644 index 0000000..41ce053 --- /dev/null +++ b/DancingGoat/Infrastructure/LanguageClient.cs @@ -0,0 +1,115 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using KenticoCloud.Delivery; +using KenticoCloud.Delivery.InlineContentItems; +using Newtonsoft.Json.Linq; + +namespace DancingGoat.Infrastructure +{ + public class LanguageClient : IDeliveryClient { + + private readonly DeliveryClient _client; + private readonly string _language; + + public LanguageClient(DeliveryClient client, string language) + { + _client = client; + _language = language; + } + + public Task> GetItemAsync(string codename, params IQueryParameter[] parameters) + { + return _client.GetItemAsync(codename, new[] {new LanguageParameter(_language)}.Concat(parameters)); + } + + public Task GetItemAsync(string codename, IEnumerable parameters) + { + return _client.GetItemAsync(codename, new[] { new LanguageParameter(_language) }.Concat(parameters)); + } + + public Task> GetItemAsync(string codename, IEnumerable parameters = null) + { + return parameters != null ? _client.GetItemAsync(codename, new[] { new LanguageParameter(_language) }.Concat(parameters)) : + _client.GetItemAsync(codename, new LanguageParameter(_language)); + } + + public Task GetItemsAsync(params IQueryParameter[] parameters) + { + return _client.GetItemsAsync(new[] { new LanguageParameter(_language) }.Concat(parameters)); + } + + public Task GetItemsAsync(IEnumerable parameters) + { + return _client.GetItemsAsync(new[] { new LanguageParameter(_language) }.Concat(parameters)); + } + + public Task> GetItemsAsync(params IQueryParameter[] parameters) + { + return _client.GetItemsAsync(new[] { new LanguageParameter(_language) }.Concat(parameters)); + } + + public Task> GetItemsAsync(IEnumerable parameters) + { + return _client.GetItemsAsync(new[] { new LanguageParameter(_language) }.Concat(parameters)); + } + + public Task GetTypeJsonAsync(string codename) + { + return _client.GetTypeJsonAsync(codename); + } + + public Task GetTypesJsonAsync(params string[] parameters) + { + return _client.GetTypesJsonAsync(new [] {new LanguageParameter(_language).GetQueryStringParameter()}.Concat(parameters).ToArray()); + } + + public Task GetTypeAsync(string codename) + { + throw new System.NotImplementedException(); + } + + public Task GetTypesAsync(params IQueryParameter[] parameters) + { + return _client.GetTypesAsync(new[] { new LanguageParameter(_language) }.Concat(parameters)); + } + + public Task GetTypesAsync(IEnumerable parameters) + { + return _client.GetTypesAsync(new[] { new LanguageParameter(_language) }.Concat(parameters)); + } + + public Task GetContentElementAsync(string contentTypeCodename, string contentElementCodename) + { + + return _client.GetContentElementAsync(contentTypeCodename, contentElementCodename); + } + + public IContentLinkUrlResolver ContentLinkUrlResolver + { + get { return _client.ContentLinkUrlResolver; } + set { _client.ContentLinkUrlResolver = value; } + } + + public ICodeFirstModelProvider CodeFirstModelProvider + { + get { return _client.CodeFirstModelProvider; } + set { _client.CodeFirstModelProvider = value; } + } + public InlineContentItemsProcessor InlineContentItemsProcessor => _client.InlineContentItemsProcessor; + public Task GetItemJsonAsync(string codename, params string[] parameters) + { + return _client.GetItemJsonAsync(codename, new[] {new LanguageParameter(_language).GetQueryStringParameter()}.Concat(parameters).ToArray()); + } + + public Task GetItemsJsonAsync(params string[] parameters) + { + return _client.GetItemsJsonAsync(new[] { new LanguageParameter(_language).GetQueryStringParameter() }.Concat(parameters).ToArray()); + } + + public Task GetItemAsync(string codename, params IQueryParameter[] parameters) + { + return _client.GetItemAsync(codename, new[] { new LanguageParameter(_language)}.Concat(parameters)); + } + } +} \ No newline at end of file diff --git a/DancingGoat/Infrastructure/LocalizedMvcRouteHandler.cs b/DancingGoat/Infrastructure/LocalizedMvcRouteHandler.cs new file mode 100644 index 0000000..899355d --- /dev/null +++ b/DancingGoat/Infrastructure/LocalizedMvcRouteHandler.cs @@ -0,0 +1,43 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Threading; +using System.Web; +using System.Web.Mvc; +using System.Web.Routing; + +namespace DancingGoat.Infrastructure +{ + public class LocalizedMvcRouteHandler : MvcRouteHandler + { + private readonly string _defaultLanguage; + + public LocalizedMvcRouteHandler(string defaultLanguage) + { + _defaultLanguage = defaultLanguage; //TODO: decide if this is even necessary + } + protected override IHttpHandler GetHttpHandler(RequestContext requestContext) + { + // Get the requested culture from the route + var cultureName = requestContext.RouteData.Values["language"]?.ToString() ?? "en-US"; + + CultureInfo culture; + try + { + //TODO: refactor this slightly + culture = new CultureInfo(cultureName); + } + catch + { + culture = new CultureInfo("en-US"); + } + + // Set the culture + Thread.CurrentThread.CurrentUICulture = culture; + Thread.CurrentThread.CurrentCulture = culture; + + return base.GetHttpHandler(requestContext); + } + } +} \ No newline at end of file diff --git a/DancingGoat/Views/Articles/Show.cshtml b/DancingGoat/Views/Articles/Show.cshtml index ff96c52..33eca7b 100644 --- a/DancingGoat/Views/Articles/Show.cshtml +++ b/DancingGoat/Views/Articles/Show.cshtml @@ -2,7 +2,7 @@ @model DancingGoat.Models.Article @{ - ViewBag.Title = @Model.System.Name; + ViewBag.Title = @Model.Title; }

@Html.DisplayFor(vm => vm.Title)

diff --git a/DancingGoat/Views/Home/Index.cshtml b/DancingGoat/Views/Home/Index.cshtml index e022c2f..a93a753 100644 --- a/DancingGoat/Views/Home/Index.cshtml +++ b/DancingGoat/Views/Home/Index.cshtml @@ -46,7 +46,7 @@

- @article.System.Name + @article.Title

@Html.DisplayFor(vm => article.Summary) diff --git a/DancingGoat/Views/Partnership/Index.cshtml b/DancingGoat/Views/Partnership/Index.cshtml index 7c41e11..b1256f6 100644 --- a/DancingGoat/Views/Partnership/Index.cshtml +++ b/DancingGoat/Views/Partnership/Index.cshtml @@ -4,7 +4,7 @@ ViewBag.Title = Resources.DancingGoat.Partnership; } - +

diff --git a/DancingGoat/Views/Shared/DisplayTemplates/Article.cshtml b/DancingGoat/Views/Shared/DisplayTemplates/Article.cshtml index 44130bb..1411034 100644 --- a/DancingGoat/Views/Shared/DisplayTemplates/Article.cshtml +++ b/DancingGoat/Views/Shared/DisplayTemplates/Article.cshtml @@ -4,14 +4,14 @@
- @Html.AssetImage(Model.TeaserImage.FirstOrDefault(), title: $"Article {Model.System.Name}", cssClass: "article-tile-image") + @Html.AssetImage(Model.TeaserImage.FirstOrDefault(), title: $"Article {Model.Title}", cssClass: "article-tile-image")
@Html.DateTimeFormattedFor(vm => vm.PostDate, "M")

- @Model.System.Name + @Model.Title

@Html.DisplayFor(vm => vm.Summary) diff --git a/DancingGoat/Views/Shared/DisplayTemplates/Product.cshtml b/DancingGoat/Views/Shared/DisplayTemplates/Product.cshtml index 695d537..bd62357 100644 --- a/DancingGoat/Views/Shared/DisplayTemplates/Product.cshtml +++ b/DancingGoat/Views/Shared/DisplayTemplates/Product.cshtml @@ -6,7 +6,7 @@

-

@Model.ProductSystem.Name

+

@Model.ProductProductName

@if (Model.ProductProductStatus.Any()) { diff --git a/DancingGoat/Views/Shared/DisplayTemplates/RelatedArticle.cshtml b/DancingGoat/Views/Shared/DisplayTemplates/RelatedArticle.cshtml index 352126c..47d5bd7 100644 --- a/DancingGoat/Views/Shared/DisplayTemplates/RelatedArticle.cshtml +++ b/DancingGoat/Views/Shared/DisplayTemplates/RelatedArticle.cshtml @@ -2,15 +2,15 @@
- - @Html.AssetImage(Model.TeaserImage.FirstOrDefault(), title: "Article" + Model.System.Name, cssClass: "article-tile-image") + + @Html.AssetImage(Model.TeaserImage.FirstOrDefault(), title: "Article " + Model.Title, cssClass: "article-tile-image")
@Html.DateTimeFormattedFor(vm => vm.PostDate, "M")

- @Html.DisplayFor(vm => vm.System.Name) + @Html.DisplayFor(vm => vm.Title)

@Html.DisplayFor(vm => vm.Summary) diff --git a/DancingGoat/Views/Shared/_Layout.cshtml b/DancingGoat/Views/Shared/_Layout.cshtml index 6139d16..68068b2 100644 --- a/DancingGoat/Views/Shared/_Layout.cshtml +++ b/DancingGoat/Views/Shared/_Layout.cshtml @@ -38,6 +38,10 @@ + + @Html.ActionLink("EN", ViewContext.RouteData.Values["action"].ToString(), new { language = "en-us" }) + @Html.ActionLink("ES", ViewContext.RouteData.Values["action"].ToString(), new { language = "es-es" }) +

@@ -67,17 +71,17 @@
diff --git a/DancingGoat/Views/Shared/_ProductLayout.cshtml b/DancingGoat/Views/Shared/_ProductLayout.cshtml index 4e53198..5ba05a9 100644 --- a/DancingGoat/Views/Shared/_ProductLayout.cshtml +++ b/DancingGoat/Views/Shared/_ProductLayout.cshtml @@ -1,13 +1,13 @@ @model DancingGoat.Models.Product @{ Layout = "~/Views/Shared/_Layout.cshtml"; - ViewBag.Title = Model.ProductSystem.Name; + ViewBag.Title = Model.ProductProductName; }
-

@Html.DisplayFor(vm => vm.ProductSystem.Name)

+

@Html.DisplayFor(vm => vm.ProductProductName)