Skip to main content

Menus for Item-Actions in HTML and JS

Warning ⚠️: New Docs Available

These are old docs and we haven't found the time to completely move them. You will find comprehensive new docs on

Introduced in Version 06.00.00
Demos of this feature

Often you can use the simple Menus generated automatically, like this:

  • [Content:Toolbar] - this is the Token syntax
  • @Edit.Toolbar(Content) - this is the new, mighty Razor syntax
    The new syntax also allows you to specify which buttons or what content-type the toolbar should be for. Read more about it in the 2sxc Wiki.
  • @Content.Toolbar - this is the old, simpler Razor syntaxt

But often you will want more control over the buttons made available - maybe because you want the toolbar for something other than the default Content-object, or because you don't want to offer all actions. 2SexyContent provides two simple mechanisms for this. 

Some Background Information

In general, all action-links are generated by a small JavaScript controller which is added automatically to the page when the page is in edit-mode. In case you want to look at the script itself, you can find it here. In addition to the JS, there is a small script which looks at the HTML and automatically inserts the edit-buttons where it finds some predefined tags. 

When you're settings these links manually, there is one more detail you must know - context is very, very important. In other words, an edit-Link to an entity 7203 should only work from within a module, which actually is responsible for this entity. Without such a limitation, you could manipulate URLs to edit just about anything, even if you only have edit permissions on a single module on the whole website. Because of this, the edit-link needs many more details which would be very cumbersome to add. This is handled as follows

  1. When the page is in edit-mode, the DNN-Module-Wrapper will receive another attribute called data-2sxc. 
  2. This data-2sxc attribute contains all the default parameters needed in an action-link. For example, the module-ID, return-URL and more. 
  3. So by default, you only need to specify parameters which are unique to this specific button - like the data-type required on a new dialog or the EntityId on an edit link. 
  4. the 2SexyContent-Controller will then take your parameters, mix them with the defaults and create the correct buttons/links based on this


Adding Menus the most Basic Way

This is done as already noted above:

  1. Tokens: [Content:Toolbar] for the current content-item, and [List:Toolbar] for the header-item
  2. Razor: @Edit.Toolbar(Content) and @Edit.Toolbar(ListContent)


  • before 2sxc 8.4 the preferred way in Razor was Content.Toolbar, now it's Edit.Toolbar(Content) which offers more features
  • before 2SexyContent 6.0, you needed @Html.Raw(Content.Toolbar) for razor. This is not necessary any more
  • This token will actually just produce an HTML-snippet just like adding it manually using HTML. The main advantage here is that it's automatically added when in edit-mode, and not added when not in edit mode. 

Adding Action Menus using HTML

If the edit-JS finds HTML in a special pattern, it will automatically insert the correct menu. The syntax is as follows:

<ul class='sc-menu' data-toolbar='special instructions here'></ul>

 The special instructions can be either

  • A single (valid) JSON package containing the instructions, like  data-toolbar='{ "entityId": @app.EntityId, "action": "edit" }'
  • An array of such JSON packages - for multiple buttons with own configurations, like  data-toolbar='[{ "entityId": @app.EntityId, "action": "edit" }, { "attributeSetName": "Picture", "action": "new" }]'
  • note: to be valid, both the key (action) and the value must be enclosed in quotes if it's a string, so "action":"new" or "useModuleList":true

The instructions contain various details regarding which button you want and more. The exact details are explained a bit further down. 

An example using Razor to first check if logged in, then add the button


             @if (DotNetNuke.Common.Globals.IsEditMode())


                    <ul class='sc-menu' data-toolbar='[{ "entityId": @app.EntityId, "action": "edit" }]'></ul>



Adding Action-Menus using JavaScript

