Umbraco CMS
CloudHeartcoreDXPMarketplace
13.latest (LTS)
13.latest (LTS)
  • Umbraco CMS Documentation
  • Legacy Documentation
    • Umbraco 11 Documentation
    • Umbraco 8 Documentation
    • Umbraco 7 Documentation
  • Release Notes
  • Contribute
  • Sustainability Best Practices
  • Fundamentals
    • Get to know Umbraco
    • Setup
      • Requirements
      • Installation
        • Install using .NET CLI
        • Install using Visual Studio
        • Local IIS With Umbraco
        • Install using Visual Studio Code
        • Installing Nightly Builds
        • Running Umbraco on Linux/macOS
        • Unattended Installs
      • Upgrade your project
        • Version Specific Upgrades
          • Upgrade from Umbraco 8 to the latest version
          • Migrate content to Umbraco 8
          • Minor upgrades for Umbraco 8
          • Upgrade to Umbraco 7
          • Minor upgrades for Umbraco 7
      • Server setup
        • Running Umbraco On Azure Web Apps
        • Hosting Umbraco in IIS
        • File And Folder Permissions
        • Runtime Modes
        • Umbraco in Load Balanced Environments
          • Load Balancing Azure Web Apps
          • Standalone File System
          • Advanced Techniques With Flexible Load Balancing
          • Logging With Load Balancing
    • Backoffice
      • Sections
      • Property Editors
        • Built-in Property Editors
          • Checkbox List
          • Color Picker
          • Content Picker
          • DateTime
          • Date
          • Decimal
          • Email Address
          • Eye Dropper Color Picker
          • File Upload
          • Image Cropper
          • Label
          • List View
          • Markdown Editor
          • Media Picker
          • Media Picker (Legacy)
          • Member Group Picker
          • Member Picker
          • Multi Url Picker
          • Multinode Treepicker
          • Repeatable Textstrings
          • Numeric
          • Radiobutton List
          • Slider
          • Tags
          • Textarea
          • Textbox
          • Toggle
          • User Picker
          • Block Editors
            • Block Grid
            • Block List
            • Build a Custom View for a Block
            • Configuring Block Editor Label Properties
          • Dropdown
          • Grid Layout (Legacy)
            • What Are Grid Layouts?
            • Configuring The Grid Layout
            • Settings And Styling
            • Grid Editors
            • Build Your Own Editor
            • Rendering Grid In a Template
            • Grid Layout Best Practices
            • Add Values Programmatically
          • Rich Text Editor
            • Rich Text Editor Configuration
            • Rich Text Editor Styles
            • Rich Text Editor Plugins
            • Blocks in Rich Text Editor
      • Login
      • Content Templates
      • Infinite Editing
      • Log Viewer
      • Language Variants
      • Settings Dashboards
    • Data
      • Defining Content
        • Default Document Types
        • Document Type Localization
      • Creating Media
        • Default Data/Media Types
      • Members
      • Data Types
        • Default Data Types
      • Scheduled Publishing
      • Using Tabs
      • Users
      • Relations
      • Dictionary Items
      • Content Version Cleanup
    • Design
      • Templates
        • Basic Razor Syntax
        • Named Sections
        • Razor Cheatsheet
      • Rendering Content
      • Rendering Media
      • Partial Views
      • Partial View Macro Files
      • Stylesheets And JavaScript
    • Code
      • Service APIs
      • Subscribing To Notifications
      • Creating Forms
      • Debugging
        • Logging
      • Source Control
  • Implementation
    • Learn how Umbraco works
    • Routing
      • Controller & Action Selection
      • Execute Request
      • Request Pipeline
    • Custom Routing
      • Adding a hub with SignalR and Umbraco
    • Controllers
    • Data Persistence (CRUD)
    • Composing
    • Integration Testing
    • Nullable Reference Types
    • Services and Helpers
      • Circular Dependencies
    • Unit Testing
  • Extending
    • Customize the editing experience
    • Dashboards
    • Sections & Trees
      • Sections
      • Trees
        • Tree Actions
      • Searchable Trees (ISearchableTree)
    • Property Editors
      • Property Value Converters
      • Property Actions
      • Tracking References
      • Declaring your property editor
      • Content Picker Value Converter Example
    • Package Manifest
    • Macro Parameter Editors
    • Health Check
      • Health Check Guides
        • Click-Jacking Protection
        • Content/MIME Sniffing Protection
        • Cross-site scripting Protection (X-XSS-Protection header)
        • Debug Compilation Mode
        • Excessive Headers
        • Fixed Application Url
        • Folder & File Permissions
        • HTTPS Configuration
        • Macro Errors
        • Notification Email Settings
        • SMTP
        • Strict-Transport-Security Header
    • Language Files & Localization
    • Backoffice Search
    • Backoffice Tours
    • Backoffice UI API Documentation
    • Content Apps
    • Creating a Custom Database Table
    • Embedded Media Providers
    • Custom File Systems (IFileSystem)
      • Using Azure Blob Storage for Media and ImageSharp Cache
    • Configuring Azure Key Vault
    • Packages
      • Creating a Package
      • Language file for packages
      • Listing a Package on the Umbraco Marketplace
      • Good practice and defaults
      • Packages on Umbraco Cloud
      • Installing and Uninstalling Packages
      • Maintaining packages
      • Create accessible Umbraco packages
      • Example Package Repository
    • UI Library
  • Reference
    • Dive into the code
    • Configuration
      • Basic Authentication Settings
      • Connection strings settings
      • Content Dashboard Settings
      • Content Settings
      • Data Types Settings
      • Debug settings
      • Examine settings
      • Exception filter settings
      • FileSystemProviders Configuration
      • Global Settings
      • Health checks
      • Hosting settings
      • Imaging settings
      • Indexing settings
      • Install Default Data Settings
      • Keep alive settings
      • Logging settings
      • Maximum Upload Size Settings
      • Models builder settings
      • NuCache Settings
      • Package Migration
      • Plugins settings
      • Request handler settings
      • Rich text editor settings
      • Runtime minification settings
      • Runtime settings
      • Security Settings
      • Serilog settings
      • Tours settings
      • Type finder settings
      • Unattended
      • Web routing
    • Templating
      • Macros
        • Managing macros
        • Partial View Macros
      • Models Builder
        • Introduction
        • Configuration
        • Builder Modes
        • Understand and Extend
        • Using Interfaces
        • Tips and Tricks
      • Working with MVC
        • Working with MVC Views in Umbraco
        • View/Razor Examples
        • Using MVC Partial Views in Umbraco
        • Using View Components in Umbraco
        • Querying & Traversal
        • Creating Forms
    • Querying & Models
      • IMemberManager
      • IPublishedContentQuery
      • ITagQuery
      • UDI Identifiers
      • UmbracoContext helper
      • UmbracoHelper
      • IPublishedContent
        • IPublishedContent Collections
        • IPublishedContent IsHelpers
        • IPublishedContent Property Access & Extension Methods
    • Routing & Controllers
      • Routing requirements for backoffice authentication
      • Custom MVC controllers (Umbraco Route Hijacking)
      • Custom MVC Routes
      • Custom Middleware
      • URL Rewrites in Umbraco
      • Special Property Type aliases for routing
      • URL Redirect Management
      • Routing in Umbraco
        • FindPublishedContentAndTemplate()
        • IContentFinder
        • Inbound request pipeline
        • Outbound request pipeline
        • Published Content Request Preparation
      • Surface controllers
        • Surface controller actions
      • Umbraco API Controllers
        • Umbraco Api - Authorization
        • Umbraco Api - Routing & Urls
    • Content Delivery API
      • Custom property editors support
      • Extension API for querying
      • Media Delivery API
      • Protected content in the Delivery API
      • Output caching
      • Property expansion and limiting
      • Additional preview environments support
    • Webhooks
      • Expanding Webhook Events
    • API versioning and OpenAPI
    • Searching
      • Examine
        • Examine Management
        • Examine Manager
        • Custom indexing
        • PDF indexes and multisearchers
        • Quick-start
    • Using Notifications
      • Notification Handler
      • CacheRefresher Notifications Example
      • ContentService Notifications Example
      • Creating And Publishing Notifications
      • Determining if an entity is new
      • MediaService Notifications Example
      • MemberService Notifications Example
      • Sending Allowed Children Notification
      • Umbraco Application Lifetime Notifications
      • EditorModel Notifications
        • Customizing the "Links" box
      • Hot vs. cold restarts
    • Inversion of Control / Dependency injection
    • Management
      • Models Reference
        • Content
        • ContentType
        • DataType
        • DictionaryItem
        • Language
        • Media
        • MediaType
        • Relation
        • RelationType
        • ServerRegistration
        • Template
      • Services Reference
        • AuditService
        • ConsentService
        • DataTypeService
        • DomainService
        • EntityService
        • ExternalLoginService
        • FileService
        • MacroService
        • MediaService
        • MemberGroupService
        • MemberService
        • MemberTypeService
        • NotificationService
        • PackagingService
        • PublicAccessService
        • RedirectUrlService
        • RelationService
        • ServerRegistrationService
        • TagService
        • TextService
        • ContentService
          • Create content programmatically
          • Publish content programmatically
        • ContentTypeService
          • Retrieving content types
          • Retrieving content types
        • LocalizationService
          • Retrieving languages
        • UserService
          • Creating a user
    • Plugins
      • Creating Resolvers
      • Finding types
    • Cache & Distributed Cache
      • Accessing the cache
      • ICacheRefresher
      • IServerMessenger
      • Getting/Adding/Updating/Inserting Into Cache
      • Examples
        • Working with caching
    • Response Caching
    • Security
      • API rate limiting
      • BackOfficeUserManager and Events
      • Cookies
      • Replacing the basic username/password check
      • External login providers
      • Locking of Users and password reset
      • Reset admin password
      • Umbraco Security Hardening
      • Umbraco Security Settings
      • Sensitive data
      • Sanitizing the Rich Text Editor
      • Setup Umbraco for a FIPS Compliant Server
      • HTTPS
      • Two-factor Authentication
      • Server-side file validation
    • Scheduling
    • Common Pitfalls & Anti-Patterns
    • API Documentation
    • Debugging with SourceLink
    • Language Variation
    • UmbracoMapper
    • Distributed Locks
    • AngularJS
      • Directives
        • umbLayoutSelector
        • umbLoadIndicator
        • umbProperty
      • Services
        • Editor Service
        • Events Service
          • changeTitle
  • Tutorials
    • Overview
    • Creating a Basic Website
      • Getting Started
      • Document Types
      • Creating Your First Template
      • CSS and Images
      • Displaying the Document Type Properties
      • Creating a Master Template
      • Creating Pages and Using the Master Template
      • Setting the Navigation Menu
      • Articles and Article Items
      • Adding Language Variants
      • Conclusions
    • Creating a Custom Dashboard
      • Extending the Dashboard using the Umbraco UI library
    • Creating a Property Editor
      • Adding configuration to a property editor
      • Integrating services with a property editor
      • Adding server-side data to a property editor
    • Creating a Multilingual Site
    • Add Google Authentication (Users)
    • Add Microsoft Entra ID authentication (Members)
    • Creating a Backoffice Tour
    • Creating Custom Database Tables with Entity Framework
    • The Starter Kit
      • Lessons
        • Customize the Starter Kit
        • Add a Blog Post Publication Date
          • Add a Blog Post Publication Date
          • Add a Blog Post Publication Date
        • Add Open Graph
          • Add Open Graph - Step 1
          • Add Open Graph - Step 2
          • Add Open Graph - Step 3
          • Add Open Graph - Step 4
          • Add Open Graph - Summary
        • Ask For Help and Join the Community
    • Editor's Manual
      • Getting Started
        • Logging In and Out
        • Umbraco Interface
        • Creating, Saving and Publishing Content Options
        • Finding Content
        • Editing Existing Content
        • Sorting Pages
        • Moving a Page
        • Copying a Page
        • Deleting and Restoring Pages
      • Working with Rich Text Editor
      • Version Management
        • Comparing Versions
        • Rollback to a Previous Version
      • Media Management
        • Working with Folders
        • Working with Media Types
        • Cropping Images
      • Tips & Tricks
        • Refreshing the Tree View
        • Audit Trail
        • Notifications
        • Preview Pane Responsive View
        • Session Timeout
    • Multisite Setup
    • Member Registration and Login
    • Custom Views for Block List
    • Connecting Umbraco Forms and Zapier
    • Creating an XML Sitemap
    • Implementing Custom Error Pages
