ID-Less URL Structure Demystified – How Does to Resolve ID-Less URLs?

I believe many of you nopCommerce pro users and developers are aware that nopCommerce 2.70 and 2.80 have employed a cleaner URL compared to the previous versions. From URLs that are suffixed with ‘.aspx’ in versions 1.XX; to extentionless but rather verbous URLs in versions 2.65 and below, we have seen a lot of changes in the URL structure in nopCommerce. However, none of them are as mysterious as the URLs in 2.70 and 2.80. Why? Because nopCommerce seems to know the magic to convert from any arbitrary texts to integer IDs.

For example, the link for my NopLite – nopCommerce Responsive Theme is You don’t see ANY integer in the URL, but nopCommerce somehow knows how to map from the URL to the appropriate ID. On the other hand, the nopCommerce 2.65 URL for my NopLite theme would have been: Note the ‘7’ somewhere in between the URL, that’s the Integer Product ID.

So the question is, how does nopCommerce 2.70 and 2.80 know the ID without looking the ID?

The UrlRecord Database Table

Well, the information is actually stored in a database table called UrlRecord. The table stores the slugs of entities to be mapped. A slug is any URL friendly-text and must be unique per nopCommerce installation. And then there is the EntityId column, which actually maps back to the actual entity represented by the slug. Last but not least, the EntityName column tells nopCommerce the actual entity type (Category, Product, BlogPost and etc) that an EntityId represents.

The nopCommerce database table UrlRecord stores the information of URL Slugs

This table, although useful, is only one part of the equation. We have stored the information, then there must be a way to connect the dots to somehow retrieve the information from the database, and map it with the URLs. The next part of the “magic” lies in the code.

Connecting the Dots – GenericUrlRouteProvider, GenericPathRoute and GenericPathRouteExtensions

First of all, let’s open Nop.Web.Framework.Seo.GenericPathRoute.cs, and you’ll see something like below:

Code snippet from GenericPathRoute.cs showing how it retrives UrlRecord from the database

Basically what the GenericPathRoute class does is to retrieve the RouteData information from the HttpRequest, extract the slug, and compare it with the database record (remember our UrlRecord database table?). If it eventually finds any active exsting record, it then provides additional values to the RouteData (see figure below) such as the Controller, the Action and the ID. In short, GenericPathRoute.cs encapsulates the logic that glue together the three pieces: UrlRecord database table, the actual Controller & Action that is responsible for producing the HTML result, and any other parameters required for the Action to perform correctly.

Code snippet showing how GenericPathRoute.cs class adds the required RouteData

But we are still missing one thing – we need to actually tell MVC to map the ID-less URLs to our freshly baked GenericPathRoute class. In other words, we have to let MVC routing engine knows that: when there is any ID-less URL coming in, we’ll let GenericPathRoute to do the heavy lifting of determining which Controller and Action to call and with what parameters. The figure below shows the GenericUrlRouteProvider class (found inNop.Web.Infrastructure.GenericUrlRouteProvider.cs) doing exactly this job. See the lines around the MapGenericPathRoute() method. The MapGenericPathRoute() method can be found inNop.Web.Framework.Seo.GenericPathRouteExtensions.cs.

GenericUrlRouteProvider doing the mapping between ID-less URLs and GenericPathRoute class

Conclusion – There is Actually No Magic in nopCommerce ID-less URLs

Yeap, the whole architecture in nopCommerce ID-less URLs is pretty clever, but there is really no magic in it. To recap, here are what make up of the ID-less URLs architecture:

  • UrlRecord database table – to store the mapping between a slug and the actual entity
  • GenericPathRoute class – to map a slug with the actual entity with the help of UrlRecord, thereby providing the RouteData to MVC’s routing engine
  • GenericUrlRouteProvider class – to tell MVC’s routing engine to let GenericPathRoute class handle ID-less URLs

Hope this explains the issue! Have any other topics that you want explained? Let me know in the comments, or better yet, use the UserVoice feedback widget at the right side to tell me your ideas! 🙂


Reference :

Material design with Polymer


Table of contents


Material design is a unified system of visual, motion, and interaction design that adapts across different devices. Material design is inspired by tactile materials, such as paper and ink. Material surfaces interact in a shared space. Surfaces can have elevation (z-height) and cast shadows on other surfaces to convey relationships.

Polymer’s paper elements collection implements material design for the web. The Polymer core elements collection provides a number of unthemed elements that you can use to achieve material design app layouts, transitions, and scrolling effects.

For more detail on the material design philosophy and guidelines, see the Material design specification.

