{"id":1248,"date":"2017-07-19T12:35:53","date_gmt":"2017-07-19T19:35:53","guid":{"rendered":"https:\/\/blogs.plm.automation.siemens.com\/t5\/Teamcenter-Blog\/Declarative-Programming-to-Author-Active-Workspace-Commands\/ba-p\/421802"},"modified":"2026-03-26T08:49:15","modified_gmt":"2026-03-26T12:49:15","slug":"declarative-programming-to-author-active-workspace-commands","status":"publish","type":"post","link":"https:\/\/blogs.sw.siemens.com\/teamcenter\/declarative-programming-to-author-active-workspace-commands\/","title":{"rendered":"Declarative Programming to Author Active Workspace Commands"},"content":{"rendered":"<p><em>This article on declarative programming is the third in a series on web development using declarative configuration, which simplifies how your IT team can deliver an adaptive product lifecycle management (PLM) environment. Read the first <a href=\"https:\/\/blogs.plm.automation.siemens.com\/t5\/Teamcenter-Blog\/Declarative-Configuration-when-Change-is-Constant\/ba-p\/413636\" target=\"_blank\" rel=\"noopener noreferrer\">declarative configuration blog<\/a>&nbsp;and the second <a href=\"https:\/\/blogs.plm.automation.siemens.com\/t5\/Teamcenter-Blog\/Declarative-UI-Configuration-with-Active-Workspace\/ba-p\/417017\" target=\"_blank\" rel=\"noopener noreferrer\">declarative UI blog<\/a>&nbsp;for background, and read on to learn more about the Siemens strategy to help you deliver Active Workspace solutions tailored to your unique business processes through declarative programming with re-usable components, instead of writing custom software code.<\/em><\/p>\n<p><span>In this blog series on declarative programming I first introduced the topic of <a href=\"https:\/\/blogs.plm.automation.siemens.com\/t5\/Teamcenter-Blog\/Declarative-Configuration-when-Change-is-Constant\/ba-p\/413636\" target=\"_blank\" rel=\"noopener noreferrer\"><u><strong>Declarative Configuration<\/strong><\/u><\/a><\/span><span>, then I gave a quick introduction to <strong><a href=\"https:\/\/blogs.plm.automation.siemens.com\/t5\/Teamcenter-Blog\/Declarative-UI-Configuration-with-Active-Workspace\/ba-p\/417017\" target=\"_blank\" rel=\"noopener noreferrer\">Declarative UI<\/a><\/strong><\/span><span>. We looked at how UI elements form our vocabulary of <\/span>building blocks for declarative programming, so we can declaratively define <span>the View and View Model artifacts to create <\/span>our pages and panels in Active Workspace<span>.<\/span><\/p>\n<p><span>This time I\u2019m going to cover the declarative programming topic of authoring commands. We will start with an overview of declarative commands and then walk through an example to show these concepts in action.<\/span>&nbsp;<\/p>\n<h2>Declarative Programming Commands in Active Workspace<\/h2>\n<p><span>You can use declarative programming to create commands in Active Workspace that provide a graphical means for the user to work with their product, process or other data.<\/span><\/p>\n<p><span><span class=\"lia-inline-image-display-wrapper lia-image-align-inline\" style=\"width: 999px\"><img decoding=\"async\" src=\"http:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/14\/2019\/09\/Declarative-programming_1_commandsInAW-1.jpg\" alt=\"Declarative programming_1_commandsInAW.JPG\" title=\"Declarative programming_1_commandsInAW.JPG\"><span class=\"lia-inline-image-caption\">Commands in Active Workspace<\/span><\/span><\/span><\/p>\n<p><span>To fully describe the command, we need to specify its appearance (icon and tooltip), its behaviours &#8211;such as when it should be presented to the user, when it should be active, what the command should do (the action it performs) &#8212; and where it should be placed in the UI relative to other commands.<\/span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/p>\n<p>As with other pieces of the UI, commands are defined declaratively in a View and View Model. Declarative commands leverage the same View Model concepts we looked at in the <a href=\"https:\/\/blogs.plm.automation.siemens.com\/t5\/Teamcenter-Blog\/Declarative-UI-Configuration-with-Active-Workspace\/ba-p\/417017\" target=\"_blank\" rel=\"noopener noreferrer\">declarative UI configuration blog<\/a>, such as localization, <em>conditions<\/em> and <em>actions<\/em>. The View has command bars in which commands can be placed (the <em>&lt;aw-command-bar&gt; <\/em>elements). The View Model is responsible for&nbsp;view state such as <em>data<\/em>, <em>actions<\/em>, <em>conditions<\/em> and localizations in which we describe the command and its behaviours.&nbsp;<span class=\"lia-inline-image-display-wrapper lia-image-align-center\" style=\"width: 400px\"><img decoding=\"async\" src=\"http:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/14\/2019\/09\/Declarative-programming_2_commandConcepts-1.jpg\" alt=\"Declarative programming_2_commandConcepts.JPG\" title=\"Declarative programming_2_commandConcepts.JPG\"><span class=\"lia-inline-image-caption\">Command concepts<\/span><\/span><strong>Command definition<\/strong><\/p>\n<p><span>Firstly, in the View Model we are able to define a command. It has an <em>Id<\/em>, <em>icon<\/em>, and <em>title<\/em> (tooltip). The <em>iconId<\/em> points to an SVG image in the image folder in the war location. There is a complete guide defining the design language and sizing for these icons in the <a href=\"https:\/\/docs.plm.automation.siemens.com\/docs\/aw\/3.3\/en_US\/ui_pattern_library\/index.html#\/FullscreenContent\/Getting%20Started\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">UI Pattern Library in the Active Workspace Document Center (customer-only access)<\/a>.&nbsp;<\/span><span>The title is data that is recommended to be bound to localized text, but could just be the string to display if support for only one language is required.<\/span><\/p>\n<p><span><span class=\"lia-inline-image-display-wrapper lia-image-align-center\" style=\"width: 400px\"><img decoding=\"async\" src=\"http:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/14\/2019\/09\/Declarative-programming_3-1.png\" alt=\"Declarative programming_3.png\" title=\"Declarative programming_3.png\"><span class=\"lia-inline-image-caption\">Defining a command<\/span><\/span><\/span><strong><span>Command handler<\/span><\/strong><\/p>\n<p><span>The command handler is responsible for describing the behaviours of a command. When needed there can be many command handlers for the same command. However, only one command handler is active at a time for a given command. This provides the ability to have different command execution logic in different circumstances. For example when I use the open command to open a PartRevision, the user is able to view a summary of its properties, whereas using the same command to open a PDFSpecification could result in opening the PDF document in a viewer if that\u2019s what we wanted. In other words I am able to use different command handlers for the same command in different contexts. Which command handler is active is determined by the command handlers\u2019 <em>activeWhen<\/em> condition. When there are multiple handlers that have <em>activeWhen<\/em> conditions for the same command, if more than one has a condition that evaluates to true then the more specific condition (i.e. the condition with the longest expression) is chosen to be active. The <em>id<\/em> field in the command handler is what associates the command handler to a given command.<\/span><\/p>\n<p><span>For Active Workspace solutions, one of the guiding usability principles is to bring the commands and capabilities to the user that are applicable depending on who they are and what they are trying to achieve (often called their context). Rather than presenting several dozen commands, the UI is tailored to offer those that are applicable at that point in time. So when a command handler is active (that is it fulfils the <em>activeWhen<\/em> condition), whether the command is visible can be controlled by its <em>visibleWhen<\/em> condition. <\/span><\/p>\n<p>The final part of a command handler is the definition of what the command should \u201cdo.\u201d The command execution is described by a declarative <em>action<\/em>. As with any declarative action this can be a SOA service, REST invocation or JavaScript function. For example, a common JavaScript function used in Active Workspace is the function to open a command panel.<span class=\"lia-inline-image-display-wrapper lia-image-align-center\" style=\"width: 400px\"><img decoding=\"async\" src=\"http:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/14\/2019\/09\/Declarative-programming_4-1.jpg\" alt=\"Declarative programming_4.JPG\" title=\"Declarative programming_4.JPG\"><span class=\"lia-inline-image-caption\">Defining a command handler<\/span><\/span><strong><span>Command placement<\/span><\/strong><\/p>\n<p><span>Where the command should be placed in the UI relative to other commands is controlled by the command placement. When needed there can be many command placements for the same command. In other words the same command can be used in multiple places in the UI. Similar to the command handler, the <em>id<\/em> field in the command placement is what associates it to a given command.<\/span><\/p>\n<p><span>The <em>uiAnchor<\/em> field defines which command bar the command should be placed in. Some of the out-of-the-box command bars for Teamcenter Active Workspace are &#8211;<em>aw_globalToolbar<\/em>, <em>aw_navigation<\/em>, <em>aw_oneStep<\/em> and <em>aw_toolsAndInfo<\/em>. The <em>priority<\/em> field gives a relative priority order to render commands in the command bar in ascending order. Optionally a <em>relativeTo<\/em> field can be used to specify the command id of another command that this command will be placed relative to. Priority as defined in the <em>priority<\/em> field is then applied relative to the command. In other words, if multiple commands are placed <em>relativeTo<\/em> the same command, they will be placed in ascending sorted priority order relative to the specified command. Negative priority means that this command will be inserted before the <em>relativeTo<\/em> command. Positive priority means the command will be appended after the <em>relativeTo<\/em> command.<span class=\"lia-inline-image-display-wrapper lia-image-align-center\" style=\"width: 400px\"><img decoding=\"async\" src=\"http:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/14\/2019\/09\/Declarative-programming_5-1.jpg\" alt=\"Declarative programming_5.JPG\" title=\"Declarative programming_5.JPG\"><span class=\"lia-inline-image-caption\">Defining a command placement<\/span><\/span><\/span><strong><span>Declarative commands in action<\/span><\/strong><\/p>\n<p><span>Now we\u2019re familiar with the concepts, let\u2019s walk through an example that shows declarative commands in action. For this case I am going to use Active Workspace as a customer or partner will do from a kitted environment. To begin with I\u2019m going to create a new module using the module generation utilities in which we will define a command for a new \u201cQuick Links\u201d slide out panel on the left-hand side of the browser page. The Quick Links panel will also be created using declarative UI and will reuse some existing UI element building blocks to provide the user with a handy shortcut to objects on the clipboard, favorites and most recently used.<span class=\"lia-inline-image-display-wrapper lia-image-align-center\" style=\"width: 999px\"><img decoding=\"async\" src=\"http:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/14\/2019\/09\/Declarative-programming_6_commandsInAW-1.jpg\" alt=\"Declarative programming_6_commandsInAW.JPG\" title=\"Declarative programming_6_commandsInAW.JPG\"><span class=\"lia-inline-image-caption\">Generate a new module<\/span><\/span><\/span><span>Using the generateModule utility, I am able to create a new module in which to create my new command and panel.<\/span><\/p>\n<p><span>I add a simple \u201ckit.json\u201d file to include the new \u201cquicklinks\u201d module.<\/span><\/p>\n<p><span><span class=\"lia-inline-image-display-wrapper lia-image-align-center\" style=\"width: 999px\"><img decoding=\"async\" src=\"http:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/14\/2019\/09\/Declarative-programming_7-1.jpg\" alt=\"Declarative programming_7.JPG\" title=\"Declarative programming_7.JPG\"><span class=\"lia-inline-image-caption\">Create a kit.json to include your new module<\/span><\/span><\/span><\/p>\n<p>As illustrated below, by modifying the module.json I add the \u201ccommandsViewModel\u201d property. Here I can fully define the new Quick Links command (\u201ccmdQuickLinks\u201d). Notice how I specify a <em>command<\/em>, <em>commandHandler<\/em> and <em>commandPlacement<\/em> in addition to an <em>action<\/em> and <em>i18n<\/em> localizations.<span class=\"lia-inline-image-display-wrapper lia-image-align-center\" style=\"width: 999px\"><img decoding=\"async\" src=\"http:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/14\/2019\/09\/Declarative-programming_8-1.png\" alt=\"Declarative programming_8.png\" title=\"Declarative programming_8.png\"><span class=\"lia-inline-image-caption\">Declarative command for launching the QuickLinks panel<\/span><\/span><span>I also create the declarative View for the slide out panel that is launched to display the quick links in the \u201csrchtml\u201d folder. I am able to reuse existing UI elements for a slide out command panel. Within the panel body element I use the clipboard, favorites and history UI elements. Because of this reuse, this View boils down to 5 simple tags, one for the panel, one for the body in the panel, and 3 for the 3 lists in the body of the panel.<span class=\"lia-inline-image-display-wrapper lia-image-align-center\" style=\"width: 999px\"><img decoding=\"async\" src=\"http:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/14\/2019\/09\/Declarative-programming_11-1.jpg\" alt=\"Declarative programming_11.JPG\" title=\"Declarative programming_11.JPG\"><span class=\"lia-inline-image-caption\">Declarative View for the QuickLinks panel<\/span><\/span><\/span><\/p>\n<p><span>The View Model for the slide out panel that is launched is added to \u201csrcviewmodel\u201d folder. The View Model is equally simple and imports just the UI elements referenced in the View and the localization strings.<\/span><\/p>\n<p><span><span class=\"lia-inline-image-display-wrapper lia-image-align-center\" style=\"width: 999px\"><img decoding=\"async\" src=\"http:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/14\/2019\/09\/Declarative-programming_10-1.jpg\" alt=\"Declarative programming_10.JPG\" title=\"Declarative programming_10.JPG\"><span class=\"lia-inline-image-caption\">Declarative View Model for the QuickLinks panel<\/span><\/span><\/span><\/p>\n<p><span>By running the \u201cwarRefresh\u201d command and deploying the updated awc.war file to your app server you can then try out the changes (play video).&nbsp;<\/span><\/p>\n<div class=\"lia-vid-container video-embed-center\">\n<div id=\"lia-vid-NqOXl5YjE6BkMIeYjhXr3e_Jtb9aHPzxw400h300r235\" class=\"lia-video-ooyala-player-container\"><\/div>\n<p>LITHIUM.OoyalaPlayer.addVideo(&#8216;https:\/\/player.ooyala.com\/static\/v4\/production\/&#8217;, &#8216;lia-vid-NqOXl5YjE6BkMIeYjhXr3e_Jtb9aHPzxw400h300r235&#8217;, &#8216;NqOXl5YjE6BkMIeYjhXr3e_Jtb9aHPzx&#8217;, {&#8220;pcode&#8221;:&#8221;sxdjkxOluLl_gSQrV57FiGraFE2-&#8220;,&#8221;playerBrandingId&#8221;:&#8221;ODI0MmQ3NjNhYWVjODliZTgzY2ZkMDdi&#8221;,&#8221;width&#8221;:&#8221;400px&#8221;,&#8221;height&#8221;:&#8221;300px&#8221;});<a class=\"video-embed-link\" href=\"https:\/\/blogs.plm.automation.siemens.com\/t5\/video\/gallerypage\/video-id\/NqOXl5YjE6BkMIeYjhXr3e_Jtb9aHPzx\" target=\"_blank\" rel=\"noopener\">(view in My Videos)<\/a><\/p>\n<\/div>\n<p><span>Because<\/span><span> we are re-using the existing UI elements for &lt;aw-clipboard&gt;, &lt;aw-favorite&gt; and &lt;aw-history&gt; that internally are re-using the &lt;aw-list&gt; element, I also get the ability to multi-select and drag and drop from the quick links with no additional code and just a few lines of declarative mark-up.<\/span><\/p>\n<p><span>Hopefully that\u2019s given you a taste of what\u2019s possible with authoring commands for Active Workspace with declarative UI. Look out for the next instalment of the blog for declarative configuration soon\u2026<\/span><\/p>\n<p><span>Dave McLeish<\/span><\/p>\n<p><span>Senior Key Expert, CTO Office of Architecture &amp; Technology, Siemens PLM<\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This article on declarative programming is the third in a series on web development using declarative configuration, which simplifies how your IT team can deliver an adaptive product lifecycle manage&#8230;<\/p>\n","protected":false},"author":30224,"featured_media":1279,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"spanish_translation":"","french_translation":"","german_translation":"","italian_translation":"","polish_translation":"","japanese_translation":"","chinese_translation":"","footnotes":""},"categories":[1],"tags":[444,26],"industry":[],"product":[],"coauthors":[],"class_list":["post-1248","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-news","tag-active-workspace","tag-plm-foundation"],"featured_image_url":"https:\/\/blogs.sw.siemens.com\/wp-content\/uploads\/sites\/14\/2019\/09\/Declarative-programming_10-1.jpg","_links":{"self":[{"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/posts\/1248","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/users\/30224"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/comments?post=1248"}],"version-history":[{"count":5,"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/posts\/1248\/revisions"}],"predecessor-version":[{"id":5937,"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/posts\/1248\/revisions\/5937"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/media\/1279"}],"wp:attachment":[{"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/media?parent=1248"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/categories?post=1248"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/tags?post=1248"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/industry?post=1248"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/product?post=1248"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blogs.sw.siemens.com\/teamcenter\/wp-json\/wp\/v2\/coauthors?post=1248"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}