Powered by GitBook
On this page
  • What are Content Apps
  • Default Content Apps
  • Custom Content Apps
  • Creating a Custom Content App
  • Setting up the Plugin
  • Creating the View and the Controller
  • Checking it works
  • Limiting according to type
  • Limiting according to User Role
  • C#: Creating a Content App
  • Notification badges
Edit on GitHub
Export as PDF
  1. Extending

Content Apps

A guide configuring content apps in Umbraco

PreviousBackoffice UI API DocumentationNextCreating a Custom Database Table

Last updated 1 year ago

What are Content Apps

Content Apps are companions to the editing experience when working with content or media in the Umbraco backoffice.

With Content Apps, editors can switch from editing 'Content' to accessing contextual information related to the item they are editing.

Default Content Apps

'Info' - The 'Info' Content App is a default Content App for all items, displaying Links, History and Status of the current content item.

Custom Content Apps

As an integrated part of Umbraco it is possible for you as a developer to create and provide your editors with helpful Content Apps.

For example, you could create a Google Analytics integration within a Content App. This would then display to editors the current 'page views' for the content item they are editing.

Controlling Appearance/Position

You can associate an icon and control the position of your custom Content App. The position, for example between 'Content' and 'Info', is set via a 'weighting' number.

Permissions

Content Apps can be configured to appear dependent on Section, Content Type and User Group Permissions.

