Skip to content

Commit

Permalink
DRAFT-3309 - first working version
Browse files Browse the repository at this point in the history
- able to switch culture via ugly button
- localized some of the hardcoded content into resx file
- able to fetch items based on culture from Delivery API
  • Loading branch information
martin-knapik committed Jul 10, 2017
1 parent 98bebf9 commit 95983d1
Show file tree
Hide file tree
Showing 24 changed files with 378 additions and 50 deletions.
Empty file.
126 changes: 126 additions & 0 deletions DancingGoat/App_Data/DancingGoat.es-ES.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AboutUs" xml:space="preserve">
<value>Sobre Nosotros</value>
</data>
<data name="Articles" xml:space="preserve">
<value>Artículo</value>
</data>
</root>
48 changes: 41 additions & 7 deletions DancingGoat/App_Start/RouteConfig.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System.Web.Mvc;
using System.Web.Routing;
using DancingGoat.Infrastructure;

namespace DancingGoat
{
Expand All @@ -9,19 +10,52 @@ public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

routes.MapMvcAttributeRoutes();

This comment has been minimized.

Copy link
@hejtmii

hejtmii Jul 10, 2017

Contributor

Discuss attribute routing vs. convention routing with Deliver, but first check if route handler can be used with attribute routing

This comment has been minimized.

Copy link
@martin-knapik

martin-knapik Jul 11, 2017

Author Contributor

it's possible using middleware instead of http handler, however due to time limitations I'm unable to implement it.

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 },

This comment has been minimized.

Copy link
@hejtmii

hejtmii Jul 10, 2017

Contributor

"en-us" should be as one constant (e.g. DEFAULT_LANGUAGE) used in the whole code

This comment has been minimized.

Copy link
@martin-knapik

martin-knapik Jul 11, 2017

Author Contributor

done

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" }
);

}
}
}
2 changes: 0 additions & 2 deletions DancingGoat/Controllers/AboutController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@

namespace DancingGoat.Controllers
{
[RoutePrefix("about")]
public class AboutController : ControllerBase
{
[Route]
public async Task<ActionResult> Index()
{
var response = await client.GetItemAsync<AboutUs>("about_us");
Expand Down
5 changes: 1 addition & 4 deletions DancingGoat/Controllers/ArticlesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,19 @@

namespace DancingGoat.Controllers
{
[RoutePrefix("articles")]
public class ArticlesController : ControllerBase
{
[Route]
public async Task<ActionResult> Index()
{
var response = await client.GetItemsAsync<Article>(
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<ActionResult> Show(string urlSlug)
{
var response = await client.GetItemsAsync<Article>(new EqualsFilter("elements.url_pattern", urlSlug), new EqualsFilter("system.type", "article"));
Expand Down
2 changes: 0 additions & 2 deletions DancingGoat/Controllers/BrewersController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@

namespace DancingGoat.Controllers
{
[RoutePrefix("product-catalog/brewers")]
public class BrewersController : ControllerBase
{
[Route]
public async Task<ActionResult> Index()
{
var response = await client.GetItemsAsync<Brewer>(
Expand Down
2 changes: 0 additions & 2 deletions DancingGoat/Controllers/CafesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@

namespace DancingGoat.Controllers
{
[RoutePrefix("cafes")]
public class CafesController : ControllerBase
{
[Route]
public async Task<ActionResult> Index()
{
var response = await client.GetItemsAsync<Cafe>(
Expand Down
2 changes: 0 additions & 2 deletions DancingGoat/Controllers/CoffeesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@

namespace DancingGoat.Controllers
{
[RoutePrefix("product-catalog/coffees")]
public class CoffeesController : ControllerBase
{
[Route]
public async Task<ActionResult> Index()
{
var response = await client.GetItemsAsync<Coffee>(
Expand Down
2 changes: 0 additions & 2 deletions DancingGoat/Controllers/ContactsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,8 @@

namespace DancingGoat.Controllers
{
[RoutePrefix("contacts")]
public class ContactsController : ControllerBase
{
[Route]
public async Task<ActionResult> Index()
{
var response = await client.GetItemsAsync<Cafe>(
Expand Down
20 changes: 16 additions & 4 deletions DancingGoat/Controllers/ControllerBase.cs
Original file line number Diff line number Diff line change
@@ -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()
{
Expand All @@ -24,8 +36,8 @@ public static DeliveryClient CreateDeliveryClient()
clientInstance.ContentLinkUrlResolver = new CustomContentLinkUrlResolver();
clientInstance.InlineContentItemsProcessor.RegisterTypeResolver(new HostedVideoResolver());
clientInstance.InlineContentItemsProcessor.RegisterTypeResolver(new TweetResolver());

return clientInstance;
}
}
}
}

1 change: 0 additions & 1 deletion DancingGoat/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ public HomeController()
}
}

[Route]
public async Task<ActionResult> Index()
{
var response = await client.GetItemAsync<Home>("home");
Expand Down
3 changes: 0 additions & 3 deletions DancingGoat/Controllers/PartnershipController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@

namespace DancingGoat.Controllers
{
[RoutePrefix("partnership")]
public class PartnershipController : AsyncController
{
[Route]
public ActionResult Index()
{
ViewBag.PartnershipRequested = TempData["formApplied"] ?? false;
Expand All @@ -15,7 +13,6 @@ public ActionResult Index()
/// <summary>
/// Dummy action; form information is being handed over to Kentico Cloud Engagement management service through JavaScript.
/// </summary>
[Route]
[HttpPost]
public ActionResult Application()
{
Expand Down
2 changes: 0 additions & 2 deletions DancingGoat/Controllers/ProductController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@

namespace DancingGoat.Controllers
{
[RoutePrefix("products")]
public class ProductController : ControllerBase
{
[Route("{urlSlug}")]
public async Task<ActionResult> Detail(string urlSlug)
{
var item = (await client.GetItemsAsync<object>(new EqualsFilter("elements.url_pattern", urlSlug), new InFilter("system.type", "brewer", "coffee"))).Items.FirstOrDefault();
Expand Down
Loading

0 comments on commit 95983d1

Please sign in to comment.