For a sample of the material design patterns in use, see the Topeka sample app.

For quick visual demos of many of the paper elements, see the Paper elements sampler.

The Polymer core elements set includes several elements for application layout, including creating toolbars, app bars, tabs, and side nav consistent with the material design guidelines.

See Layout elements for information on using these elements.

To work well with the Polymer layout elements, you should make sure other parts of your app follow the same metrics described in the material design spec, such as:

  • Baseline grids
  • Keylines
  • Touch target size

Material design uses icons extensively. Polymer provides access to a large variety of scalable, tintable SVG icons using the <core-icon> element and its associated icon sets. Using <core-icon> can be as simple as:

<link rel="import" href="/components/core-icons/core-icons.html">
<core-icon icon="info"></core-icon>

core-icons.html is a utility import that includes the <core-icon> element and the default icon set, which includes over 150 common icons. Here are a few examples:

For details on using <core-icon> and its relatives, see Using core icons.

The paper elements collection includes a number of material-themed controls for all common areas of your application. The following table shows the common controls.

More examples
Toggle button
Icon button
More examples
Floating action button
Radio buttons
Progress bar
More examples

Dialogs, snackbars and toasts all appear as a separate sheet, overlaying the background. The paper element collection includes two elements.

  • A dialog (<paper-dialog>) is a modal window that can include a title, text, action buttons, and other controls.
  • A snackbar or toast (<paper-toast>) is a small, transient popup that includes a message and optionally a single action (such as “undo”).

Use the <paper-dialog> element to create a dialog. Set a title on a dialog using the heading published property.

You can use any kind of children inside the dialog. For action buttons, add the dismissive or affirmativeattributes to place the controls (typically buttons) at the bottom of the dialog:

  • dismissive actions, like Cancel, close the dialog and return to the previous screen without making changes. They’re displayed on the left.
  • affirmative actions, like OK or Save continue a process or confirm a decision. They’re displayed on the right.

The following example creates a dialog with two buttons:

<paper-dialog id="dialog" heading="Launch?"
  <p>This app would like to launch a small, unmanned vehicle
     into space.</p>
  <paper-button label="Cancel" dismissive></paper-button>
  <paper-button label="OK" affirmative default></paper-button>

In this example, the default button has a default attribute. The dialog doesn’t apply any special treatment for a default option; you can style it differently using CSS.

Dialogs are hidden by default. Call the dialog’s toggle method to show or hide it.

More examples

A <paper-toast> element appears at the bottom of the screen or on the lower-left on mobile. Use the textattribute to specify the text to display.

<paper-toast id="toast" text="Your draft has been discarded."></paper-toast>

Like a dialog, a <paper-toast> is hidden by default. Call the element’s open method to display it. The toast disappears after a timeout, or can be dismissed by swiping.

More examples

When designing your own components or using generic HTML elements such as <div>s, you can add material design effects using the <paper-ripple> and <paper-shadow> elements.

Material responds to input events with an touch ripple effect: an animation that moves out radially from the origin of the event. These effects are built into the paper elements collection:

When working with other elements, you can use the <paper-ripple> element to create a touch ripple effect.

To use <paper-ripple>, declare a <paper-ripple> element as a child of the element you want to add the effect to:

<div style="position: relative;">
  <paper-ripple fit></paper-ripple>

Touch the cards and icon below to see ripple effects.

Default ripple

Colored ripple

Circular ripple

The <paper-ripple> should be position: absolute and sized to fit the parent element. In this example, the fit layout attribute is used to position the ripple appropriately. (See layout attributes for information on fit and other layout attributes.)

You can clip the ripple to a circle by adding the circle class to the ripple’s classlist. Circular ripples are used for small buttons used in a grid layout (for example, icon buttons, number pads).

You can set the color of the ripple using the color CSS property.