Read-Only

Content Apps are designed to be companions to the Content Item. They should enhance the editor's experience by enabling quick access to contextual information for the particular content item they are editing. Content Apps are not intended to be used for the editing content.

Creating a Custom Content App

This guide explains how to set up a custom Content App in the following steps:

  • Adding a Content App that counts how many words are added for each property type

  • Limiting the Content App to appear for only specific content types

  • Limiting which user groups can see the Content App

A basic understanding of how to use AngularJS with Umbraco is required. If you have created a property value editor before, this will all feel familiar.

Setting up the Plugin

The first thing we do is create a new folder inside /App_Plugins folder. We will call it WordCounter.

Next we need to create a manifest file to describe what this Content App does. This manifest will tell Umbraco about our new Content App and allows us to inject any needed files into the application.

Create a new file in the /App_Plugins/WordCounter/ folder and name it package.manifest. In this new file, copy the code snippet below and save it. This code describes the Content App. To help you understand the JSON, read the inline comments for details on each bit:

{
    // define the content apps you want to create
    "contentApps": [
    {
        "name": "Word Counter", // required - the name that appears under the icon
        "alias": "wordCounter", // required - unique alias for your app
        "weight": 0, // optional, default is 0, use values between -99 and +99 to appear between the existing Content (-100) and Info (100) apps
        "icon": "icon-calculator", // required - the icon to use
        "view": "~/App_Plugins/WordCounter/wordcounter.html", // required - the location of the view file
        "show": [
        "+content/*" // show app for all content types
      ]
    }
    ],
    // array of files we want to inject into the application on app_start
    "javascript": [
        "~/App_Plugins/WordCounter/wordcounter.controller.js"
    ]
}