In some cases the automatic menu-generator doesn't suffice. This can be the case if you have special logic you want to run first, or if you are generating the menus inside a knockoutJS or AngularJS template, and the automatic conversion doesn't work as planned. Then you have the following commands at your disposal:

  1. getToolbar(settings) - returns a string containing the <ul><li> construct containing the normal toolbar. This will generate one or more buttons in one go, by calling up the next command for each button, namely...
  2. getButton (settings) - returns a string containing the <a href=""> construct for a specific button. The exact action isn't hardwired, it actually inserts a call to the correct action-method, namely...
  3. action (settings) - does something - like open a dialog or perform a postback for a server-side action. 
  4. if something needs a dialog, it calls openDialog(settings) , which will open the lightbox dialog
  5. if something needs a URL (for a dialog, or for the dialog without a lightbox) it uses getLink(settings)

All these commands expect settings. This is a small JSON-Package containing all parameters needed. It works a bit like the ajax-parameters in jQuery. The exact list of settings follows below. 

To use these commands, you need the javascript controller. Note that it's only available when the page is in edit mode. To access it,you must use 


For example

  • $2sxc(2043).manage.openDialog({...});
  • From a token template: $2sxc([Module:ModuleID]).manage.openDialog({...});
  • From a razor template: $2sxc(@Dnn.Module.ModuleID).manage.openDialog({...});

What can be defined in a Settings-JSON

The most general setting is usually action - which can be:

  1. action
    1. "action": "edit" - edit the current entity based on either the EntityId or the 
    2. "action": "new" - create a new-dialog - either the default type of this list or an allowed type for this module. note that new opens a dialog - which doesn't add anything when cancelled
    3. "action": "add" - add a new entity/presentation-pair to the list of this module. note that add extends the list (no edit dialog) - which is ideal for prototyping
    4. delete/publish actions are not documented but exist as well
  2. entityId (todo: document)
  3. prefill (in v7+) - a JSON to pre-fill values 
  4. metadata (new in 08.02.03) - a JSON containing metadata assignment info, relevant when a link should create a new entity, which will function as metadata for another piece of information. Check out the blueimp App in v.2 it currently has inner properties key, keyType and targetType, but in most cases you'll just need key while the remaining values are automatically set.

The new and add actions need to know what data-type is allowed. By default, it's the type configured in the template. So not specifying it will automatically add/edit this type. If you do want to specify it, you can add

  • "contentType" : "Person" (in v 7.2.3+, previously attributeSetName- or any other content-type name. It only works for content types allowed in this context

New and add also might need to know at what position in the list the item is added. This is only needed for manually sorted lists - very common in Token-scenarios. If this is a requirement, you will need

  • "sortOrder": 0 - or any other number. 

There is also an important distinction for all actions - it's if you're working on this entity or if you're working on an entity/presentation pair. Let's just explain this:

  1. When you're editing an entity/presentation-set, the dialog will always offer both the content and the presentation for editing in the same dialog. There are coupled together, because the user might want to change the description of a picture and also configure how it's presented in this specific template. This is the most common way of doing things before 2SexyContent 6.0 and the way it's done in Token-Templates. 
  2. When you're editing an entity by itself then the dialog will only show this entity. This usually only makes sense when there is no presentation-information tied to this entity. This is the most common scenario when using entities as data. Because when you say "show all news entities ordered by date" you will not have any assigned presentation-information, and there will be no slot #2 in a pre-sorted list where this is stored. 

For each of these scenarios, the information required for the button is a bit different:

  1. for entity/presentation-sets the settings must know the contentGroupId and the sortOrder. This is because these sets are bundled together in this content-group. Note that the contentGroupId can be inherited automatically from the module, so you usually don't have to specify it - if you specify "useModuleList": true. This is automatically placed in the tag for the standard edit-toolbars. 
  2. for entity-editing only the settings must just know the entityId. 


<ul class='sc-menu' data-toolbar='[{"action":"edit", "useModuleList":true, "sortOrder": 0, "prefill": { "DocumentedOnPage": "page:@Dnn.Tab.TabID", "title": "@Dnn.Tab.Title" } }]'></ul>