paper-ripple {
  color: red;

When using a paper element, check the element API doc to find the CSS selector to style the ripple. Most elements that have a ripple have a <paper-ripple> in the shadow DOM with an ID of ink or ripple. For example, to style a button:

paper-button::shadow #ripple {
  color: blue;

To style a checkbox:

paper-checkbox::shadow #ink {
  color: blue;

Material has an apparent elevation (z-height) and casts shadows. In Polymer, elements can have a z-height between 0 and 5. Material can raise or lower in response to user input.

The paper-elements have shadow effects built-in. For example, a <paper-button> declared with theraisedButton attribute appears raised above thesurface it rests on, and raises up when touched.

When building your own elements or using standard DOM elements, you can use the <paper-shadow>element to create the appropriate shadow effect.

To apply a shadow to an element, simply add a <paper-shadow> element as a child element of a relatively positioned element. The <paper-shadow> element automatically adds the shadow to its parent element:

 <div style="width: 100px; height: 100px;" relative>
   <paper-shadow z="3"></paper-shadow>

You can change the z-height of the target element by setting z on the <paper-shadow> element. Z values range from 0 (no shadow) to 5.

z = 1

z = 3

z = 5

The apparent height of the element (the z-height value) is absolute — that is, an element with a z-height of 3 casts the same size shadow regardless of the z-heights of the background elements. In addition, the z-height does not affect the stacking order of elements. To change stacking order of sibling elements, use the z-indexCSS property as usual.

You can apply a shadow to a different element (other than the parent element) by setting the<paper-shadow> element’s target property. However, the target must still be an element that accepts children. (For example, you can’t add a shadow directly to an <img> element.)

Note: The <paper-shadow> element sets its target to overflow: visible so the shadows are visible outside of the element’s borders. If you need to clip inner content, use another container inside the shadowed container.

More examples

Support for transitions is rapidly evolving. The <core-animated-pages> element displays a single child element at a time, and provides support for sophisticated transitions between two children, or pages.

You can define a set of transitions to be executed when transitioning between pages. To provide visual continuity across transitions, animated pages support hero transitions, where a selected element on the starting page appears to morph into a related element on the ending page. Use hero transitions to link important elements together, while using a simpler transition such as a cross-fade for the remaining elements.

For example transitions, see the <core-animated-pages> demos. The Topeka sample app also demonstrates a number of transitions in context.

The <core-scroll-header-panel> element supports a number of scrolling effects described in the material design spec, including condensing and expanding the toolbar as the user scrolls and hiding or showing the toolbar.

For resizing toolbars, <core-scroll-header-panel> lets you define how to transition the toolbar’s contents between states — resizing text, showing or hiding /components, and cross-fading between backgrounds, for example.

See the <core-scroll-header-panel> demos for some examples of the effects possible.



Polymer paper elements (material design)

paper-button is a button containing text or an image. When the user touches the button, a ripple effect emanates from the point of contact.

A paper-button may be flat or raised. A raised button behaves like a piece of paper resting on another sheet, and lifts up upon press. Flat buttons do not raise up. Add the raisedButton attribute to make a raised button.


<paper-button label="flat button"></paper-button>
<paper-button label="raised button" raisedButton></paper-button>

A button should be styled with a background color, text color, ripple color and hover color.

To style the background, text and hover color, apply the background and color CSS properties to the button. To style the ripple color, apply the color CSS property to the #ripple element in the button’s shadow root:

/* Style #my-button blue with white text and darker blue ink. */
#my-button {
    background: #4285f4;
    color: #fff;

#my-button:hover {
    background: #2a56c6;

#my-button::shadow #ripple {
    color: #2a56c6;



stringdefault: ''

The label of the button.


booleandefault: false

If true, the button will be styled as a “raised” button.


stringdefault: ''

(optional) The URL of an image for an icon to use in the button. Should not useicon property if you are using this property.


stringdefault: ''

(optional) Specifies the icon name or index in the set of icons available in the icon set. If using this property, load the icon set separately where the icon is used. Should not use src if you are using this property.



Learning Polymer


Table of contents


If you want to learn Polymer, the easiest way to get started is to download the starter project:

The starter project includes Polymer, a set of elements, and a starter app. Work through the tutorial for an introduction to Polymer APIs and concepts, or work through the finished app on your own.

If you’re ready to start your own project, you can pick and choose the components you want to install, or install a whole set of components, like the Paper element collection.

Polymer is very modular; you can install just the Polymer library and platform polyfills, a single element, or a whole collection of elements.

Throughout the site, you’ll find component download buttons like this:

The component download button offers three ways to install a component or set of components:

  • Bower. Recommended. Bower manages dependencies, so installing a component also installs any missing dependencies. Bower also handles updating installed components. For more information, seeInstalling with Bower.
  • ZIP file. Includes all dependencies, so you can unzip it and start using it immediately. The ZIP file requires no extra tools, but doesn’t provide a built-in method for updating dependencies. For more information, seeInstalling from ZIP files.
  • Github. When you clone a component from Github, you need to manage all of the dependencies yourself. If you’d like to hack on the project or submit a pull request, see setting up Polymer with git.

Pick your method and follow the instructions in the download dialog.

The recommended way to install Polymer 0.4.0 is through Bower. To install Bower, see the Bower web site.

Bower removes the hassle of dependency management when developing or consuming elements. When you install a component, Bower makes sure any dependencies are installed as well.

If you haven’t created a bower.json file for your application, run this command from the root of your project:

bower init

This generates a basic bower.json file. Some of the questions, like “What kind of modules do you expose,” can be ignored by pressing Enter.

The next step is to install one or more Polymer packages:

bower install --save Polymer/polymer

Bower adds a bower_components/ folder in the root of your project and fills it with Polymer and its dependencies.

Tip: --save adds the item as a dependency in your app’s bower.json: { "name": "my-project", "version": "0.0.0", "dependencies": { "polymer": "Polymer/polymer#~0.4.0" } }

Using the component download button, click the Bower tab and cut and paste the Bower install command.

You can also choose one of the commonly-used packages:

  • Polymer/polymer. Just the Polymer library and platform polyfills.
  • Polymer/core-elements. The Polymer Core elements collection.
  • Polymer/paper-elements. The Paper elements collection.

For example, if you’d like to install Polymer’s collections of pre-built elements, run the following commands from the terminal:

bower install --save Polymer/core-elements
bower install --save Polymer/paper-elements

When a new version of Polymer is available, run bower update in your app directory to update your copy:

bower update

This updates all packages in bower_components/.

When you download a component or component set as a ZIP file, you get all of the dependencies bundled into a single archive. It’s a great way to get started because you don’t need to install any additional tools.

Expand the ZIP file in your project directory to create a components folder.

If you download multiple component sets as ZIP files, you’ll usually end up with multiple copies of some dependencies. You’ll need to merge the contents of the ZIP files.

Unlike Bower, the ZIP file doesn’t provide a built-in method for updating dependencies. You can manually update components with a new ZIP file.

Because there are a number of dependencies we suggest you install Polymer with Bower instead of git. If you’d like to hack on the project or submit a pull request check out our guide on setting up Polymer with git.

Now that you’ve installed Polymer it’s time to learn the core concepts. In the next section we’ll get you up and running on using elements in a project. Continue on to:

If you’d rather skip ahead, check out our guide on Creating Elements.


CKAN, the world’s leading open-source data portal platform

CKAN is the world’s leading open-source data portal platform.

CKAN is a complete out-of-the-box software solution that makes data accessible and usable – by providing tools to streamline publishing, sharing, finding and using data (including storage of data and provision of robust data APIs). CKAN is aimed at data publishers (national and regional governments, companies and organizations) wanting to make their data open and available.

CKAN is used by governments and user groups worldwide and powers a variety of official and community data portals including portals for local, national and international government, such as the UK’s and the European Union’s, the, Dutch and Netherland government portals, as well as city and municipal sites in the US, UK, Argentina, Finland and elsewhere.

CKAN Tour:
Features overview:


Publish and Manage Data

An intuitive web interface allows dataset publishers and curators to easily register, update and refine datasets in a distributed authorisation model called ‘Organizations’. ‘Organizations’ allow each publisher to have their own dataset entry and approval process with numerous members. This means responsibility can be distributed and authorization access managed by each department or agencies’ admins instead of centrally.

Screenshot: Organizations

Entering data

You can add and edit data in CKAN in many ways, including:

  • Directly via the web interface
  • Using CKAN’s rich JSON API
  • Via custom spreadsheet importers



Many organisations already have their data in repositories with well-defined process and procedures for publishing and managing data. In this case the data can be simply pulled regularly into CKAN from the existing repositories. To facilitate this model we’ve developed a sophisticated and customisable “harvesting” mechanism which can fetch and import records from many different repository sources, including:

  • Geospatial CSW Servers (see geospatial for more information)
  • Existing web catalogues
  • Simple HTML index pages or Web Accessible Folders
  • ArcGIS, Geoportal Servers and Z39.50 databases
  • Other CKAN instances

This functionality is used on to get data in from hundreds of their agencies, on to implement a Discovery Metadata Service used to fulfill the UK’s obligations under the EU INSPIRE directive. It is also used on to pull in information from other catalogues to make them all searchable in one place. – See more at:

Publisher tools

  • Publisher (Organization) admin dashboard: manage members, datasets, approve datasets to be public, manage harvest sources all from each organization admin page.
  • Forms: Create portal or publisher specific forms that pre-fill certain fields or have additional required fields to fit individual requirements.


Datasets can be public or private. If they are private they are only visible to the logged in members of their owning publishing Organization (e.g. Department of National Statistics). Admins can approve datasets for publication with our bulk editing tool which lets you search, facets and pick datasets to become public or private.