Umbraco backoffice uses the Helveticons icon pack by default.

Creating the View and the Controller

Add 2 additional files to the /App_Plugins/WordCounter/ folder:

  • wordcounter.html

  • wordcounter.controller.js

These 2 files will be our main files for the app, with the .html file handling the view and the .js file handling the functionality.

In the .js file we declare our AngularJS controller and inject Umbraco's editorState and userService:

angular.module("umbraco")
    .controller("My.WordCounterApp", function ($scope, editorState, userService, contentResource) {

        var vm = this;
        vm.CurrentNodeId = editorState.current.id;
        vm.CurrentNodeAlias = editorState.current.contentTypeAlias;

        var counter = contentResource.getById(vm.CurrentNodeId).then(function (node) {
            var properties = node.variants[0].tabs[0].properties;

            vm.propertyWordCount = {};

            var index;
            for (index = 0; index < properties.length; ++index) {
                var words = properties[index].value;
                var wordCount = words.trim().split(/\s+/).length;

                vm.propertyWordCount[properties[index].label] = wordCount;
            }
        });

        var user = userService.getCurrentUser().then(function (user) {
            vm.UserName = user.name;
        });

    });

And in the .html file:

<div  ng-controller="My.WordCounterApp as vm">
    <umb-box>
        <umb-box-header title="Amount of words for each property"></umb-box-header>
        <umb-box-content>
            <div ng-repeat="(key, value) in vm.propertyWordCount">
                <p>Property: <span style="font-style:italic">{{key}}</span>, amount of words: <span style="font-style:italic">{{value}}</span> </p>
            </div>
            <hr />

            <ul>
                <li>Current node id: <b>{{vm.CurrentNodeId}}</b></li>
                <li>Current node alias: <b>{{vm.CurrentNodeAlias}}</b></li>
                <li>Current user: <b>{{vm.UserName}}</b></li>
            </ul>
        </umb-box-content>
    </umb-box>
</div>

Checking it works

After the above edits are done, restart your application. Go to any content node and you should now see an app called Word Counter. Clicking on the icon should say "Amount of words for each property" and confirm the details of the current item and user. You can now adapt your Content App to retrieve external data using the standard Umbraco and AngularJS approach.

Limiting according to type

You can set your Content App to only show for specific types by adding a 'show' directive in the package.manifest file.

This can be done for both Content and Media Types and for Member types. It is also possible to show the Content App on specific Document Types (contentTypes) in the Settings section.

Here is an example where all types are taken into consideration when limiting access to a Content App:

{
    "contentApps": [
        {
            "show": [
                "-content/homePage", // hide for content using the 'homePage' Document Type (Content section)
                "+content/*", // show for content using any other Document Type (Content section)
                "+media/*", // show for all Media Types
                "-member/premiumMembers", // hide for Member Type 'premiumMembers'
                "+member/*", // show for all other Member Types
                "-contentType/textPage", // hide on the Document Type with alias 'textPage' (Settings section)
                "+contentType/*", // show on all other Document Types (Settings section)
            ]
        }
    ]
}

When the 'show' directive is omitted then the app will be shown for all types.

Also, when you want to exclude any type, make sure to include all the rest of that type, using "+content/*", "+media/*" or "+member/*".

In this case, the WordCounter app is only usable within the Content section so you have to exclude it from all other types.

Limiting according to User Role

In a similar way, you can limit your Content App according to user roles (groups). For example:

{
    "contentApps": [
        {
            "show": [
                "+role/admin"  // show for 'admin' user group
            ]
        }
    ]
}

When a role restriction is given in the manifest, it overrides any other restrictions based on type.

C#: Creating a Content App

This is an example of how to create a Content App with C# and perform your own custom logic to show a Content App. Create a WordCounter.cs file with the following implementation:

using System.Collections.Generic;
using System.Linq;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Models.Membership;

namespace My.Website;

public class WordCounterAppComponent : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        // Add our word counter content app into the composition aka into the DI
        builder.ContentApps().Append<WordCounterApp>();
    }
}

public class WordCounterApp : IContentAppFactory
{
    public ContentApp? GetContentAppFor(object source, IEnumerable<IReadOnlyUserGroup> userGroups)
    {
        // Can implement some logic with userGroups if needed
        // Allowing us to display the content app with some restrictions for certain groups
        if (userGroups.All(x => x.Alias.ToLowerInvariant() != Umbraco.Cms.Core.Constants.Security.AdminGroupAlias))
            return null;

        // Only show app on content items
        if (source is not IContent content)
            return null;

        // Only show app on content items with template
        if (content.TemplateId is null)
            return null;

        // Only show app on content with certain content type alias
        // if (!content.ContentType.Alias.Equals("aliasName"))
        //    return null;

        return new ContentApp
        {
            Alias = "wordCounter",
            Name = "Word Counter",
            Icon = "icon-calculator",
            View = "/App_Plugins/WordCounter/wordcounter.html",
            Weight = 0
        };
    }
}

You will still need to add all of the files you added above. However, because your C# code is adding the Content App, the package.manifest file can be simplified like this:

{
    // array of files we want to inject into the application on app_start
    "javascript": [
        "~/App_Plugins/WordCounter/wordcounter.controller.js"
    ]
}

You can also have a coloured icon for your Content App by specifying the icon in the format icon-[name of icon] color-[name of color]. For eg, an indigo colored icon can be specified for your Content App by specifying the icon as "icon-calculator color-indigo" in your Content App C# class or package.manifest .

Notification badges

There are times when you want to draw the attention of editors to your content badge, so they know they need to take some action. That is where notification badges come in to play.

When you set a badge, a circle with a chosen background and a number in it will be added to the content app icon.

You can enable a badge by using this code in the angular controller of your content app.

$scope.model.badge = {
  count: 5, // the number for the badge - anything non-zero triggers the badge
  type: "warning" // optional: determines the badge color - "warning" = dark yellow, "alert" = red, anything else = blue (matching the top-menu background color)
};

Further customization can be done by setting a notification badge from an IContentAppFactory. This is achieved by setting the badge property on the ContentApp model.

using System.Collections.Generic;
using System.Linq;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Models.Membership;

namespace My.Website;

public class WordCounterAppComponent : IComposer
{
    public void Compose(IUmbracoBuilder builder)
    {
        // Add our word counter content app into the composition aka into the DI
        builder.ContentApps().Append<WordCounterApp>();
    }
}

public class WordCounterApp : IContentAppFactory
{
    public ContentApp? GetContentAppFor(object source, IEnumerable<IReadOnlyUserGroup> userGroups)
    {
        // Can implement some logic with userGroups if needed
        // Allowing us to display the content app with some restrictions for certain groups
        if (userGroups.All(x => x.Alias.ToLowerInvariant() != Umbraco.Cms.Core.Constants.Security.AdminGroupAlias))
            return null;

        // Only show app on content items
        if (source is not IContent content)
            return null;

        // Only show app on content items with template
        if (content.TemplateId is null)
            return null;

        // Only show app on content with certain content type alias
        // if (!content.ContentType.Alias.Equals("aliasName"))
        //    return null;

        return new ContentApp
        {
            Alias = "wordCounter",
            Name = "Word Counter",
            Icon = "icon-calculator",
            View = "/App_Plugins/WordCounter/wordcounter.html",
            Weight = 0
        };
    }
}

Possible values for the ContentAppBadge Type are Default, Alert and Warning.

Content Apps in backoffice
Content App in action: Word Counter
Content App badge