Download as pdf or txt
Download as pdf or txt
You are on page 1of 1001

1. Architecture and Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

7
1.1 Open Areas of Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.1.1 Workshops . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
1.1.1.1 2014-11-18 Managing Experience Depending on Referrer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
1.1.1.2 2015-01-28 Authoring: UX to API mapping meetings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
1.1.1.3 2015-02-06 Testing and Mock Frameworks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.1.1.4 2015-02-09 Cognifide Slice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
1.1.2 Design Decisions Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.1.3 User Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.1.3.1 Remote Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
1.1.3.2 User Access and User Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.1.4 Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.1.4.1 Front-End Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
1.1.4.2 Back-end Search . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
1.1.5 Galleries and Entity handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
1.1.6 Login and Bastion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
1.1.7 Changes to Entity Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
1.1.8 Asynchronous calls from the Authoring tool - Draft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
1.1.9 Owner and Delivery Platforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
1.1.10 Dates in AEM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
1.1.11 Sitemaps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
1.1.12 RSS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
1.1.13 Image paths in AEM DAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
1.1.14 Cluster Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
1.1.15 Live Articles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
1.1.15.1 Basic Live Articles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
1.1.15.2 Target Live Articles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
1.1.16 Primary Topic options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
1.1.17 Editorial Order for Hub pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
1.1.17.1 Providing override fields in the editorial order . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
1.1.18 Auto Redirect when article page URLs change . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
1.1.19 AMP (Google top result card and SEO) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
1.1.19.1 Google AMP in AEM Proof of Concept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
1.2 Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71
1.2.1 Periodic Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
1.3 Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
1.3.1 Adobe Analytics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
1.3.1.1 Most Viewed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
1.3.1.1.1 Most Viewed List diagram . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
1.3.2 Adobe Campaign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
1.3.2.1 Basket Abandonment email marketing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
1.3.3 Adobe Social Communities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
1.3.3.1 Adobe Live Article Service Pack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
1.3.3.2 Options for Migrating comments from Disqus to AEM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
1.3.4 Front-end . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
1.3.4.1 New Slider/Gallery . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
1.3.5 Nitro Integration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
1.3.5.1 AEM Content Retrieval (JSON-LD Selector) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
1.3.5.1.1 AEM Article -> Canonical Model mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
1.3.5.2 AEM Cross Domain Ajax Requests to TMG's Core API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
1.3.5.3 AEM Data Driven Pages (Nitro Entity Roadmap) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 100
1.3.6 Script Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
1.3.7 Video . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 104
1.3.8 Dynamic Image Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
1.3.8.1 Param Crop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
1.3.9 Embeds . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
1.3.10 Image renditions offloading to Amazon web services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
1.4 Processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
1.4.1 Ways of Working . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
1.4.2 Mocks Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
1.4.3 AEM Clientlib inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121
1.5 Projects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
1.5.1 Data Registration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
1.5.1.1 Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
1.5.1.1.1 Infrastructure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
1.5.1.1.2 Process Flows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
1.5.1.1.3 AEM Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127
1.5.1.1.4 Administration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
1.5.1.1.5 Escenic Changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
1.5.1.2 Integration Points . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
1.5.1.2.1 Analytics and Segmentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131
1.5.1.2.2 Core API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
1.5.1.2.3 Data Registration: Adobe Campaign . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
1.5.1.2.4 Data Registration: Script Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
1.5.1.2.5 Proxy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
1.5.2 Technical Debt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
1.6 Archive (To be deleted) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
1.6.1 Launching a new TMG channel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
1.7 404 pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139

1
1.8 Moving channels from Escenic to AEM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
1.9 Risks and Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 145
1.10 Web Font Register . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
1.10.1 Investigate font optimisation AEM-1708 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
1.11 Browser Support Matrix . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
1.12 Adobe Managed Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
1.12.1 File lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
1.12.2 Reference Material . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154
1.13 Invalidation Caching Strategy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 155
1.14 List with Sling Dynamic Include . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
1.15 Metered Paywall . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
1.16 Replication Offloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 160
1.17 URL to Resource mapping for Year, Month and Date content hierarchy - Externalise mapping to Redis . . . . . . . . . . . . . . . . . . . 162
2. Component and Template requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
2.1 Article Page Template Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
2.2 Component Bible . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 170
2.2.1 Ad Blocker Detector . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
2.2.2 Advert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
2.2.3 Advert Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
2.2.3.1 Advert Management background and usage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
2.2.4 Article 2 Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
2.2.5 Article Body Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
2.2.6 Article Body Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
2.2.7 Article Date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
2.2.8 Article List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 217
2.2.9 Author 2 Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
2.2.10 Author Bio . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223
2.2.11 Autotweeting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 227
2.2.12 Blank Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 233
2.2.13 Box Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
2.2.14 Breadcrumb Bar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 235
2.2.15 Byline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
2.2.16 Cluster template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 241
2.2.17 Component Styles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 242
2.2.18 Content structure - Channels, Sections and Articles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244
2.2.19 Curated List 2 & Curated List Tile 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
2.2.20 Curated List & Curated List Tile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
2.2.21 Entities (Cars, Film, Best) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
2.2.22 Error Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
2.2.23 Folder Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
2.2.24 Gallery Teaser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
2.2.25 Gallery Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
2.2.26 Google AMP . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
2.2.27 Google AMP POC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 272
2.2.28 Hard Regwall (ESI) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 275
2.2.29 Header . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
2.2.30 Headline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
2.2.31 HTML Embed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 282
2.2.32 Hub Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
2.2.33 Image Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
2.2.34 Lead Asset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
2.2.35 List (The) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
2.2.36 List of Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
2.2.37 Metatags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
2.2.38 Most Viewed List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
2.2.39 Navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 314
2.2.39.1 Footer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 317
2.2.39.2 Local Navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
2.2.40 Ooyala overlay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
2.2.41 Paywall, meter (ESI) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 321
2.2.42 Publication Date Override . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 328
2.2.43 Segment Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
2.2.44 Snippet & Snippet Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
2.2.45 Social Follow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
2.2.46 Social Share . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 340
2.2.47 Spark Slots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 343
2.2.48 Splitter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
2.2.49 Sponsor's Reskin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
2.2.50 Sponsored Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
2.2.51 Sponsored Lists . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
2.2.52 Sticky-Ad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
2.2.53 Sticky Branding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362
2.2.54 Sticky Preview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
2.2.55 Tag Mapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
2.2.56 Topic Pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 371
2.2.56.1 Topic Page URL resolution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 374
2.2.56.2 Topic tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
2.2.57 Topic Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 376
2.2.58 Video Player - Ooyala Updates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377

2
2.2.59 Video Player - Relevant Recommendations & Autoforwarding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
2.3 Components tracking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
3. How-to articles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
3.1 Ad Blocker Message . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 387
3.2 Adding content, javascript or CSS to a page using the HTML Embed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 389
3.3 Blacklisting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
3.4 Bulk Tag Upload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 393
3.5 Business Segment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
3.6 Clearing down diskspace on Adobe instances . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
3.7 Commenting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 398
3.7.1 Commenting Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 399
3.7.1.1 Commenting Channels & Sections Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 401
3.7.1.2 Commenting Global Switch Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 403
3.7.1.3 Default Commenting setting for new Channels and Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
3.7.1.4 Feature flag for Commenting in Authoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
3.7.1.5 How to set initial commenting configuration for channels and sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
3.7.1.6 Livefyre Configuration for Single Story . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 410
3.7.1.7 Livefyre Configuration in AEM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
3.7.1.8 Livefyre Global Configuration for Commenting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 412
3.7.2 Commenting endpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 414
3.7.2.1 Channels and Sections Provider Servlet (OPI-46) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 415
3.7.2.2 Commenting Configuration Reader Servlet (OPI-46) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416
3.7.2.3 Save Commenting Configuration Servlet (OPI-46) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 417
3.7.3 Commenting Solution Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 418
3.7.4 Commenting support . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 421
3.7.5 Livefyre Studio User Roles and permissions granted to each user role . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
3.7.6 Setting up Livefyre Comment feature on Localhost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 423
3.8 Component Validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 424
3.9 Configure a TMG subscription product . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
3.10 Configure clientlibs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 429
3.11 Creating a Channel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
3.12 Creating a new Channel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 432
3.13 Git Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 456
3.14 Hiding Channels prior to launch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 459
3.15 How to add HTML Embed in Global Navigation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 461
3.16 How to configure Mid-Article Unit for content via LiftIgniter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
3.17 How to configure Reg Walls in AEM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 467
3.18 How to Flush Content on Secure 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470
3.19 Inject Sponsor logo and message using JS (spark) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 472
3.20 Mobile previews . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
3.21 New Developer Application Setup 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
3.22 New Developer Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 478
3.23 Optimizely and ESI Switches . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 479
3.24 Performance impact of Inheritance Value Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 480
3.25 Troubleshooting Advice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 482
3.26 UI Environment Cheetsheet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483
3.27 Understanding application configuration pages . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 484
3.28 Using Sponsor Slots . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 485
3.29 Web images with Akamai Image Manager . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 486
4. Technical . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 490
4.1 Application Monitoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 491
4.2 Asynchronous Solution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493
4.2.1 Asynchronous browser communication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
4.2.2 Asynchronous Communication - Known issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 496
4.2.3 PubNub Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 497
4.3 Authoring Automation tests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 498
4.3.1 Automated Tests - useful links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 499
4.3.2 Solutions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 500
4.3.2.1 Remote image upload . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 501
4.4 Authoring Coding Standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 502
4.5 Authoring git standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 504
4.6 Authoring performance testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 505
4.6.1 FS Performance Testing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 506
4.6.2 Installing & running jmeter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 507
4.6.3 Performance Test: Pre-conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 508
4.6.4 Running groovy script to crunch SI values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
4.6.5 Running JMeter test via Bamboo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 510
4.6.5.1 How to Analyse Performance Test Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 512
4.7 Authoring Publishing Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513
4.7.1 Component Publishing Flow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
4.8 Authoring Technical Debt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 518
4.9 Authoring tool story statuses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
4.9.1 Authoring Story Statuses - Sequence Diagrams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 521
4.9.1.1 Story status flow - Publishing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 522
4.9.1.2 Story status flow - Scheduling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 524
4.9.2 Authoring tool Story Statuses calculation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 525
4.10 CK Editor Notes for Authoring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 526
4.11 Elasticsearch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 529
4.11.1 Elasticsearch DEV/TEST/DEMO server configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 530

3
4.11.2 ElasticSearch Endpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 531
4.11.2.1 ElasticSearchSearchServlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532
4.11.2.2 TmgPageReindexContentServlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 533
4.11.3 ElasticSearch Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 534
4.11.4 Reindex content in ElasticSearch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
4.11.5 Remove index from ElasticSearch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 537
4.11.6 Setup ElasticSearch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 538
4.12 Front end frameworks for Authoring UI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
4.13 Gitflow branching model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 543
4.14 JSON Communication Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
4.14.1 Assets Manager Servlet (AUT-34) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 545
4.14.2 Author Autocomplete Servlet (AEM-401) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
4.14.3 Component properties.json structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 549
4.14.4 Content Manager Servlet (AUT-25) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 555
4.14.4.1 Components Json v2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 567
4.14.5 Content Types Provider Servlet (AUT-7) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 570
4.14.6 Environment Configuration Servlet (AEM-1741, AEM-444) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 571
4.14.7 Finder Search Servlet (AEM-189) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 572
4.14.8 Finder Servlet (AUT-88) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 574
4.14.9 Keyword Search Servlet (AEM-1557) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 576
4.14.10 Open Premium Mock API (AEM-5962) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 577
4.14.10.1 Authoring Open Premium Mock API Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 579
4.14.11 Preview Servlet (AUT-18) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 583
4.14.12 Sections Feed Servlet (AUT-8) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 584
4.14.13 Server Time Servlet (AEM-4325) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 586
4.14.14 Status codes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 587
4.14.15 Story Copy Servlet (AEM-3367) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 588
4.14.16 User Information Servlet (AUT-5) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 589
4.14.17 User Logout Servlet (AUT-4) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 590
4.14.18 Workflow Manager Servlet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 591
4.14.18.1 Publish Action (AUT-20) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 593
4.15 Logging with New Relic and ELK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 594
4.16 NFRs - Non-functional requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 596
4.17 Open Premium API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 598
4.18 Solution Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 599
4.18.1 01 Business Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 600
4.18.2 02 Application Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 601
4.18.2.1 Page Status . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 606
4.18.3 03 Business continuity plan / Disaster Recover . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 607
4.19 Tagging - AEM and Semantic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 608
5. Components and related features . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 612
5.1 Adverts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 616
5.2 Article Body Headline . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 618
5.3 Article Body Image - old . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 622
5.4 Article Body Standfirst . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 626
5.5 Article Body Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 630
5.6 Article Body Text - old . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634
5.7 Article Date Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 637
5.8 Author . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 638
5.8.1 Author component configuration for Film Channel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 641
5.8.2 Author Content (ID) Component Requirement Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 642
5.9 Author Bio Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 648
5.10 Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 653
5.11 Breadcrumb . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 655
5.12 Byline (deprecated) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 659
5.13 Call To Action Box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 662
5.14 Compare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 666
5.15 Countdown Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 669
5.16 Curated List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 673
5.17 Curated List 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 676
5.18 External Video Player . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 681
5.19 Headline Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 683
5.20 Image group . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 685
5.21 Image with Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 688
5.22 Inline Content . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 689
5.23 Lead Asset Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 692
5.24 List . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 697
5.24.1 How to provide design requirements for lists? - draft . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 698
5.24.2 List Content Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 701
5.24.2.1 Content Type Comment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 702
5.24.2.2 Content Type Live . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 703
5.24.2.3 Content Type Video . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 704
5.24.3 List for Cars and Film . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 706
5.24.4 List Headings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 708
5.24.4.1 Primary Heading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 709
5.24.4.2 Secondary Heading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 710
5.24.4.3 Secondary title . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 711
5.24.5 List hover states . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 712
5.24.6 List Item Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 713

4
5.24.6.1 List Item Type 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 714
5.24.6.2 List Item Type 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 715
5.24.6.3 List Item Type 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 716
5.24.6.4 List Item Type 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 717
5.24.6.5 List Item Type 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 718
5.24.6.6 List Item Type 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 719
5.24.6.7 List Item Type 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 720
5.24.6.8 List Item Type 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 721
5.24.6.9 List Item Type 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 722
5.24.7 List Versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 723
5.24.7.1 Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 726
5.24.7.2 List Version 1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 729
5.24.7.3 List Version 2 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 733
5.24.7.4 List Version 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 739
5.24.7.5 List Version 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 746
5.24.7.6 List Version 5 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 753
5.24.7.7 List Version 6 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 758
5.24.7.8 List Version 7 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 762
5.24.7.9 List Version 8 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 765
5.24.7.10 List Version 9 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 771
5.24.7.11 List Version 10 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 772
5.24.7.12 List Version 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 785
5.24.7.13 List Version 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 789
5.24.7.14 List Version 13 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 801
5.24.7.15 List Version 14 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 805
5.24.7.16 List Version 15 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 817
5.24.7.17 List Version 16 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 826
5.24.8 News Homepage Timebreaks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 832
5.25 List of Links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 835
5.26 List of Tags - old . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 837
5.27 Logo Bar Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 838
5.28 Lower and Upper instream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 843
5.29 Meta Property Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 845
5.30 Meta tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 848
5.31 Most Viewed List (old) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 851
5.32 Outbrain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 856
5.33 Page ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 858
5.34 Properties Entity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 859
5.35 Quote Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 860
5.36 Rating . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 864
5.37 Related Entities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 865
5.37.1 Improvement ideas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 872
5.38 Renderer Config Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 873
5.39 Review List of Links . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 876
5.40 Snippet and Snippet Reference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 878
5.41 Social Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 880
5.42 Stand First Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 883
5.43 Sticky Ad . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 885
5.44 Sticky box . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 887
5.45 Summary Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 889
5.46 Text . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 891
5.46.1 Body Copy Component Requirement Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 893
5.47 Tweet Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 898
5.48 Tweet Timeline Component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 901
5.49 Twitter Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 905
5.50 Video Player . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 906
6. Component Tracking . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 913
7. Content Refresh . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 915
8. Cookie Audit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 918
9. Core Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 919
9.1 Entities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 920
9.2 Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 923
10. Debug Caching Issues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 925
11. Deploying the List Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 927
12. Image Renditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 928
13. Login, Registration and Subscription . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 931
13.1 API's . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 932
13.2 Forgotten Password . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 933
13.3 Global Navigation setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 934
13.4 Login . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 935
13.5 Password Reset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 936
13.6 Payment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 938
13.7 Payment Confirmation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 939
13.8 Registration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 940
13.9 SoapUI - testing of TMG account API's . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 941
13.10 Test accounts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 942
14. New Relic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 943
14.1 New Relic Authoring Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 944
15. Opentag tag management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 951

5
15.1 Opentag Cookie Widget Setup . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 952
16. Templates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 958
16.1 Review Template . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 960
17. UI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 961
17.1 Accessibility . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 962
17.2 Front End Optimisations - 2 Seconds TTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 965
17.3 List component . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 967
17.4 Schema.org . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 968
17.5 Time tag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 971
17.6 TMG Channels guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 973
17.7 TMG SASS guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 978
17.7.1 Custom styles - ClientLib configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 979
17.7.2 Font Scaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 981
17.7.3 SASS architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 983
17.7.4 SASS guidelines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 986
17.7.5 Useful tools . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 995
17.8 Using the HTML embed to inject 'widgets' . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 996
18. Password encryption for TCUK website . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 997
19. SEO - GoogleBot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 998
20. UI components & modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1000

6
Architecture and Analysis
CORE Backlog

Key Summary T Created Updated Assignee Reporter

No issues found

Key Summary T Created Updated Assignee Reporter Status

CCORE Batch update JIRA issue statuses (step 64) Mar 10, May 08, Unassigned Tero Pikala IN
-1470 2015 2019 [X] PROGRESS

CCORE Automate creating RFC in JIRA for the release (steps Mar 04, May 08, Michal Tero Pikala IN
-1466 34,35 & 39) 2015 2019 Boruczkowsk [X] PROGRESS
i [X]

CCORE When accessing the scaffolding page of resource with no Feb 17, Feb 17, Rachana None CODE
-1441 data, no error message is shown 2015 2015 Mehta REVIEW

CCORE How do the packages compare? component should not Jan 22, Jan 22, Unassigned None READY
-1390 show checks on package description cells 2015 2015 FOR TEST

CCORE Ooyala Video Player doesn't work on Cars pages Jan 05, Mar 04, Joe Young None TESTING
-1358 2015 2015 [X]

CCORE Create a page to generate release related texts Dec 03, Dec 05, Unassigned Patrick CODE
-1314 2014 2014 Clancey [X] REVIEW

CCORE Rewrite rules for Film channel Nov 27, Jan 20, Unassigned None IN
-1295 2014 2015 PROGRESS

CCORE Add maven release plugin to Ooyala POM file Nov 06, Dec 08, Unassigned None READY
-1223 2014 2014 FOR TEST

CCORE Apply optimisations to caches Oct 15, Apr 14, Frederic None IN
-1162 2014 2015 Dran PROGRESS

CCORE Filter styles by prefix for each component Oct 01, Jul 29, Unassigned Tero Pikala READY
-1104 2014 2016 [X] FOR TEST

10 issues

Key Summary T Created Updated Assignee Reporter

CCORE-1090 OWASP ZAP Penetration testing Sep 23, May 28, Unassigned None
2014 2015

CCORE-1055 Login - Channel selector Sep 05, Oct 07, 2014 Unassigned Jon Attard
2014

CCORE-769 Login - submit malformed email or incorrect password Jun 09, Sep 19, Unassigned Mathias
2014 2014 Douchet

CCORE-768 Submit information Jun 09, Jan 14, 2015 Unassigned Mathias
2014 Douchet

CCORE-748 Login - customer can log out Jun 03, Sep 19, Unassigned Mathias
2014 2014 Douchet

CCORE-747 Login - retain status between Escenic and AEM Jun 03, Jan 14, 2015 Unassigned Mathias
2014 Douchet

7
6 issues

Key Summary T Created Updated Assignee Reporter

CCORE- Auto-linking producing broken tags Aug 18, Aug 18, Unassigned Owen Tuz
1479 2015 2015 [X]

CCORE- Cars - Social plugin in wrong position Jul 13, Jul 13, Unassigned Patrick
1478 2015 2015 Clancey [X]

CCORE- CI - Automated Test Framework - Ooyala Video content finder fails to May 22, May 22, Unassigned None
1477 filter out expired content 2015 2015

CCORE- [SEO] Make the carousel work May 08, May 08, Melinda None
1476 2015 2015 Rogers [X]

CCORE- [SEO] remove blank meta description May 08, May 08, Melinda None
1475 2015 2015 Rogers [X]

CCORE- [SEO] Page title is not correctly hooked up (Film) May 08, May 11, Melinda None
1474 2015 2015 Rogers [X]

CCORE- Node.js backed image filters Apr 15, Apr 15, Unassigned None
1472 2015 2015

CCORE- Finish GitFlow release by merging back to develop and master (steps 66 Mar 10, Mar 20, Unassigned Tero Pikala
1471 - 75) 2015 2015 [X]

CCORE- Plan how to deploy release to PROD without shutting down CMS Mar 10, Mar 13, Unassigned Tero Pikala
1469 2015 2015 [X]

CCORE- Fix Externalizer configuration for DEMO environment Mar 10, Mar 10, Unassigned Tero Pikala
1468 2015 2015 [X]

CCORE- Automate running Chef and release scripts in DEMO environment (step Mar 04, Mar 13, Unassigned Tero Pikala
1465 27) 2015 2015 [X]

CCORE- Automate deployment of release candidate to DEMO environment (steps Mar 04, Mar 20, Unassigned Tero Pikala
1464 16-25) 2015 2015 [X]

CCORE- Plan and implement framework for running release scripts (Groovy etc) Mar 04, Mar 26, Unassigned Tero Pikala
1462 2015 2015 [X]

CCORE- Create Confluence page for the release (step 32 replacement) Mar 04, Mar 19, Unassigned Tero Pikala
1461 2015 2015 [X]

CCORE- Automate generating GitFlow release candidate (steps 5-13) Mar 04, Mar 24, Unassigned Tero Pikala
1459 2015 2015 [X]

CCORE- Automate and improve current AEM release process. Mar 04, Mar 30, Unassigned Tero Pikala
1458 2015 2015 [X]

CCORE- SearchHit.class should be translated to sling model Mar 03, Mar 03, Unassigned Michael
1457 2015 2015 Goszczynski

CCORE- CCORE-1358- Ooyala not working on cars pages in dispatcher Mar 03, Mar 03, Unassigned Joe Young
1456 2015 2015 [X]

CCORE- Remove LeadAssetExtractorUse from list renderers Mar 03, Mar 03, Unassigned Michael
1455 2015 2015 Goszczynski

CCORE- QuoteLocator to look for fallback only when required. Mar 03, Mar 03, Unassigned Michael
1454 2015 2015 Goszczynski

CCORE- List is created twice Mar 03, Mar 03, Unassigned Michael
1453 2015 2015 Goszczynski

CCORE- Refactor Review.class to be specific to cars only, and use different logic Mar 03, Mar 03, Unassigned Michael
1452 on other channels 2015 2015 Goszczynski

CCORE- Code duplication on product renderer. Mar 03, Mar 03, Unassigned Michael
1451 2015 2015 Goszczynski

8
CCORE- Related entities from Nitro are being stored on AEM Feb 27, Mar 04, Unassigned None
1448 2015 2015

CCORE- Extend list component to enable primary tag and entity selection Feb 27, Mar 03, Unassigned Fabio
1446 2015 2015 Abresti-
Safarian

CCORE- Article ID - generation and storage Feb 27, Feb 27, Unassigned None
1445 2015 2015

CCORE- JSONLD issue - JMX console crashes Feb 26, Mar 04, Unassigned None
1444 2015 2015

CCORE- Possible race condition in AddCreatedPropertyJobConsumer class Feb 16, Feb 16, Unassigned Michael
1440 2015 2015 Goszczynski

CCORE- Populating relatedArticle with content in JSONLD Feb 12, Feb 12, Unassigned None
1437 2015 2015

CCORE- Spike: Check whether Vagrant can lookup new basebox version when it Feb 11, Feb 11, Unassigned None
1435 starts 2015 2015

CCORE- Subscription page - package style not displayed Feb 06, Feb 06, Unassigned None
1429 2015 2015

CCORE- Subscription page - FAQ table not displayed if there is only one question Feb 05, Feb 05, Unassigned None
1427 2015 2015

CCORE- Pre poulate the value in nitromultifield from nitro object. Feb 05, Feb 09, Rachana Rachana
1425 2015 2015 Mehta Mehta

CCORE- Subscription page - Android 4.0 doesn't display FAQ correctly Feb 04, Feb 04, Unassigned None
1421 2015 2015

CCORE- Create Test to validate AEM package(s) have deployed correctly to Feb 04, Feb 04, Unassigned Patrick
1420 Master CMS 2015 2015 Clancey [X]

CCORE- Create Bamboo tasks Feb 04, Feb 27, Unassigned Patrick
1419 2015 2015 Clancey [X]

CCORE- Improve release process Feb 04, Feb 27, Unassigned Patrick
1418 2015 2015 Clancey [X]

CCORE- Investigate whether we can use hashing for font urls Feb 02, Feb 02, Unassigned None
1417 2015 2015

CCORE- Author data doesn't appear in Article JSONLD Feb 02, Jul 27, Unassigned None
1414 2015 2015

CCORE- Error updating image metadata in CRX Feb 02, Feb 02, Unassigned None
1413 2015 2015

CCORE- Cannot get session Error when activating topics page Jan 29, Jan 29, Unassigned None
1412 2015 2015

CCORE- Nitro : Ingest images into DAM Jan 22, Feb 04, Frederic None
1388 2015 2015 Dran

CCORE- Author page readjusted when the user selects configuration in the author Jan 15, Jan 15, Unassigned None
1382 component 2015 2015

CCORE- Fix groovy console installation - chef Jan 15, Jan 15, Unassigned None
1381 2015 2015

CCORE- Add time stamp to core.css Jan 15, Jan 15, Unassigned Patrick
1379 2015 2015 Clancey [X]

CCORE- HTML mocks need work e.g. JS not working Jan 09, Jan 09, Unassigned Patrick
1377 2015 2015 Clancey [X]

CCORE- Apply to PROD Jan 08, Jan 08, Unassigned Tero Pikala
1376 2015 2015 [X]

CCORE- Apply to DEMO and sanity check Jan 08, Jan 08, Unassigned Tero Pikala
1375 2015 2015 [X]

CCORE- Apply to TEST environments and run test automation Jan 08, Jan 08, Unassigned Tero Pikala
1374 2015 2015 [X]

9
CCORE- Update Chef recipes to include Hotfix Jan 08, Jan 08, Unassigned Tero Pikala
1373 2015 2015 [X]

Showing 50 out of 202 issues

10
Open Areas of Analysis
To be organised

Autocomplete
Metering
CRX3 Migration
AEM 6.1 Migration
MongoDB/TAR debate follow up + next steps
Third party embeds
Ingest Tool
Extending JSON-LD Selector (images)
Touch UI
Sitemap generator

11
Workshops

12
2014-11-18 Managing Experience Depending on Referrer
Date
Nov 18, 2014

Attendees
Frederic Dran
Fabio Abresti-Safarian
Unknown User (adcockdaniel)
Unknown User (harrisjo)
Unknown User (donovanti)
Unknown User (bartlettc)

Background
The Business would like to enable the serving of different experiences depending on where a user came from.
For example, when a reader navigates to the Jennifer Lawrence page from Fashion,the articles displayed should be
more relevant to Jennifer Lawrence and Fashion rather than display the latest new content about Jennifer Lawrence. The changes expected would be both
Front-end and content based.

Suggested Approach
Append a # tag at the end of all links present within a page indicating the destination page, the name of the referrer page. For example, #fashion
would indicate to the destination page that the referrer was fashion.
The # tag would be parsed and pages dynamically generated either at FE level or at AEM Publish level

Action items
Unknown User (bartlettc) and Unknown User (harrisjo) to clarify what changes are expected on the FE depending on referrer
Unknown User (donovanti), Frederic Dran and Fabio Abresti-Safarian to discuss approach for dealing with #tags to identify referrer

13
2015-01-28 Authoring: UX to API mapping meetings
This page documents the meeting between TMG, Cognifide and Adobe to discuss the Authoring UX. The aim was to map the key functionality to existing
APIs or AEM functionality to identify any gaps or enhancements needed.

Items discussed:

1. Introducing a microservice between AEM and the Authoring UI


2. Article Authoring flow
3. Gallery authoring flow

Introducing a Microservice layer between AEM and the Authoring UI

A separate authoring UI and a microservice were proposed in the Architecture to provide a layer of abstraction between the Authoring UI and AEM. The
key drivers for this are:

AEM's native authoring experience is considered unintuitive and to use it we would be forcing the editorial team to work in an AEM way rather
than what works for them.
Customising the Classic or Touch UI will place added pressure on existing AEM development teams. The volume of customisation will be
extensive and an MVP is unlikely to be completed in 6 sprints
Adobe Touch UI is not yet a mature product
A separate UI that presents all of the existing AEM functionality in a more intuive flow would provide a faster on boarding process, less training
for editorial and ultimately make them more productive
By keeping the Author UI separate from AEM, eventual migration away from AEM would be facilitated should it be necessary in the future. Fairfax
transitioned their print production to AEM without changing the authoring interface from a editorial perspective. Editorial were unaware of the
change and no loss in productivity was noted.
By decoupling we could enable a UI that has access to multiple systems and not just AEM.
A microservice could reduce the number of individual calls made to AEM components. It would also provide a consistent way to interact with the
Authoring UI

The following recommendations were made:

The microservice (to begin with) should be on the same stack as AEM to leverage key AEM features such as Login which we shouldn't look to
replicate in an MVP.
Author UI should not be on the same stack and should not use Sightly
For MVP a Java Servlet will be introduced in AEM that interacts primarily with AEM's API (Sling).

UX mapping- Authoring an Article or Gallery


Key

Green- Out of the box functionality or very little development required

Amber- Some development required but not extensive

14
Red- Investigation/analysis required before size of development is identified

Screen Step Available Delivery options/ considerations Recommendation

Login Login 1
1. As long as the Microservice are hosted on the AEM stack this functionality is OOB. This would avoid cross
domain issues.
2. If the Author UI is not hosted on the AEM stack this could be handled by cookies. Questions to be solved are:
how do we set the cookies? should this be at domain or sub-domain level?

Dashboard Display 1
available 1. Poll Sling API to identify the list of templates. This could be done using query builder
templates 2. Hardcode available set of templates in the UI

Dashboard Create story Post request to Sling (Need to check that there is an updated endpoint for this) and retrieve story template
button

ACTION: verify if AEM needs to create entities at this stage?

Author Open Article AEM needs to be able to know where the article lives before returning the template. Authors to complete Headline and
Article template Path dialog and the full template is then displayed.

Author Add lead asset Use Sling via Servlet to perform basic CRUD operations on images. Servlet approach would help to apply the Manipulation could be
Article from DAM necessary transformations to the image metadata stored in the DAM done at the front end.

ACTION: Need to define the methods for the API calls to the servlet.

Author Article body-


Article Side kick available components to be pulled from AEM
components displayed to be controlled by user permissions (one user group for MVP)
potentially cache the displayed list in the front end

Author Article body- Approach


Article image upload
Use workflows to upload images. Metadata needed per image is Title, Caption, Alt Text, Source, Copyright and,
post MVP, Usage.
Renditions to be done on the fly on the front end while the workflow completes in AEM.
Sling API will accept being provided with the image and crop centre points.
A second API call to Sling is required to check when this has been completed.

This is red because in addition to the decisions requied (below) the front end component is complex in that it allows
users to drop components within the body of the text.

ACTION: need to define how to identify when the image has been loaded into the DAM? Do we poll Sling API or can
this be a workflow that triggers a notification when the image is ready.

ACTION: AEM doesn't import IPTC headers. Need to perform a spike to identify effort/complexity in importing IPTC
headers. Is there a 3rd party public domain component for this?

ACTION: Need to look into Dynamic Image Sizing. Current approach is to use tactical approach used for Film but this
is not scalable.

Author Article body-


Article component Component dialogs can be pulled in from AEM. To avoid unnecessary clutter (data field that editorial are not
dialogs interested in), the dialogs will need to be customised at the back end to define which fields are to be presented
to the front end.
If a component needs a custom UI it will have to be built.
Going forward the data displayed on the dialog can be controlled by user permissions and the available fields list
on the dialog XML

Spell check to be provided by Tansa 4 API calls.

Author Article body- This is a flag that is set at Article level that will be applied to assets within the article so that they don't display
Article sensitive flag advertising

Author Publish When this is set, the article and all assets within it are activated.
Article

Author Upload image See Author Article/Article body-image upload


Gallery

Author Change image Use Sling.


Gallery position in
gallery

Author Publish When this is set, the gallery and all assets within it are activated. Minimum of 1 image per gallery required to publish
Gallery

Items for further investigation (Not required for MVP)

1. Tansa 4 API documentation :https://drive.google.com/a/telegraph.co.uk/folderview?id=0B06_1S_y6OJWSkNLeU1XZnF3Zms&usp=sharing


2. When the microservice is moved from the AEM stack, how should AEM talk to it? The options raised by Cognifide are polling or an open
connection.
3. Sling documentation

15
16
2015-02-06 Testing and Mock Frameworks
Date
Feb 06, 2015

Attendees
Frederic Dran
Unknown User (hoared)
Unknown User (pikalat)
Unknown User (williamsch)
Unknown User (donovanti)
Unknown User (maffiaj)
Unknown User (niedzwiedzt)

Background
wcm.io Testing builds a layer upon Sling Testing to make it easier to mock AEM-specific functionality. It also makes it very easy to load example
content into a mock repository and test various classes against it. It literally just requires placing a JSON file with test content in the classpath
and writing a couple of lines to load it, allowing us to perform actual black-box integration testing. This makes it possible to avoid extensive,
explicit mocking of the objects our classes are dependent on with Powermock, which always results in very tight coupling between the test and
the implementation as opposed to just the expected behaviour. Something along these lines can be observed in the following tests:

1. RelatedEntitiesListAdapterFactoryTest
2. CuratedTileAdapterFactoryTest

My concern is that with the approach taken in these, we get tests that maintain reasonable coverage but break whenever an implementation detail is
changed, even if it does not affect the API at all. It also requires a lot of work to virtually reimplement the class using a set of mocks. This time can be
utilized better.

The library also supports the testing of Sling Models. The developer can simply import content into the mock repository, register the model and test all
of its functionality.

In my experience, this is also the only sensible way to test methods that perform some operations in the repository while having void as the return type
(I tend to avoid this style anyway wherever possible).

Mock processes (see Mocks Process)

Objectives
Decide suitability of the wcm.io framework
Decide on mock process

Discussion items
Time Item Who

10 min Using wcm.io testing framework Unknown User (niedzwiedzt)

10 min Mocks Process Unknown User (williamsch)

Action items
Spike to be created in the Fashion stream to use the USE-API and confirm its suitability for TMG's AEM Projects
Spike to be performed to test the wcm.io and identify how it fares compared to the testing frameworks currently used by TMG (in particular
performance). Results to be brought back to this panel for review and next steps.

17
2015-02-09 Cognifide Slice
Date
Feb 06, 2015

Attendees
Frederic Dran
Unknown User (hoared)
Unknown User (pikalat)
Unknown User (williamsch)
Unknown User (donovanti)
Unknown User (maffiaj)
Unknown User (niedzwiedzt)

Background
Incorporating Slice has been mentioned many a time already over the course of the project by various Cognifide engineers. While this is a library
developed internally by Cognifide, it is an open source (hosted on Github), Apache-licensed project that anyone can contribute to.
The feature most useful to us would be the dependency injection capabilities that Slice introduces by incorporating Google Guice. The telegraph-
component project currently uses no general-purpose dependency injection mechanism. While we can use OSGi dependency injection, there are many
cases, in which exposing a piece of functionality as an OSGi service would be an overkill. In many cases, we may need to inject very application-specific
objects into our classes.
Another massively useful feature is a pre-built set of bindings for AEM, Sling and JCR APIs, which reduces the amount of code needed to obtain objects of
the classes included in this API (some examples being Resource,ResourceResolver, Page, etc.) without the need to explicitly read a resource from a
request and adapt it to any of those. Slice models also don't need explicit adapters. All the developer has to do to use them is to read
The main arguments for using Slice are:

the presence of an actual DI framework with the ability to inject absolutely arbitrary objects (it also comes with AOP capabilities) and create
even complex hierachies in a declarative way that promotes code reuse and loose coupling
no need to write adapters or use the Sling and JCR APIs explicitly (which tends to be verbose) when data is read from the repository
very good knowledge of Slice among Cognifide engineers (both the ones who are just starting work on the new streams and the ones who are
assigned to the older teams)
we can start using the library without breaking existing code, it's a matter of instantiating a Guice injector in the bundle activator and registering
a number of Guice modules
encapsulation - we can make reusable, modular providers within the application, without exposing them to the entire OSGi environment (at
the same time, nothing prevents us from doing so when the behaviour is actually desired)
the ability to use a single DI mechanism to inject classes provided by Slice, custom providers and OSGi (it's possible to create bindings to
OSGi services and inject them using Guice like every other class)

Disadvantages and possible risks include:

other developers would need to learn Slice (new employees are given a day's introduction to the library, which is usually enough to start actual
development, the learning curve is not steep)
a lot of the current codebase does not use Slice. AFAIK, this would introduce the third way of writing code into the same codebase (with the
legacy, AEM 5.6.1 factories, Sling Models and Slice)
Slice is Cognifide specific which can create vendor lock in.
Slice could impact upgrades to next AEM versions

Useful resources:

A blog post on using Slice with Sighty, including a comparison of a Slice model to a Sling model.
On the benefits of Slice and Guice
Documentation for the latest version of Slice

Decision
AEM now provides all of the key features provided by the Slice framework
TMG prefers not to create a dependency with a framework created and maintained by a third party even if the framework is Open Source if AEM
now fulfil the desired functionality

18
Design Decisions Register
Create decision

Decisions
Record important project decisions and communicate them with your team.

Create decision

19
User Access

20
Remote Access
Background
Out of scope
Not about the tools - the subject of this discussion is opening the authoring environment to the Editorial Team
To be handled by Authoring and Workflow Project
Users, Users Management policy
Workflows
Asset storage
Journalism to become mobile - DAM
Live article
Mobile devices allowing content authoring/editing
content
video
images

Initial Approach
(Meeting held 8 January 2014 Lucian Craciun, Frederic Dran, Mark Callaby, Unknown User (glancm), Unknown User (pereiraj))

AEM’s author interface is web based therefore it could be exposed to allow journalists or contributors to logon remotely and create content and/or
take part to a workflow within AEM
In order to author on Escenic, authors must be within the TMG network or connected via the TMG VPN
This is not the preferred position for AEM as using VPN access would provide access to all of the services that can be accessed via VPN.
Therefore only exposing AEM would limit potential unautorised access and activity to AEM instances.
Device authentication is possible but not a viable option:
It would require a specific setup and would make the ability to use any device for authoring impossible.
There are issues with certificates on iOS or Android making the solution unreliable.
The proposed solution would be to expose Chase possibly through connect.telegraph.co.uk and the move of AEM author instance onto a public
ELB.
In terms of authentication, the preferred approach would be to leverage Active Directory and use 2 step authentication. Julian is ok to launch
without 2 steps authentication however, it should be part of the roadmap.
2 steps authentication should however be disabled when access within the TMG network to maintain the simplicity of the editorial workflow.
Penetration testing should be organised and the monthly scan already in place should encompass AEM.
What happens when Active directory is not reachable? A primary and secondary LDAP sources should be specified.
Web support will be available to help testing but requires a couple days notice.

21
User Access and User Management
Film Commercial Beta and Film MVP (December 2014 and January 2015)

Approach
An As-Is tactical approach will be adopted for both Film Commercial beta and Film MVP phases since wider policies will be reviewed and confirmed as
part of the upcoming Authoring and Workflow project (Makers and Managers aka M&Ms). As such:

The process for provisioning and managing users remains unchanged and continues to require a JIRA ticket to be lodged with Web Support /
Web Operations
Access to the AEM Authoring interface remains limited to the TMG Network (internally or via VPN). Whenever VPN is not possible, the existing
workflow involves the submission of a story and/or associated assets to an on-site editor via email or any other method already in place so that he
/she can include on the target platform(s).
There is still no user policy in place:
User roles are therefore limited to the ones already in place (Administrators or Editors)
There isn't a Starters & Leavers process in place. Although the number of AEM users is currently low, this will also need to be
addressed as part of the Authoring and Workflow project
Until the Authoring and Workflow projects define future policies, additional roles may be requested ad-hoc but will be required to be
communicated and reviewed by the TRS forum which occurs weekly every Thursday. The temporary list of users and roles is to be maintained in
this document below.
The list of users and associated roles required for a channel is to be defined, maintained and approved by the Product Manager in charge of the
channel for which users are being created. Due to security concerns until the wider user policy is defined, a strict Account creation policy should
be followed whereby Accounts should only be provisioned for the users that strictly require them and permissions limited to the activities required
to be conducted. For logging and tracking purposes, credentials must NOT be shared. Therefore unique logons should be created for each
individual requiring access to the system.
Web Support is to maintain the list of AEM users until a wider user policy is put in place.

Users and Permission Matrix


Editor Ad Operations Admin Super User Administrator

Create content Yes No Yes Yes Yes

Edit section pages Yes No Yes Yes Yes

Edit config sections No No Yes (for channel) Yes Yes

Edit menus No No No No Yes

Create new sections No No Yes (for channel) Yes Yes

Create users No No No No Yes

Edit Metatags Yes Yes Yes Yes Yes

General User Policy


A set of domains will be defined
User Access will be restricted according to a user's domain
Restrictions will be applied at component or page level by applying different read and write to groups

22
Search

23
Front-End Search
Date
Nov 24, 2014

Attendees
Frederic Dran
Unknown User (mocchettir)
Giuseppe Saltini

Approach

Film
For Film MVP, search will be performed across content residing on AEM only and will leverage tags. A customer facing form will be built in AEM in order to
enable users to search for content (find film feature). The search will be performed against the tags applied to the AEM content.

Monza and Film retro-fit


2 searches are fired in parallel while a user types within a search box:

1. Full Text Search


a. A common words database would be setup and maintained using Elasticsearch
b. As words are typed, an AJAX call would be made to Elasticsearch. When words are matched (including misspells - search against letters
entered whatever order), a full text search would be fired via the discovery API to OTSN
c. All search results returned would then be indexed by Elasticsearch for caching purpose (future searches)
2. Graph Search
a. As words are typed, an AJAX call would be made to the discovery API for matching entities (with REDIS hit first)
b. Search would be on tags only (where titles, actors are tags)

Dependencies
1. To date, no forms have been implemented on any of the AEM projects. Therefore stories around form validation, sanitisation (to prevent XSS)
and other form security measures + tests will be required to be introduced in the CORE backlog.
2. A search result page must be created. Advertising behaviour for search results should be identified.

Action items
Frederic Dran to present this early approach to TRS for initial feedback and discuss next steps

24
Back-end Search
To be validated

Search is needed for 3 day to day functions in the Authoring tool:

Search reason Criteria to be Expected outcome Search in


used for search what?

Finding/ surfacing articles that an editor Headline Full text search on headline, standfirst, author, keywords and section. Content API
wants to work on
Standfirst Search also allows for 'And' and 'Excluding'. I.e. search for' Bryony Gordon' as
Author but excluding keywords of 'Parenting'
Author

Date (created,
published, modified)

Keywords

Section

Finding the correct keyword and section Auto complete i.e. type 3 letters and see what tags match this. User can keep AEM repository
tags to apply to an article tying and the result set reduces. (Phase 1)

Content API
(Phase 2)

Finding an article to promote on Page Headline Full text search on headline, standfirst, author, keywords and section. Content API
Manager
Standfirst Search also allows for 'And' and 'Excluding'. I.e. search for' Bryony Gordon' as
Author but excluding keywords of 'Parenting'
Author

Date (created,
published, modified)

Keywords

Section

25
Galleries and Entity handling
Current state of AEM- Core API integration on Production

AEM->Core API integration in progress


Core API-> AEM integration exists and is working
All entity creation and maintenance is being done manually and does not come from Core API.
Galleries

Galleries are not physical assets but are composites made up of a collection of other assests. They may be reused in many articles and in other CMSs.
For these reasons we will treat Galleries as entities much in the same way that Films are handled in AEM.
Set up activities required are:

1. Create a node under Entities for 'Gallery'


2. Create a Entity definition page for the 'Gallery' class defining the following properties:
a. Name (headline)
b. Caption
c. Keywords
3. Create a node under 'Pages'
4. Create a node per channel under 'Pages' (first one will be Fashion)
5. Create a node under Pages->Fashion for galleries (I.e. Pages->Fashion->Gallery)

let's review a bit this structure... I'm not sure in this way is correct

When an author creates a Gallery article and a subsequent gallery to populate it the following will happen:

1. A node under 'Gallery' entity for that gallery is created


2. A node under Pages->Fashion->Gallery is created for the Gallery article

When the Gallery article is Published the following happens: (reference: NOS-1654 - JSON-LD : Push pages to Core API (Nitro) DONE )

1. a notification is sent to Core API stating the gallery article ID and the gallery entity ID that have been created
2. Core API makes a GET request to AEM to retrieve the data

When search in the Authoring tool is configured to talk to Core API then a further two steps occur:
3. Core API sends a notification to AEM indicating the successful POST operation
4. The entity node and the gallery page node are deleted from AEM.

Entity handling for MVP

The Authoring tool is configured (for MVP) to search the node structure withing AEM for entities
A spreadsheet loading mechanism will be built so that a 2 column list (Type, Label) can be loaded into AEM
This list contains all the entities that need to be loaded into AEM.
The 'type' defines the class the entity belongs to while 'label' provides the name of the entity (e.g. Type= Model, Label= Kate Moss)
Should any disambiguation be needed this will be handled manually e.g. Birmingham (US) vs. Birmingham (UK).
As the list is loaded the following occurs:
the list is parsed and the values in Type are matched against the nodes immediately below Entity. Any new values will trigger a new
node directly under Entity. I.e. If the list contains a value for type= Motorbikes and withing the Entity none there is no class for
Motorbikes, a new node is created with this name. An entity definition page for Motorbikes is also created with a single property of 'Label'
(string).
the list is parsed a second time where the matching the values listed under each Type against the corresponding entities under a class
within the Entity node.Any new values trigger a creation of a new node under the correct entity class I.e. If the file contains Type= Cars,
Label= Fiat Punto and there is no entity named Fiat Punto under the entity class of Cars in AEM then a new node under Cars is created
in AEM called Fiat Punto.
Adding new entities: To add a new entity a row in blank uploader template is added and loaded into AEM
Modifying existing entities:

To modify an entity a user will need to log into AEM and browse the Entity node structure and edit the node they are interested
in
A change to an entity will be reflected wherever there is a refernce to that entity. I.e. If a user changed Kate Moss to Catherine
Moss then any article that had Kate Moss as keyword annotated to it would now have Catherine Moss.
Articles in Draft would not reflect the change until the user selected to publish.
Clean up activities

Before Cars, Film and Best can be migrated to the Authoring tool all keywords that are currently being stored in the tag store
must be migrated to the entity node structure. E.g. buggy friendly will need to be made an entity. A Type or class for these
values will be needed.

Post MVP
Post MVP an integration will be made between the Authoring Tool and the Core API so that entities will be managed in the Data Hub and surfaced to the
authoring tool via the Core API.
All existing AEM entities will need to be migrated to the Data Hub.

26
Login and Bastion
The following topics will be part of deep dive sessions

Customer Login
Login
Social Login
Subscription
User activity

Administration Login

System Management
User Authentication
Google Authentication (OAuth)

Internal Login and Remote Access


Content authoring
Workflows
Live Article

Security
HTTPS
Use cases are limited to the subscription and account management journeys (including Login). Because these experiences are highly customised
to the user do we really need to go through Akamai or CDN?
Approach would be to use the SSL on Dispatcher for Wayfarer and Bastion part of the experience that would require it
What is the cost for installing SSL with Akamai? is it based on certificate or traffic or both?
Problem with serving pages that are mixed SSL and non SSL (Ajax)
Either everything is under SSL (cost associated)
we redirect users to a separate dedicated sub-domain
this may not solve cross domain issues

Frederic Dran to research Akamai costs


Frederic Dran to identify options for security for login, account management and subscription

27
Changes to Entity Management
Approach:

Entities are not to be stored in AEM


Tags currently used in Cars either need to be entities or entity properties (e.g. buggy friendly)

User needs:

Need multi entity tagging of articles


Need multi presentation tag tagging for articles (each one maps to a hub page)
Need to customise lists to enable selection of presentation tags, entities and entity properties

Tasks

Task description Who?

Domain modelling for Fashion, Film, Beauty and Best Fabio C/Data team

Migrate AEM entities to Flat entity structure i.e. CSV file (includes mapping AEM tags to entity properties)

Do we need cars/best?

Also new channels (Fashion, Beauty, Books, Theatre) will be introducing new models within AEM that are
already technical debt

Specify Methods for entity interactions:

Search (GET)
GET properties

Do we need to restrict by domain?

Stand up Entity API

Integrate Entity API with Authoring, CQ and Flat entity structure

Update CQ page properties to point to Entity API and hold entity URIs instead of JCR

Update CQ page properties to allow multiple entity URIs

Agree whether entity URIs are also defined at component level and what inheritance rules (if any) can AEM Architecture team
apply

Change List components to allow authors to specify: AEM development

Hub pages (i.e. Cars)


Entities (i.e. Maserati Quattroporte)
Entity properties (i.e. Good to drive)

I think there is a lot more logic for Lists required based on Dan Adcocks model of different types of pages
(RS)

Entity update management (manual) Data team via defined process agreed
with Editorial

Entity update GUI Data team

Investigate caching approach in AEM AEM architecture team

Solution Approach diagram

28
29
Asynchronous calls from the Authoring tool - Draft
Goals for Asynchronous Messaging
Providing up to date information in the Authoring information without full page refresh
Providing timely feedback on user initiated actions (success and error scenarios)
Preventing overloading of AEM (this is not necessarily required, see below section on AEM Author Load)

Use cases
1. User initiated actions that require feedback

Publish
User publishes an article in Authoring UI
Publish message sent to AEM
AEM publishes page
Article status is updated in Authoring UI
Unpublish
Save
Upload Image
User uploads an image in Authoring UI
Image is uploaded to AEM
AEM Workflow for processing images runs
Renditions generated
IPTC metadata extracted
Image editing screen updates with IPTC metadata in Authoring UI
NOTE: Potentially there will be other interactions that will require async messaging

Pic below shows the header of the Authoring tool. The Status box on the right will change based on the action of the user - ie. Publish, UnPublish etc

2. Server initiated actions:

Conveying the up-to-date status of multiple articles on the finder page


User 1 is viewing the finder screen in Authoring UI
User 2 publishes an article (currently shown on User 1’s screen) in Authoring UI
Publish message sent to AEM
AEM publishes page
Article status is updated on User 2’s screen in Authoring UI (same as case 1)
Article status is updated on User 1’s finder screen in Authoring UI

Pic below shows the Finder page of the Authoring tool. Initially the status on the right for each article should update based on the current
status. (Potentially we may want to update all information shown about each article)

30
History
An initial 3 day investigation into using ActiveMQ to provide this functionality was undertaken by the Authoring Dev team.

These are their findings: ActiveMQ asyncronous communication - research

TRS (28/05/2015)
Presented the challenges with Asynchronous Messaging at the TRS and discussed the following:

Queueing mechanisms
Potential learnings from Google Docs APIs
In order to meet timelines for first use of Authoring we need to come up with a basic solution that meets the needs
Authoring tool is intended only for Web content
Load on AEM Author instance - see AEM Author Load section below
Reducing the traffic for this service, potentially not handling the Save events through the same method as status updates
The suggested use of the MVVM pattern (http://en.wikipedia.org/wiki/Model_View_ViewModel)

Proposed Approach

31
The proposed solution implements the MVVM pattern. Potentially through using Knockout.js http://knockoutjs.com/

(Work in progress)

AEM Author Load


Adobe say their Author instance should be able to support many concurrent users
Rule of thumb formula from Adobe (for CRX2) is; num. conc. users / 30 = num. CPU cores required
CRX3 should be better
As we use quad core machines we should be able to support 120 concurrent users (4x30) - this means that we could handle 120 users
all performing an operation at the same time.
Caveat: this does not apply to image uploading - however there are plans to have a dedicated authoring instance to handle this

Below this point is OLD (saving for history)

N.B. The Authoring Servlet must be designed with a Tolerant Reader pattern in mind so that changes in the Sling API can be handled without causing the
servlet to break.

32
33
Owner and Delivery Platforms
Current

Proposed

34
35
Dates in AEM
AEM System Dates
These dates come built in to AEM.

Date field How/when populated Used for

Modified Date This date is auto updated whenever the page is modified, regardless of its publish status Internal only

(NOTE: activating or deactivating does not count as a modification)

Published This date is auto updated when the page is published (activated or deactivated) Internal only
Date

Activate Date This date is set manually by an editor as the time in the future when the page will be published (activated) Implementing
embargoes

Deactivate This date is set manually by an editor as the time in the future when the page will be unpublished Implementing
Date (deactivated) embargoes

TMG Defined Date


The following date property should be present for ALL page types.

Date field How/when populated Used for

Published This date is auto updated when the page is first published (activated) Ordering
Date Overri Lists
de Also it can then be manually edited by an editor
Display date
Q: If the author sets a Publication Date Override before the first activation what should happen? Should it keep the for the article
manual setting or take on the current datetime?

Q: If someone is 'refreshing' an article by updating its date and they want this to happen out-of-hours then they will need
to remember to manually update the Publication Date Override when setting up the embargo. Is this OK?

36
Sitemaps
Yet to be fully discussed but intention is to use the Content API to generate Sitemaps

Full requirements to come.

37
RSS
Intention is to use the Content API to generate RSS feeds

Full requirements to come.

38
Image paths in AEM DAM
Below is the agreed approach for image paths in the AEM DAM

/{channel}/{year}/{month}/{day}/{image-name}

Where...

{channel} = the name of AEM channel (the same as the top level URL for this channel) eg. fashion, books, football etc

{year} = the current year eg. 2015, 2016 etc

{month} = the current month eg. 01 to 12

{day} = the current day eg. 01 to 31

{image-name} = the filename of the image

eg.

/books/2015/06/24/harry-potter.jpg

39
Cluster Pages
Agreed approach to implementation of Cluster pages
Definitions:
Cluster pages

Cluster pages are pages that pull content from other channels and never have articles directly beneath them
The only current examples of these are:
Sport
News
Lifestyle
Culture
Their URLs need to be at the top level of the site ie. /sport or /news
A Cluster may or may not correspond to a Business Segment (see below)
A page will need to know of relation to a Cluster in order to provide a link back to it (ie. Football links back to Sport)

Business Segments

Not necessarily the same as a Cluster


A Business Segment is an area of the site grouped together for Ad delivery and Analytics, and potentially other, purposes
For example we currently have the concept of a Lifestyle Business Segment in Advertising that means we can book ads across all the following
Channels in one action:
Lifestyle
Men
Women
Gardening
Food and Drink
History
Which channels are apportioned to which Business segment should be able to change
Topic pages may start assigned to a Topics segment but could be moved to another

Description of approach (agreed in TRS 02/07/15):


Clusters pages will be created in the JCR separate from the channels under a top level folder named "/content/telegraph/clusters"
we will add a rewrite rule to exclude the /clusters/ folder from the URL
we will also present another field in page properties that enables a channel to choose one Cluster page from beneath the /clusters folder for
Navigation purposes
The Meta Tags will be defined manually for each Cluster
Exact Meta tags to be confirmed
A new property will be added to the page properties of the Hub, Cluster and Topic templates called "Business Segment"
This will allow the user to choose from a defined list of segments (to be agreed by Analytics/Advertising)
The property will inherit down to all descendant pages - but could be overridden further down the tree
eg. /content/telegraph/topics will be set to segment=topics
but /content/telegraph/topics/people/t/tom-cruise may be set to segment=culture
The property will be exposed in a new Meta tag on the page so that it can be passed to Analytics/Advertising
We will restrict the creation of pages beneath the /clusters folder to only one level so no pages can be created under a particular cluster ie.
/clusters/sport/page/ will not be possible
This will have to be done in each Template content.xml file using the allowedPath property
Exact regex to be defined

40
Open Questions:

41
Live Articles
This page will describe the approach for Basic and Target Live articles on AEM

42
Basic Live Articles
This page describes the basic live article functionality being built for initial use on Sport and other channels

Approach Diagram

NOTE: Yellow items are to be build in this approach

The following work is to be done:

Add a new Live checkbox to Article2 page Properties


When checked this enables
A bar indicating that this article is Live (with the ability to pause/restart the updates)
A new Live Stream wrapper component in the page, in which Editors can add new Live Post Components

In the Live Stream component properties the editor can choose the Update Frequency from a predefined list (ie. 30 seconds, 1
minute, 90 seconds etc)
In the Live Post component the Editor can specify

The Timestamp of the post


The Headline of the post
The Body of the Post will be implemented using the existing Inline Content component
In the future we could add styling options (ie. Goal, Red Card, Gold Medal etc)
A Live icon next to the article on any section pages/lists in which this article appears
On first page load the most up-to-date content will be loaded

the time stamp of the latest update will be written in the page source
The periodic polling of the contents of the Live Stream wrapper component

The first call will request a selector view of the component to get the timestamp of the last update in the Live Stream
If this update is more recent than the timestamp rendered with the page then another call will be made utilising the jcr:content
URL of the component

TBC: this URL will be accessible from page? No, but we need to work out how to open this up or rewrite the URL
TBC: we need to confirm that we can flush the cached copy of the component URL from the dispatcher using Adobes
new Cache invalidation strategy
ESI/SSI/SDI will not be required for this as the page will have to be reactivated as a whole which will invalidate the cache for the
whole page and all its selectors
We will set the Akamai cache header to decrease the amount of time that Akamai caches the whole page and the component
fragment that contains all the post content

ie. for 30 seconds: response.setHeader("Edge-Control","max-age=30");


The article will not be eligible for Syndication whilst Live
The normal content area will still be available for editing but will not dynamically update for the user (neither will the headline or other
components on the page)
When the Live checkbox is unchecked

the Live Stream and Posts will still be displayed but will no longer be editable
the page will no longer update dynamically
the page will no longer show as Live in section pages

43
the page will be eligible for Syndication again

44
Target Live Articles
This page describes the Target Architecture for Live Articles on AEM

https://docs.google.com/presentation/d/1wJPyUcru0fn7pKyQWTxJnjVSz7mZ-W1TsVXHmH-C2iA/edit#slide=id.g8e5d3cb43_2183

45
Primary Topic options
Option 1: Store the tag in the JCR properties of the page (RECOMMENDED)

Create a new property for articles (& galleries?) called primaryTopic


This property will hold a path to a tag in the JCR
In the page template for the breadcrumb in the nav, look up the tag in the tags mapping page to find the referenced page, use this page to create
a link using the referenced pages headline property as the text for the link.
In the list view of the page, look up the tag in the tags mapping page to find the referenced page, use this page to create a link using the
referenced pages headline property as the text for the link
In Authoring in the tags area allow a user to choose one as a primary topic (by starring it?), when this is written to the JCR the path to the starred
tag will be written in to the primaryTopic field.
In Authoring when a page is loaded the primaryTopic field should be checked for a value so that when the tag is rendered in the tags area it can
be shown as starred

Pros/Cons

Logic to look up URL of topic from mapping page is in template code so slows page compile (already done this way for list of tags)
Primary Topic URL would not be visible to API (the API doesn't resolve tags to page locations)
Not easy to add in CQ Authoring (no auto complete/validation unless we build a new control), possible manual errors
Easier to implement through Authoring - Starring a Tag causes it to be written to this property and when loading page in Authoring should be easy
to check this field and display the tag as starred
Changing the mapping on the mapping page will eventually change it on all pages (assuming the breadcrumb and lists are SSI'd)

Option 2: Store the Topic page path in the JCR properties of the page

Create a new property for articles (& galleries?) called primaryTopic


This property will hold a path to a page in the JCR
In the page template for the breadcrumb in the nav, when this property has a value, use it to create a link using the referenced pages headline
property as the text.
In the list view of the page, when this property has a value, create a link using the referenced pages headline property as the text
In Authoring in the tags area allow a user to choose one as a primaryTopic, on save look up this Tag in the Tags Mapping page and write the
corresponding page path to the primaryTopic property.
In Authoring when a page is loaded read the primaryTopic field and look up the page in the tags mapping page and find the corresponding Tag,
show this Tag as starred when it is rendered in the tags area

Pros/Cons

Logic to look up URL of topic from mapping page is executed on save so page compile is faster
Would not store anything if there was no mapping at point of save - strange user experience in Authoring - reopening Article would not show a
starred tag
Primary Topic URL could be exposed through API
Reverse lookup on Mapping page required when loading page in Authoring - more complex
Changing the mapping on the mapping page would not update any pages (even if breadcrumb and lists are SSI'd) - would require a re-publish of
the article page

Option 3: Do a mixture of both 1 and 2, store both the Tag and the mapped Path to the topic page in the JCR properties of the page. Looks up
the mapping and rewrites the topic page jcr path on page save/publish.

Create two properties called primaryTag and primaryTopic


primaryTag holds a path to an AEM Tag
primaryTopic holds a path to a Topic page
In the page template for the breadcrumb in the nav, when the primaryTopic has a value, use it to create a link using the referenced pages
headline property as the text.
In the list view of the page, when the primaryTopic property has a value, create a link using the referenced pages headline property as the text
In Authoring in the tags area allow a user to choose one as a primary topic (by starring it?), when this is written to the JCR the path to the starred
tag will be written in to the primaryTag field. On save look up this Tag on the tags mapping page and write the corresponding page path to the
primaryTopic field
In Authoring when a page is loaded the primaryTag field should be checked for a value so that when the tag is rendered in the tags area it can be
shown as starred

Pros/Cons

Logic to look up URL of topic from mapping page is executed on save so page compile is faster
Both could be exposed through the API
Replicates the mapping held on the mapping page - so wouldn't update on the page if the mapping was changed until re-save/publish
Could be confusing when editing in CQ - perhaps make the primaryTopic uneditable and just populate it on save from the tag
No auto complete/validation for Tag field (unless we build a new control)
Changing the mapping on the mapping page would not update the primaryTopic link in the page properties and therefore the API - unless the
page was re-published - this could cause a discrepancy between the page and the API
Changing the mapping on the mapping page will eventually change it on all pages (assuming the breadcrumb and lists are SSI'd)

--

46
Richard Spence > Solution Architect, Technology, Telegraph Media Group Limited
Tel > 020 7931 2271
Email > richard.spence@telegraph.co.uk

47
Editorial Order for Hub pages
Update (from 8th Feb 2016) - Chosen approach
We have chosen to split the requirements in to two phases.

Phase 1 = deliver the editorial order (from curated lists on a section page) - see AEM-3665

This will involve adding some markup to the links generated by manual list components, and also firing events for parent pages of snippets when snippets
are edited

Phase 2 = deliver any overridden headlines, images and other fields - see AEM-4320

This will involve moving the override content from the Curated List component to the Article itself. See here for specification: (add link here)

Update (from 1st Feb 2016) - Options after further analysis


1. Enforce the order in the JCR so that cview.xml shows Editorial Order (snippet references need to be followed)
a. API does the work to follow snippets
b. Work is done in the cview.xml to follow snippet references
c. A new service is written to expose the editorial order based on the ordered JCR
2. Add a property to container areas (parsys & splitter slots) to indicate their logical order
a. API does the work to order the nodes and follow snippets
b. Work is done in the cview.xml to order the nodes and follow snippet references
c. A new service is written to expose the editorial order based on the JCR with order indices
3. Parse the editorial order from the HTML

State (as of 8th Dec 2015)


The ability to retrieve an editorial order for any given section page on the AEM website is required for a number of reasons:

1. To provide an editorial order of articles to the Content API which can then be used by any consumer to present that order of articles on any
platform. Currently the editorial order in the content API is only consumed by the Live Mobile App, but switching the major channels to AEM will
mean it loses any editorial order.
2. Lists on the website are required to be powered from the editorial order on other sections. For example the Sport section on Portal should be
powered by the manually curated list on the Sport cluster page. This reduces the amount of manual curation required.

The main goal here is to be able to provide a list of all content in all curated lists on any single page. Automated lists will not be included in the Editorial
order. The content should be in the logical order of editorial prominence that they appear on the page. For example the hero block on Fashion currently
has 3 stories displayed left to right however the most prominent is the middle one, so this should appear at the top of the editorial order list.

In order to achieve this we need a consistent JCR structure for all curated lists. There are currently two types of curated list which produce a slightly
different JCR structure.

1. The Hero Block component


2. The Curated list component

One major consideration is that each item or tile in a curated list can be either a reference to a another page or manually added including a custom
Headline, Link, Image and Text. Manual tiles need to be included in the editorial order.

Hero Block
You can see an example on the Fashion homepage here (I've included the xml in this email below as well).
http://pub1.aem-demo.awspreprod.telegraph.co.uk:4503/fashion.xml
You'll notice that the three items in the list are referenced in the <tile_left>, <tile_middle> and <tile_right> nodes. This component can only take 3
items. You'll also notice that there are two types of item in the list.

The <tile_left> node describes a an item that simply refers to another page in the JCR, this location is held in the pagePath attribute. There is an Image
node here but it has no fileReference attribute

The <tile_centre> node describes a completely manually entered item where the Title and URL are explicitly specified in the attributes . (Note: the URL could
point at something offsite - we need to decide if these types of items should be included in the editorial order)

48
The <tile_right> node is just like the first item where it refers to another page in the JCR, however the image is specified here. It appears if the referenced
page is a gallery then it requires an image to be set here.

Hero block XML

<heroblock jcr:primaryType="nt:unstructured" componentHeading="fashion" jcr:created="2015-06-16T17:26:55.483+01:


00" jcr:createdBy="chaumooy" jcr:lastModified="2015-06-16T17:27:02.027+01:00"jcr:lastModifiedBy="chaumooy"
sling:resourceType="telegraph/core/commons/components/heroBlock" theme="version-1" uniqueId="TMG-ID-HeroBlock">

<listpar jcr:primaryType="nt:unstructured" sling:resourceType="telegraph/core/commons/components


/curatedList/curatedListParsys">

<tile_left jcr:primaryType="nt:unstructured" date="2015-01-01T00:00:00.000Z" jcr:lastModified="


2015-11-15T11:29:02.429Z" jcr:lastModifiedBy="newbolda" pagePath="/content/telegraph/fashion/style/how-to-find-
the-perfect-tweed-jacket" sling:resourceType="telegraph/core/commons/components/curatedList/tile" uniqueId="TMG-
ID-CuratedListTile">
<image jcr:primaryType="nt:unstructured" jcr:lastModified="2015-11-15T11:29:
02.429Z" jcr:lastModifiedBy="newbolda"/>
</tile_left>

<tile_centre jcr:primaryType="nt:unstructured" date="2015-01-01T00:00:00.000Z" jcr:


lastModified="2015-11-15T11:36:56.693Z" jcr:lastModifiedBy="newbolda" sling:resourceType="telegraph/core/commons
/components/curatedList/tile" title="Victoria Beckham on her fashion empire" uniqueId="TMG-ID-CuratedListTile"
url="/content/telegraph/fashion/people/victoria-beckham-interview-designer-talks-fashion-and-family">
<image jcr:primaryType="nt:unstructured" fileReference="/content/dam/fashion/NOV/Nov10
beckham/victoria-beckham-portrait-n.jpg" jcr:lastModified="2015-11-15T11:36:56.693Z"jcr:lastModifiedBy="
newbolda"/>
</tile_centre>

<tile_right jcr:primaryType="nt:unstructured" date="2015-01-01T00:00:00.000Z" jcr:lastModified="


2015-11-15T11:34:17.611Z" jcr:lastModifiedBy="newbolda" pagePath="/content/telegraph/fashion/shopping/what-to-
wear-to-a-winter-wedding" sling:resourceType="telegraph/core/commons/components/curatedList/tile" uniqueId="TMG-
ID-CuratedListTile">
<image jcr:primaryType="nt:unstructured" fileReference="/content/dam/fashion/NOV/nov12
/zara-dress.jpg" jcr:lastModified="2015-11-15T11:34:17.611Z" jcr:lastModifiedBy="newbolda"/>
</tile_right>

</listpar>

</heroblock>

Curated List

This is the other component that can be used to place a manual article list on a page. This component allows many items.It is very similar to the Hero
block above. You can see an example here on the Film home page (as before I have included the key part of the XML here)
http://pub1.aem-demo.awspreprod.telegraph.co.uk:4503/film.xml

There are actually multiple curated lists in this page but its the one that doesn't sit inside the footer that we are interested in.

You'll notice that the tiles inside a curated list are numbered in this component for example <tile_1>, and that they are not listed in numerical order - they
are are however listed in the order that they appear on the website - ie the editorial order. The tiles are the same kind of formats as above.

Unfortunately if multiple lists are included in the page it doesn't appear that they are shown in the editorial order - the template must be including them by
name at certain points in the page. This would prove difficult to extract an editorial order from as the order in the XML is ok within each list but not for the
lists themselves.

Curated List XML

<curatedlist jcr:primaryType="nt:unstructured" jcr:lastModified="2015-07-23T15:52:59.323+01:00" jcr:


lastModifiedBy="rogersm"sling:resourceType="telegraph/core/commons/components/curatedList" uniqueId="TMG-ID-
CuratedList">

<listpar jcr:primaryType="nt:unstructured" sling:resourceType="telegraph/core/commons/components

49
/curatedList/curatedListParsys">

<tile_1 jcr:primaryType="nt:unstructured" jcr:created="2015-07-24T16:40:22.887+01:00" jcr:


createdBy="rogersm" jcr:lastModified="2015-08-13T16:57:16.310+01:00"jcr:lastModifiedBy="harrodh" pagePath="
/content/telegraph/film/star-wars-the-force-awakens" sling:resourceType="telegraph/core/commons/components
/curatedList/tile" uniqueId="TMG-ID-CuratedListTile">
<image jcr:primaryType="nt:unstructured" jcr:lastModified="2015-08-13T16:57:16.310+01:
00" jcr:lastModifiedBy="harrodh"/>
</tile_1>

<tile_7 jcr:primaryType="nt:unstructured" jcr:created="2015-12-07T10:29:47.257Z" jcr:createdBy="


admin" jcr:lastModified="2015-12-07T10:30:18.286Z" jcr:lastModifiedBy="admin" pagePath="/content/telegraph/film
/bridge-of-spies" sling:resourceType="telegraph/core/commons/components/curatedList/tile" uniqueId="TMG-ID-
CuratedListTile">
<image jcr:primaryType="nt:unstructured" jcr:lastModified="2015-12-07T10:30:18.286Z"
jcr:lastModifiedBy="admin"/>
</tile_7>

<tile_2 jcr:primaryType="nt:unstructured" jcr:created="2015-07-24T16:48:04.167+01:00" jcr:


createdBy="khamashtal" jcr:lastModified="2015-08-13T16:58:07.161+01:00"jcr:lastModifiedBy="harrodh" pagePath="
/content/telegraph/film/hateful-eight" sling:resourceType="telegraph/core/commons/components/curatedList/tile"
uniqueId="TMG-ID-CuratedListTile">
<image jcr:primaryType="nt:unstructured" jcr:lastModified="2015-08-13T16:58:07.161+01:
00" jcr:lastModifiedBy="harrodh"/>
</tile_2>

<tile_6 jcr:primaryType="nt:unstructured" jcr:created="2015-11-24T14:01:32.631Z" jcr:createdBy="


admin" jcr:lastModified="2015-11-24T14:01:32.631Z" jcr:lastModifiedBy="admin" pagePath="/content/telegraph/film
/james-bond-spectre" sling:resourceType="telegraph/core/commons/components/curatedList/tile" uniqueId="TMG-ID-
CuratedListTile">
<image jcr:primaryType="nt:unstructured" jcr:lastModified="2015-08-13T16:56:43.484+01:
00" jcr:lastModifiedBy="harrodh"/>
</tile_6>

<tile_4 jcr:primaryType="nt:unstructured" jcr:created="2015-07-24T16:41:46.032+01:00" jcr:


createdBy="rogersm" jcr:lastModified="2015-11-23T09:28:24.745Z"jcr:lastModifiedBy="khamashtal" pagePath="
/content/telegraph/film/x-men-the-new-mutants" sling:resourceType="telegraph/core/commons/components/curatedList
/tile" uniqueId="TMG-ID-CuratedListTile">
<image jcr:primaryType="nt:unstructured" jcr:lastModified="2015-11-23T09:28:24.745Z"
jcr:lastModifiedBy="khamashtal"/>
</tile_4>

<tile_0 jcr:primaryType="nt:unstructured" jcr:created="2015-07-24T16:47:23.626+01:00" jcr:


createdBy="khamashtal" jcr:lastModified="2015-10-29T13:33:02.032Z"jcr:lastModifiedBy="jonesr" pagePath="/content
/telegraph/film/carol" sling:resourceType="telegraph/core/commons/components/curatedList/tile" uniqueId="TMG-ID-
CuratedListTile">
<image jcr:primaryType="nt:unstructured" jcr:lastModified="2015-10-29T13:33:02.032Z"
jcr:lastModifiedBy="jonesr"/>
</tile_0>

<tile_3 jcr:primaryType="nt:unstructured" jcr:created="2015-11-30T08:54:22.247Z" jcr:createdBy="


admin" jcr:lastModified="2015-11-30T08:55:20.181Z" jcr:lastModifiedBy="admin" pagePath="/content/telegraph/film
/blackfish" sling:resourceType="telegraph/core/commons/components/curatedList/tile" title="blackfish" uniqueId="
TMG-ID-CuratedListTile">
<image jcr:primaryType="nt:unstructured" jcr:lastModified="2015-11-30T08:55:20.181Z"
jcr:lastModifiedBy="admin"/>
</tile_3>

<tile_5 jcr:primaryType="nt:unstructured" jcr:created="2015-11-30T14:56:36.419Z" jcr:createdBy="


admin" jcr:lastModified="2015-11-30T14:56:58.267Z" jcr:lastModifiedBy="admin" pagePath="/content/telegraph/film
/under-milk-wood" sling:resourceType="telegraph/core/commons/components/curatedList/tile" uniqueId="TMG-ID-
CuratedListTile">
<image jcr:primaryType="nt:unstructured" jcr:lastModified="2015-11-30T14:56:58.267Z"
jcr:lastModifiedBy="admin"/>
</tile_5>

</listpar>

</curatedlist>

50
Proposal (for Q1 2016)
Proposed alterations to JCR and XML format for curated lists and hero block components.

The recommendation is to alter the cview selector of pages to include the following xml for each tile in a list that is manually curated (currently hero block
and curated list).

New tile XML markup

<tile_centre jcr:primaryType="nt:unstructured" date="2015-01-01T00:00:00.000Z" jcr:lastModified="2015-11-15T11:


36:56.693Z" jcr:lastModifiedBy="newbolda" sling:resourceType="telegraph/core/commons/components/curatedList
/tile" uniqueId="TMG-ID-CuratedListTile">
<editorialOrderItem title="Victoria Beckham on her fashion empire" url="/content/telegraph/fashion
/people/victoria-beckham-interview-designer-talks-fashion-and-family">
<image jcr:primaryType="nt:unstructured" fileReference="/content/dam/fashion/NOV/Nov10 beckham
/victoria-beckham-portrait-n.jpg" jcr:lastModified="2015-11-15T11:36:56.693Z"jcr:lastModifiedBy="newbolda"/>
</editorialOrderItem>
</tile_centre>

OR

<tile_left jcr:primaryType="nt:unstructured" date="2015-01-01T00:00:00.000Z" jcr:lastModified="2015-11-15T11:29:


02.429Z" jcr:lastModifiedBy="newbolda" sling:resourceType="telegraph/core/commons/components/curatedList/tile"
uniqueId="TMG-ID-CuratedListTile">
<editorialOrderItem pagePath="/content/telegraph/fashion/style/how-to-find-the-perfect-tweed-jacket">
<image jcr:primaryType="nt:unstructured" jcr:lastModified="2015-11-15T11:29:02.429Z" jcr:
lastModifiedBy="newbolda"/>
</editorialOrderItem>
</tile_left>

The reasoning behind adding the extra node <editorialOrderItem> is so that the content API team can retrieve all the items that make up the editorial order
regardless of which components they are coming from with the following single XPath expression

//editorialOrderItem

There are 2 options here for implementation:

1. Change the underlying JCR nodes so that the XML and CVIEW XML selectors will automatically change,
and change the component renderers to use this new format
and write a groovy script to go back and fix all existing manual lists on current pages
2. Add logic in to the CVIEW selector that will rewrite the normal XML format to this new format
a. We would rather not create a new selector as the API would have to make an extra call

References to Escenic and AEM pages can be resolved by the API when presenting the editorial order out to other platforms.

These curated lists can contain links to pages that are not in Escenic or AEM, ie external links through to partner sites like Fantasy Football etc. These
types of items should be ignored by the API and not presented out to other platforms.

Open questions:
1. Which of the above two options should we take?
a. I think this largely depends on question 2 below - ideally we change the JCR nodes to be ordered correctly but if this proves impossible
in AEM we look to option 2
2. Currently the lists on a page are not held in any editorial order within the JCR - it is seemingly random. How much work is this to change it to
enforce the priority of the lists on a page?

a.

51
2.

a. It appears that the order in the JCR of the lists nodes is dependant on a couple of things, the template and the order in which the lists
were added to the page. This basically means that the order is not reliable for editorial order.
b. Talking with Michael G from SR1 it seems that for (Option 2) to order the parsys's within the template would require defining them in the .
content.xml file for each template. This would be a significant amount of work (as all templates would need it) and would also change
their development process, increasing dev time and potentially increasing the possibility of the template code and the xml definition
getting out of sync.
c. Option 1 however would require us to write a new selector or replicate the template logic in the CVIEW selector, this would also be at
risk of getting out of sync.
3. Should the tracking params on link URLs be carried in to the API? Can they be stripped off by the API?
a. ?
4. How will this work with Portal where the lists will likely be curated on different pages in AEM?
a. In option 1 the API would have to follow the references to each of the subsections

52
Providing override fields in the editorial order
The current ticket for this is (AEM-4320)

The previous ticket for Editorial Order (AEM-3665) only handled passing the order of stories to the Content API. There is a desire from editorial to also
pass any override fields that have been applied to the story when placed in a curated list or hero block on a section page.

Architecture have decided that the correct place to store this information is in the article itself rather than where it is now in the curated list or hero block
component on the section page. This means significant changes to the curated list tile component.

Current Curated List Tile component

The existing Curated List Tile component can be used inside the Curated List and the Hero Block Components. This component allows an editor to add a
link on a section page. This can link to an AEM page or any other web link. There are some fields that are only present on this Tile component that don't
exist elsewhere

Label
Quote
Title Suffix
No Follow

It is currently possible to link to an AEM page but override the following fields:

Image

It is NOT possible to override the following (unless you create a completely manual tile and use the URL of an AEM article - then you can override all
fields):

Title
Date

53
This dialog currently reads and writes these properties to the JCR node for this component

JCR Structure changes

The Current JCR structure is

Current JCR structure

hub-page
jcr:content
...
par_section_0
heroblock
listpar
tile_left (external link)
@date
@label
@quote
@title
@titleSuffix
@noFollow
@url
image
@fileReference
tile_centre (aem article - no overrides)

54
@pagePath
tile_right (aem article - with overrides)
@pagePath
@quote
@label
@titleSuffix
@noFollow
image
@fileReference

article
jcr:content
content
social
headline
standfirst
authorPath
articleDate
paragraph
...
tagContent
...
liveStream
articlehero
leadAsset
image
cropping

This would need to change to something like the below forma, note the following:

The External link entry remains the same - all properties are stored against the tile component
The AEM article tile only ever stores the path to the AEM content item - no overrides are stored in the tile component
The Label, Quote and Title Suffix fields are now present in the article
There is a new Summaries node in the article which contains a Summary node for each set of summary fields
Each set of summary fields contains section and component path arrays which will contain a list of section page and component paths where this
summary is used

Target JCR Structure

hub-page
jcr:content
...
par_section_0
heroblock
listpar
tile_left (external link)
@date
@label
@quote
@title
@titleSuffix
@noFollow
@url
image
@fileReference
tile_centre (aem article - no overrides)
@pagePath
tile_right (aem article - with overrides)
@pagePath

article
jcr:content
@label
@quote
@titleSuffix
content

55
social
headline
standfirst
authorPath
articleDate
paragraph
...
tagContent
...
liveStream
articlehero
leadAsset
image
cropping
summaries
summary_1
@sectionPath[]
@component[]
@date
@label
@quote
@title
@titleSuffix
image
@fileReference
summary_2
@sectionPath[]
@component[]
@date
@label
@quote
@title
@titleSuffix
image
@fileReference

Curated List Dialog changes

The dialog for the Curated List Tile component will need to change. It should be broken in to 2 tabs, one for AEM article links and one for external links.

The AEM Article tab will contain a single page path field when first loaded. Once a valid page path is inserted in this field the default summary data (ie.
lead asset, headline, pub date etc) and any other defined summaries, will be retrieved from the article and displayed with radio buttons for the editor to pick
one. If the default summary or other defined summaries are not suitable they will be able to click a button to add a new set of summary fields, once
entered these will be saved back to the summaries area of the JCR under the article node.

AEM article tab

56
57
The External link tab has a URL field at the top and the rest of the summary fields beneath.

External link tab

58
59
Original diagrams here: https://www.lucidchart.com/invitations/accept/3029997d-d968-45a7-804d-2239585a01b3

Questions/Points of note

Will we migrate all existing curated lists in to this format using a script?
How many are there - migrating by hand might be an option?
Or could this be a new component that would allow the old ones to remain?
In this model you have to override all fields or nothing, we cannot override a single field without copying all others - but these could be copied
from the default values
We should advise editors not to use the external link tab to link to AEM content as any override data will be "lost"
The component will only store the page path for an AEM reference, it will need to go to the page path and find a summary node that references
the hub page and component that it is being displayed in and pull in that data.
The Content API will have to refer to the article page and find a summary that references the section page in order to display the correct summary
data (or it has to be done by the consumers of the API)
If an article appears twice on a page with different summaries the Content API will not be able to distinguish and will just see the first summary for
that page (As the Content API has no concept of a Component).
If an article is referenced from a curated list and that article is moved then the curated list will no longer be able to display any link (ignoring any
caching of the page) - previous behaviour would be the same display on the section page but the link would fail unless a redirect had been added.
If both the AEM page path and the URL field on the External link field are entered the AEM page path should take priority
I have assumed that the No Follow attribute is only required for external links (if this is not true then we can included it in the properties we move
to the article).
Should an editor be able to edit the override fields when viewing the article page properties?
Should they be editable in TMG Authoring as they are core article fields?
Should the editor be able to editing the override fields when viewing the curated list tile summaries? - it could affect other section pages if one
summary is used in more than one place.
Should we show which other pages the summary is used on when it is presented for choosing?

60
Auto Redirect when article page URLs change
Requirement
The requirement from Editorial and SEO is that editors should be able to change the URL of an article (for SEO reasons) and any old URLs for the article
should redirect to current live URL of the article. So if article /first/ is moved to /second/ then /first/ should 301 redirect to /second/.

If it is then subsequently moved again to /third/ then both /first/ and /second/ should now 301 redirect to /third/ - this is to avoid double hop
redirects. Also we should not be able to create redirects that form a loop (ie. /first/ to /second/ and /second/ to /first/)

There is an existing URL shortcut tool that enables editors to put in redirects in the form (fromURL, toURL) - it has the following features:

Login through AD
Audit trail (currently through Stash checkins)
Some validation? TBC

The following are out of scope:

It is not possible to see all existing redirects


Wildcard redirects

This tool should ideally be replaced as part of this solution.

Solution Description
Assumptions
There is no requirement to validate a URL change and prevent a user from performing the change based on existing redirects. This means that
we will never prevent a URL change but the implementation of the redirect could fail if it breaks the constraints we have defined (ie. no looping
etc). This also means we will not provide any feedback to a user of AEM or TMG Authoring that the URL change they just made has not been
possible to redirect. There will be a dead letter queue that will collect failed redirects - this can be monitored.

High-Level Description
The proposed solution is to use a Microservice with persistent storage to handle the addition of new redirects. The Service will contain a simple UI that
should replicate the functionality that is available in the existing tool. The service will write a new version of the redirect list to S3 and publish to an AWS
SNS Topic to notify downstream systems of the changes.

Any downstream Apache will have a running client script which will monitor an AWS SQS Queue that is subscribed to the SNS Topic in order to know
when to pull a new version of the redirects. The Client will then pull the file from S3 Storage and build a new config file for Apache and install it.

Micro Service Architecture


The Microservice should follow our standard Springboot template. For monitoring purposes DevOps have requested that it contain Jolokia.

Logical Diagram

61
Original diagram here

AWS Component Diagram

62
(https://www.lucidchart.com/invitations/accept/a6c58bd8-2ae3-4aa5-ae8f-e80aa46b566c from Unknown User (holdichk))

63
Logic
Consistent state (DB constraints)

The assumption is that the DB will ALWAYS adhere to the below rules, so before and after any single redirect is added to the DB this will be the case.

There will be no double hop redirects


ie. there will be no redirect (B to C) if (A to B) already exists
There will be no looping redirects
ie. there will no redirect (B to A) if (A to B) already exists
There will no ambiguous redirects
ie. there will be no redirect (A to C) if (A to B) already exists
There will be no duplicate redirects
ie. there will never be (A to B) in the DB more than once

For inserting a new redirect (A to B) there are number of cases for how to handle it based on what already exists in the DB.

Cases and expected outcomes:

1. There is an existing redirect with the same source and target, ie. (A to B)
The new redirect is not processed as it already exists
2. There is an existing redirect with a target of A, ie. (X to A)
The existing redirect is changed to (X to B)
The new redirect is added (A to B)
3. There is an existing redirect with a target of B, ie. (X to B)
The existing redirect is not changed (X to B)
The new redirect is added (A to B)
4. There is an existing redirect with a source of A, ie. (A to X)
The existing redirect is removed
The new redirect is added (A to B)
5. There is an existing redirect with a source of B, ie. (B to X)
The existing redirect is not changed (B to X)
The new redirect target is altered and added (A to X)
6. There is a an existing redirect for the reverse which would cause a loop, ie. (B to A)
The new redirect is not added and a message is sent to the dead letter queue
7. None of the existing redirects in the DB refer to A or B
The new redirect is added (A to B)

All these rules need to be applied together as there are cases where more than one of these cases could apply for the same redirect - for example case 2
and case 3 could occur together:

Starting state of DB:

(X to A)

(B to Y)

now we want to insert (A to B), if we apply rule 2 first we get:

(X to B) - changed

(B to Y) - unchanged

(A to B) - inserted

but now the second and third rules violate the double hop constraint, so we'd have to reprocess the existing redirects to somehow result in what we expect:

(X to Y) - changed

(B to Y) - unchanged

(A to Y) - changed

This illustrates the need to apply all rules together, or at least have a priority, and the ability to reapply them across the whole set of redirects potentially in
cycles until the constraints are met. This logic will not be straightforward.

Flows

Complete publish flow


1. Editor publishes a page with a changed URL

64
2. During publish cq author adds message to queue (fromURL, toURL, TIMESTAMP) - ensures no messages lost if microservice is down

3. Microservice uses polls the queue to retrieve messages from queue

4. Microservice stores message with status PENDING in DB (fromURL, toURL, TIMESTAMP, PENDING) - If (fromURL, toURL) already exists in the DB
we can discard this message

5. Microservice deletes message from the queue

6. Microservice polls origin TMG servers for the toURL until it gets a 200 (I suggest we set a number of retries and gap between them as configurable
parameters - after the number of retries has occurred we send a message to a dead letter queue logging the error and remove the PENDING
entry in the DB so it is not tried again - we should have a process monitoring the dead letter queue to notify someone about these failures)

7. Microservice determines if there are any other redirects that need to change as a consequence of this new one (to avoid double hops)

8. Microservice writes all changes back to the DB with status ACTIVE

9. Microservice uses DB to generate a new full set of redirects in a file which it writes with PUT to S3 with a timestamped filename

10. When file write is complete Microservice adds a new message to the ActiveMQ Topic containing the timestamped URL to the file

11. Any clients that are subscribed to the ActiveMQ Topic retrieve the message

12. The client script retrieves the file from the S3 location in the message

13. The client script generates the redirect mapping config file and updates Apache config with it

NOTE: if there is an error at any point during the processing of the message by the Microservice a message should be sent to a dead letter queue.

New Redirect added through Simple UI


1. Editor adds new rule in UI and clicks submit (user can select if this is for pages already live - it would poll the origin - or if the rule is for pages not yet live
- no origin poll is required)

2. Microservice stores message with status PENDING and POLL (true/false) in DB (fromURL, toURL, TIMESTAMP, PENDING, POLL) - If (fromURL,
toURL) already exists in the DB we can discard this message

3. If POLL=true then Microservice polls origin TMG servers for the toURL until it gets a 200 ELSE skip this step

4. Microservice determines if there are any other redirects that need to change as a consequence of this new one (to avoid double hops)

5. Microservice writes all changes back to the DB with status ACTIVE

9. Microservice uses DB to generate a new full set of redirects in a file which it writes with PUT to S3 with a timestamped filename

10. When file write is complete Microservice adds a new message to the ActiveMQ Topic containing the timestamped URL to the file

11. Any clients that are subscribed to the ActiveMQ Topic receive the message

12. The client script retrieves the file from the S3 location in the message

13. The client script generates the redirect mapping config file and updates Apache config with it

Complete Microservice startup flow (autoscale group of 1)


1. Connects to DB to find PENDING entries

2. For each PENDING entry in order of their TIMESTAMP value (I suggest we should process these one by one as normal rather than try to batch
up all the changes)

2a. Start polling toURL on TMG origin until 200 received

2b. When 200 received microservice determines if there are any other redirects that need to change as a consequence of this new one (to avoid double
hops)

2c. Write all changes to the DB

3. Microservice uses DB to generate a new full set of redirects in a file which it writes with PUT to S3 with a timestamped filename

4. When file write is complete Microservice adds a new message to the SNS Topic containing the timestamped URL to the file

5. Subscribe to the ActiveMQ topic for new updates and process as above

Complete Apache Client startup flow

65
1. Client script retrieves latest file from S3 (I suggest the Microservice provides an endpoint which the clients can query to get the location of the
latest file. If this is not available then it should retrieve a file with a fixed name from S3 which will contain the correct filename to retrieve - this
will be updated every time a new file is written - we understand that due to eventual consistency in S3 updates that this could get an older file)

2. The client script generates the redirect mapping config file and updates Apache config with it

3. Subscribe to the ActiveMQ topic for new updates and process as above

Questions
items highlighted above in red

1. How to use sequence number to ensure messages are processed in the correct order (not guaranteed by SQS)
a. As order is important to preserve we should not use SQS. Instead I recommend ActiveMQ as we have used this elsewhere in
TMG Technology.
2. When the service is polling for the article to arrive on the origin server - how often and for how long do we poll, what happens if it
doesn't come back with a 200 for a long time?
a. I suggest we set a number of retries and gap between them as configurable parameters - after the number of retries has
occured we send a message to a dead letter queue logging the error and remove the PENDING entry in the DB so it is not tried
again - we should have a process monitoring the dead letter queue to notify someone about these failures
3. If a user wishes to enter a redirect through the UI should we still poll for the target page on the origin? They could be trying to put a
redirect live before an embargoed article is published out of hours.
a. Option 1: default the simple UI to not require the polling of the origin - its assumed that someone using this interface knows what they
are doing
b. Option 2: provide an option in the UI for the user to opt out of the polling the origin
c. Option 3: poll the fromURL at the origin first and only if this returns a 200 do we try to poll the toURL
d. NOTE: if some redirects require a poll and others do not we should store this with the PENDING entry in the DB so that we know on
startup if we have to poll.
4. When the Microservice is starting up processing all pending redirects should we do them all before writing a new file or write a new file
one by one as we work through them?
a. How would we handle the waiting for origin polls before sending out the PENDING redirects on start up?
b. I suggest we should send them one by one as normal - the fanout queues could fill up but the clients will clear them down and
only process the latest message.
5. How does the Client script know where to get the latest redirect file from when it starts up?
a. Option 1: make the microservice provide an endpoint for the clients to query to get the location of the latest file - this would require a
fallback of some sort in case the microservice were down when the clients were initialising
b. Option 2: write the latest file location back to the DB and have the client request it from here on start up - again this would need a
fallback if the DB was unavailable for any reason
c. Option 3: after writing the redirect file to S3 update a file always with the same name with the location of the latest file - the client can
then always request this file at startup - as S3 is only eventually consistent on updates we would not be guaranteed to get the newly
updated version of this file but it may be acceptable to get a version slightly out of date until the next update message comes through?
d. NOTE: I suggest Option 1 with Option 3 as a fallback

66
AMP (Google top result card and SEO)
Background
Google AMP is a new specification for delivering fast pages when clicking through on google searches on mobile.

The documents and associated materials are available here: https://www.ampproject.org/

The idea is to provide a reduced functionality basic HTML version of all article pages (sections and channel pages are not included), which will be linked to
the original page via a <link> tag (and vice versa). So most javascript will be removed although some functionality will be provided through specific Google
AMP JS libraries in order to achieve common pieces of functionality such as Analytics, Advertising, Videos and other embeds.

Design of the pages is largely up to the provider (ie. TMG) but typically there is some branding, a few navigation links and the main article text. Some
examples from other sites that have already implemented it are here:

https://www.theguardian.com/environment/2015/dec/17/leading-lightbulb-brands-making-false-claims-on-energy-efficiency/amp
http://mobile.nytimes.com/2015/12/18/business/shkreli-fraud-charges.amp.html
http://www.nydailynews.com/amp/entertainment/tom-hanks-finds-student-id-badge-attempts-return-article-1.2387536 (this one has a fluid layout
rather than fixed)

This is an example of what Google will return at the top of search results where AMP pages are available.

Telegraph Implementation
When each page in AEM is published, an alert is sent to platform code outside of AEM. The code that receives this alert then generates a separate AMP
version of the page. The second level caching looks for any requests for AMP pages (url ending /amp/) and forward those requests to another system.

Steps for generating an AMP page version:

1. On publishing a page, an alert is sent to a separate system.


2. The AMP generation system queries AEM using page.1.json to get the top-level meta-data.
3. It also gets a copy of the published page, then parses the published HTML to extract only the main article, excluding header, right column and
footer.
4. This HTML fragment is also transformed.
5. A new page is generated and hosted within this separate system.

AEM PoC
There was a proof of concept done in AEM for rendering the AMP versions of pages. This was not the final approach used. Currently large amounts of
code exist in AEM code that should be removed. The only work done in AEM is the outputting of the reference in <head> to inform systems consuming the
page that an AMP version is available.

See Google AMP in AEM Proof of Concept

67
Google AMP in AEM Proof of Concept
Background
Google AMP is a new specification for delivering fast pages when clicking through on google searches on mobile.

The documents and associated materials are available here: https://www.ampproject.org/

The idea is to provide a reduced functionality basic HTML version of all article pages (sections and channel pages are not included), which will be linked to
the original page via a <link> tag (and vice versa). So most javascript will be removed although some functionality will be provided through specific Google
AMP JS libraries in order to achieve common pieces of functionality such as Analytics, Advertising, Videos and other embeds.

Design of the pages is largely up to the provider (ie. TMG) but typically there is some branding, a few navigation links and the main article text. Some
examples from other sites that have already implemented it are here:

https://www.theguardian.com/environment/2015/dec/17/leading-lightbulb-brands-making-false-claims-on-energy-efficiency/amp
http://mobile.nytimes.com/2015/12/18/business/shkreli-fraud-charges.amp.html
http://www.nydailynews.com/amp/entertainment/tom-hanks-finds-student-id-badge-attempts-return-article-1.2387536 (this one has a fluid layout
rather than fixed)

Proof of Concept
As this is essentially an alternate web presentation for all articles it seemed to make sense to explore the use of AEM to generate the AMP view of an
article. This keeps all web presentation on the same system and codebase and under the control of the same development teams who have expertise in
HTML and CSS.

AEM provides the Sling Selector mechanism which enables different renderings of the same JCR content node. This is a good fit for the needs of the AMP
rendering.

Sling Selectors and their priorities are described here: https://sling.apache.org/documentation/the-sling-engine/url-decomposition.html

The code is using the .amp.html selector, I'm sure there is a more elegant way to structure the files using the selector concept, but this did the job of
proving it was possible.

The Proof of concept is currently available on the AEM demo environment (as of 18 Dec 2015 - although if demo is cleared down or rebuilt it will be lost -
see below for files and a zip containing the code). You can add /amp to the end of any article using the article2 template.

http://web1.aem-demo.awspreprod.telegraph.co.uk/fashion/people/jennifer-lawrence-discusses-nude-photos-leak-in-us-vogue-interview/amp

Scope of PoC
Things I have specifically handled are:

AMP doc type


AMP viewport declaration
CSS must be inline with amp-custom attribute (see restrictions here: https://www.ampproject.org/docs/guides/responsive/style_pages.html)
Instagram JS include and <amp-instagram> markup (if added through externalVideo component)
Youtube JS include and <amp-youtube> markup (if added through externalVideo component)
All images use <amp-img> markup
Ads use <amp-ad> markup (although the call to DFP is fixed as though the page is on News channel - I seem to )
HTML Embeds are stripped out (as cannot be guaranteed to be AMP compliant)
<link> tag on normal rendering links to /amp version
<link> canonical on AMP rendering links to normal article url
Review ratings are displayed as squares (although there is no AMP specific markup required)
Quote component is displayed in Red (again no AMP specific markup is required)
Dispatcher rewrite rule to handle /amp (redirecting to .amp.html)

Items still to address in a full solution NOTE: The below list is not complete - I expect there to be more things to handle - especially as the spec
is new and will change quickly.

Decide on the best structure for the code, where and how to utilise the sling selector approach
Embeds (we cannot parse the HTML Embed component to extract the different embeds - this might require additional components)
Videos (potential issue with getting the video asset url from Ooyala through their API)
Adriaans Embeds? - is <aside> allowed?
Iframes <amp-iframe> - resizing requires a callback from the child to the parent to trigger a resize
Twitter <amp-twitter> - do we use the Embed Tweet or Tweet Timeline components? I cant get the first one to work on demo
Image Sizes are currently fixed to one rendition
Layout fluid or fixed width?
Design & Fonts <amp-font>
Galleries (implementation to be decided)
Live? (not yet in the spec?)

68
Analytics, using <amp-analytics> or <amp-pixel> - tracking components?
Onward Journey list of articles (required for MVP?)
Ads to be correctly parameterised to channel/section (this needs to be done with the help of Ad Ops)
Other components that could be dropped in the main content area will need to be handled in CSS or ignored
Decide if we want to notify Google directly on publish that the AMP version is available or just rely on the crawler
Bypass Paywall/Metering for AMP view
Sponsorship for Spark?

New and Changed files

New files
/apps/telegraph/core/commons/renderers/pageRenderer/amp.html
/apps/telegraph/core/commons/renderers/pageRenderer/ampBody.html
/apps/telegraph/core/commons/renderers/pageRenderer/ampBodyContent.html
/apps/telegraph/core/commons/renderers/pageRenderer/ampHead.html

/apps/telegraph/core/commons/renderers/articleRenderer2/ampBodyContent.html
/apps/telegraph/core/commons/renderers/articleRenderer2/ampMainBodyHeader.html

/apps/telegraph/core/commons/components/articleBodyImage/amp.html
/apps/telegraph/core/commons/components/advert/amp.html
/apps/telegraph/core/commons/components/externalVideoPlayer/amp.html
/apps/telegraph/core/commons/components/htmlEmbed/amp.html
/apps/telegraph/core/commons/components/galleryTeaser/amp.html
/apps/telegraph/core/commons/components/leadAsset/amp.html

Changed files
/apps/telegraph/core/commons/renderers/pageRenderer/head.html (Added the <link> to the AMP version - Not currently restricted by template)
/apps/telegraph/core/commons/components/component/templates.html (Added the <amp-img> tag rendering)

All files are in this ZIP: AMP-PoC-Files.zip

On the Dispatcher

In this file:
/etc/httpd/conf-enabled/rewrite.conf

Add this to 'pass through' urls with the /amp to .amp.html:

#transform */amp to *.amp.html


RewriteCond %{REQUEST_URI} ^/(.*)/amp$
RewriteRule ^/(.*)/amp$ /$1.amp.html [PT]

and add this to let the .amp.html selector through:


/etc/httpd/dispatcher/dispatcher.any

/1003 { /type "allow" /glob "GET *.amp.html *"}

then restart apache

sudo service httpd restart

AMP Validation
It is possible to validate any page as AMP in Chrome by adding #development=1 to the end of the AMP article URL. Then view the browser console you
should see a "Powered by AMP" message and then any errors that have been found. The validation process also adds error classes to the HTML in
places where it find a problem, perhaps this could be used in automated tests?
For example: http://web1.aem-demo.awspreprod.telegraph.co.uk/fashion/people/katy-perry-hm-christmas-campaign/amp#development=1

69
70
Components
Component/Template Catalogue is available here:

https://docs.google.com/spreadsheets/d/1tc-xIHxcQLI4mdS_g0oLJfJDqQEaOFoH_-pwGmVf24Y/edit#gid=0

71
Periodic Table
Components by Business Area
(Click here to download the Full size PDF)

Components by type
(Click here to download the Full size PDF)

72
73
Integration
Adobe Analytics
Most Viewed
Most Viewed List diagram

Adobe Campaign
Basket Abandonment email marketing

Adobe Social Communities


Adobe Live Article Service Pack
Options for Migrating comments from Disqus to AEM

Front-end
New Slider/Gallery

Nitro Integration
AEM Content Retrieval (JSON-LD Selector)
AEM Article -> Canonical Model mapping
AEM Cross Domain Ajax Requests to TMG's Core API
AEM Data Driven Pages (Nitro Entity Roadmap)

74
Adobe Analytics
Introduction & Summary
Current Landscape
Requirements
Assumptions and Constraints
Implementation Approach (Data Layer vs Existing Metas)
Data Layer detail
Transition Approach (How to introduce AA and phase out Webtrends)
Prerequisites
Overview
Step 1a: TCUK legacy sites + reporting and parallel run
Step 1b: Begin Data Layer implementation on AEM
Step 2: Implement internal integrations with Analytics consuming applications (through Nitro)
Step 3: Change outgoing data feeds (for TCUK sites only)
Step 4: Mobile Apps
Step 5: Ongoing migration of rest of the 3rd party sites
Step 6: Decommission Webtrends (& any other platforms we can)
Next Steps
Questions

Introduction & Summary


The business would like to replace the current Analytics solution(s) with Adobe Analytics. Below I will describe an approach for implementing Adobe
Analytics on the Legacy (Escenic, WordPress etc) and Future (AEM) platforms.

Current Landscape
There are currently a large number of Analytics tools deployed to the different platforms and sites in the landscape. Each fulfils different capabilities.

Full ABCe reporting on traffic Dynamic Visualisation AdHoc Queries and nice interface Industry required

Webtrends yes

Google Analytics yes

Chartbeat yes

Comscore Yes

Parse.ly yes

OutBrain Engage (recent) yes

Adobe Analytics yes yes yes

This is a view of which tools are currently deployed to which platforms.

https://docs.google.com/a/telegraph.co.uk/drawings/d/11_9_BPK5XFQp10PEgTX7MIuJ0hFZD8nouAvXmXl-ifY/edit

Requirements
General Analytics Requirements (Brian/Jodi)

2014-09-29 TMG-Culture-SDR-v2 1 (1).xlsx

2014-09-16 Adobe Evolve Analytics BRD - Telegraph Culture - Medium (1).xlsx

Video Analytics Requirements (Howard)

https://docs.google.com/a/telegraph.co.uk/presentation/d/1seHmL4-BOIKwMvTl8hVCX1IZoW-_JWLId9WCyCfzxHA/edit#slide=id.g41337551a_15

Assumptions and Constraints

75
1. Adobe Analytics
2. The QlikView Dashboard is no longer in use.
3. We have to send out all analytics data to ABC (and NLA) - this data is split in to two areas - Website and Mobile App traffic. We could send one
set of data from one system and another from a new system, however all the data for a single area has to be sent from a single source.
4. The ultimate target architecture is to remove the need for all other analytics products and replace with Adobe Analytics, this will only be possible
once Adobe Analytics is in place on all platforms.
5. Any integrations with Adobe Analytics will be done through Nitro - not direct to Adobe.
6. There will be a long transition period during which we will continue to have multiple delivery platforms and CMSs - all will need to have Adobe
Analytics implemented on them.
7. Adobe Analytics must be implemented through DTM (this is the recommendation from Adobe and it provides more flexibility for Brians team)
8.

Implementation Approach (Data Layer vs Existing Metas)


Adobe recommend that for a new integration with Analytics that a Data Layer is implemented on the site. A Data Layer is an extensible, standardised way
of storing all the data about a webpage that you may want to pass to other systems, ie. Analytics, Advertising etc. It can also hold information about events
that occur on the page. The data is stored in a Javascript Object that conforms to a particular standard.

Implementing this on our existing platforms will be a lot of work, so I propose that we only consider this form of implementation on AEM and treat it as the
method for delivering the Monza Analytics/Advertising requirements.
DTM is bridge between the data in the page and the destination (in this case Adobe Analytics). It contains the rules that define where in the page the
values can be found. The existing websites expose data values in a mixture of Meta tags, Javascript variables, the URL of the page, Cookies etc. This is
not a good model as data is replicated in many places and in slightly different formats and is not easily managed and is prone to problems caused by other
development changes.

A single Web Property in DTM defines the rules for how to extract the data from a website. As we are proposing 2 different methods of extracting the data
(1 by existing meta tags etc and 1 new version that will utilise a new data layer object) this means we will need 2 Web Properties setup in DTM. Each Web
Property has a different code embed that has to be deployed to each environment where it needs to be used.

2 new DTM Web Properties are already setup and changes are in the dev pipeline to deploy the new "Legacy" DTM tag to the legacy environments (E4.3,
E5.3, E5.4, Blogs, My, Fashion). The work still needs to be done to define the full set of rules for this (although some work was done for the Culture PoC
that was done previously).

The new AEM DTM tag can be deployed to AEM once we have finalised and implemented the Data Layer.

76
Each Web Property in DTM is connected to a particular Adobe Analytics account and Report Suite within that account. The Report Suite defines a "set" of
data on which reports and other operations can be done. Data in different Report Suites would be more difficult to compare.

For this reason it would be ideal if both our new Web Properties would send their data to the same Report Suite. See below:

One thing that might stop us doing this is if the changes to the site structure proposed for Monza (ie. creating different types of pages - Bridges, Hollow
Sections etc) mean that we want to track different things in Monza compared to what is tracked at the moment. For this reason we need to fully
understand the new AEM site structure.

Data Layer detail


There appear to be a few standards out there, the W3C has a standard and Google have a standard which is most commonly used in conjunction with the
Google Tag Manager. The difference is essentially the name of the Javascript Object and the names of properties within the Javascript Object.

I have looked more in to the W3C standard. It allows us to store data about anything we like but there are some components that are defined as part of the
standard.

77
The Page object carries significant details about the page, and the most commonly used data elements are captured by the specification below.

The Product object carries details about a particular product with frequently used properties listed below. This is intended for data about products
displayed on pages or other content. For products added to a shopping cart or ordered in a transaction, see the Cart and Transaction objects below.

The Cart object carries details about a shopping cart or basket and the products that have been added to it. The Cart object is intended for a purchase
that has not yet been completed. See the Transaction object below for completed orders.

The Transaction object is similar to the Cart object, but represents a completed order. The Transaction object contains analogous sub-objects to the
Cart object as well as additional sub- objects specific to completed orders.

The Event object collects information about an interaction event by the user. An event might be a button click, the addition of a portal widget, playing a
video, adding a product to the shopping cart, etc. Any action on the page could be captured by an Event object.

The Component object is intended to capture information about a content component included as part of a page, such as a video. Interactions with the
component — such as playing the video — would be an Event, captured by the Event object above.

The User object captures the profile of a user who is interacting with the website.

The Privacy object holds the privacy policy settings that could be used to:
1. Capture and enforce site visitor consent to use tracking technologies on the site.
2. Together with Security objects described below, secure access to individual objects within the JSO by categories of tracking technologies.

The Security object is an optional sub-object of each object in the JSO, which can be used to enforce data access control over that object. If a Security
object is defined for an object, the value should be a comma-separated list of categories defined as categoryName in the Privacy object. If a Security
object is not defined for an object, no data access controls will be enforced.

Full specification is available here: ceddl-201312-data-layer-spec.pdf

Some of the above are obviously more pertinent to our website that others. Most of our data could be captured in the Page and Event objects. We could
also do a more in-depth integration with SAM and registration/subscription flows to store those details here as well.

Any additional data that is not defined in the spec can be added as new properties or objects.

Transition Approach (How to introduce AA and phase out Webtrends)


Prerequisites
Model of new AEM site structure defined? - With Dan Adcock
Requirements for tracking on existing site and on new finalised structure - With Brian O'Connor
Model of data in AA defined to accommodate both
2 web properties created in DTM - DONE

Overview
Below is a rough timeline indicating the order and overlap of the steps described further below. Blue=Todo, Green=Done

Step Task

Step 1a Implement on Escenic 4.3 x

Implement on Escenic 5.3 x

Implement on Escenic 5.4 x

Implement on .Net x

Implement on Blogs x

Implement on My x

Implement on High Priority 3rd party sites x

Parallel run x x

Step 1b Implement on AEM Data Layer x x x x

Step 2 Implement Nitro integration x

Switch Escenic 4.3 Most Viewed to use Nitro x

Switch Krux to get data from Nitro x

Step 3 Switch ABCe report (for TCUK) to Adobe Analytics x

Switch NLA to receive data from Adobe Analytics x

78
Step 4 Implement on iPad App x

Switch ABCe report (for iPad) to Adobe Analytics x

Implement on iPhone App x

Implement on Android phone App x

Implement on Android tablet App x

Implement on Kindle App x

Implement on Blackberry App x

Implement on Win 8 App x

Step 5 Implement on low priority 3rd party sites x x x

Step 6 Decommission Webtrends x

Step 1a: TCUK legacy sites + reporting and parallel run


Implement Adobe Analytics on all TCUK sites/platforms including some high priority 3rd party hosted websites (ie. Jobs, Fantasy Football etc). Platforms
are:

Escenic 4.3
Escenic 5.3
Escenic 5.4
.Net
Blogs
My
High priority 3rd party sites (List TBC)

Also build replacement internal reports powered by Adobe Analytics.

Parallel run Webtrends and Adobe Analytics for a period of time and compare the reports from both systems to ensure that we are happy with the
implementation and the data that is captured by Adobe.

79
Step 1b: Begin Data Layer implementation on AEM
We already have a basic implementation of Adobe Analytics on AEM Cars and Best this will need to be discarded and the new implementation
built. Based on the recommendation this implementation should be creating a Data Layer in the page (see above).

This process should not delay the TCUK sites implementation.

Step 2: Implement internal integrations with Analytics consuming applications (through Nitro)
The recommended approach here is to integrate Adobe Analytics with Nitro and then switch any consuming applications over to get the data from
Nitro. The Applications include Website Most Viewed, Krux, Qlikview (Qlikview may no longer be in use).

Step 3: Change outgoing data feeds (for TCUK sites only)


Switch all outgoing data feeds of Analytics to come from Adobe Analytics and not Webtrends. These data feeds currently go to ABCe and the NLA.

Step 4: Mobile Apps


Migrate mobile apps one by one to use the Adobe Analytics SDK. Once the iPad app is done we can also switch the ABCe report for this platform over to
Adobe Analytics and disable the Webtrends feed.

Step 5: Ongoing migration of rest of the 3rd party sites


Request the changes to all 3rd parties that manage each of the externally hosted sites. Full list TBC.

Step 6: Decommission Webtrends (& any other platforms we can)


Disable Webtrends on all platforms and decommission.

80
Next Steps
1. We finalise the new site structure as per the Monza/URS recommendation. Without this we will not be able to say what the requirements for tracking and
ad delivery will be.

2. We define what will need to be tracked/used by Analytics, Advertising, The Data Team (Ken MacPherson), Subscriptions etc. This comes down to
business requirements.

3. We specify a data layer with properties that hold all the values required The key is that this needs to be a collaborative approach to create a single data
layer object that does not duplicate data and holds everything that.

Questions

to be filled in

81
Most Viewed
Problem:

We need to build a new component on AEM that displays an ordered list of articles based on a page view report in Adobe Analytics.
We need to rebuild the Most Viewed list component on Escenic so it gets its data from Adobe Analytics instead of Webtrends because...
The Webtrends contract expires in December 2015 (although disabling sooner may reduce overage charges)

Assumed Requirements - mostly taken from current Escenic Functionality (TBC):

Most Viewed lists on either platform need to be able to show content from both platforms (ie for old content still delivered on Escenic and
Portal
Most Viewed units need to display the following fields: Link URL, Headline, Publish date, Thumbnail image,
We need to be able to filter the Most Viewed lists by: Channel (multiple), Type of Article (multiple) and Time period (Day, Week, Month) (only a
single time period will be shown in any single Most Viewed unit)
We need to be able to blacklist certain articles from appearing in Most Viewed lists
The Most Viewed list can be configured to show different numbers of articles (potentially a max of 10?)

ie. Show me :

The URL, Headline, Publish date and Thumbnail image URL of


the top 5 (most page views)
Articles and Galleries from
Escenic and AEM from
/football or /rugby or /golf or /tennis or /cricket .... over
the last day
ignoring 3 specific articles (specified by id/url?)

Recommendation
I recommend we go for option 2 for AEM and option 3 for Escenic, this means integrating the Data Lake platform with Adobe Analytics and the Content API
and exposing a Most Viewed API that can be used by either AEM or Escenic. This does mean the Most Viewed component will not be delivered until later
than planned, although exact timing would have to be worked out. The delay could be mitigated by defining and mocking the API upfront so that
developers could start the work on the components for each platform.

TL;DR
There is a spreadsheet here with the pros and cons of the options below:
https://docs.google.com/spreadsheets/d/1kd1qAiTU__1c4HSK0YJevdicxt-FvXg0uRJAQuWjI7M/edit#gid=0

Options for AEM:


1. Direct to Adobe Analytics integration (Quick/Dirty solution)
We build a direct integration to query Adobe Analytics APIs from AEM on a scheduled basis. A new Most Viewed list component will use the cached
responses to generate the list for display on the page.
Caveat: This is only possible if it is possible to utilise the Page Path that is passed to Adobe Analytics via the metatag to look up the Headline/Image etc
from the article:
<meta name="DCSext.articleId" content="/film/birdman/michael-keaton-interview">

If the above cannot be used then an alternative ID would have to be included in the tag for Adobe Analytics that we could then use when it comes back in
the Most Viewed list API responses to look up information about that article, ie. headline etc.

Pros:

Development can start today


No dependency on Data Lake platform

Cons:

Escenic Articles will not appear in AEM Most Viewed lists as we cannot look up information on Non AEM ids
Not an elegant solution
Would probably need to be rebuilt once the Data API is in place

82
2. Data API integration (Full solution)
We build the integration between the Data Lake platform and Adobe Analytics and also integrate the Content API in order to expose a "Most Viewed API"
endpoint that delivers all data required by the AEM component to present the list of articles. We connect the new AEM component to this API.

Pros:

Escenic content could be displayed in Most Viewed lists on AEM


Complete elegant solution that would be future proof
Easier development for the AEM team (as the Most Viewed end point would provide all information required to build the list)
The same API can be used by Escenic

Cons:

Dependency on Data Lake platform


More development for the Core API team
Make take longer due to dependancy on Data Lake platform being in Production

Options for Escenic:


1. Do nothing
Leave the current implementation in place maintaining the Webtrends driven Most Viewed lists on Escenic.

Pros:

No development work on a sunsetting system

Cons:

We may incur overage charges from Webtrends if we cannot switch off sooner than December
AEM content doesn't currently display in Escenic Most Viewed lists

2. Rebuild the integration directly with Adobe Analytics (Quick/Dirty solution)

We change our implementation of Most Viewed to query Adobe Analytics APIs instead of Webtrends.

Pros:

May reduce overage charges from Webtrends if we can switch it off before December

Cons:

Development work on sunsetting system


AEM content still won't display in Escenic Most Viewed lists

3. Data API integration (Full solution)


We build the integration between the Data Lake platform and Adobe Analytics and also integrate the Content API in order to expose a "Most Viewed API"
endpoint that delivers all data required by the Escenic component to present the list of articles. We rewrite the existing Escenic Most Viewed code to
connect to this API.

Pros:

AEM content could display in Escenic Most Viewed lists


Dependency on Data Lake platform
Complete elegant solution that would be future proof
The same API can be used by AEM

Cons:

Development work on sunsetting system

83
Most Viewed List diagram

84
Adobe Campaign

85
Basket Abandonment email marketing
Problem description
Ken would like the capability to email users that have abandoned the purchase process at various stages on a number of our third party hosted white label
sites. Any solution we choose should be able to be used on our own subscription pages as well. The Third party sites initially targeted are:

http://shop.telegraph.co.uk
http://dating.telegraph.co.uk
http://wine.telegraph.co.uk
http://books.telegraph.co.uk
http://gardenshop.telegraph.co.uk
http://boxoffice.telegraph.co.uk
http://travelshop.telegraph.co.uk

There is already existing functionality to do this on the shop.telegraph.co.uk site provided by Red Eye, a digital agency that work for the supplier of the site
(BVG). This has been in place since March 2014 and has seen good results. Four specific scenarios are being targeted:

1. User viewed item and abandoned


2. User added item to basket and abandoned
3. User added item and abandoned during checkout process
4. TBC with Ken

The key problems with this existing solution are:

It only applies to a single third party site and is not portable to others
The marketing emails are not sent in a timely fashion, ie. they are sent the next day - research suggests that emails sent within an hour of
abandonment have an approximately 50% better conversion rate.
This process currently involves a manual process to process the emails and currently takes up 2 peoples time on Kens team each day. Ideally
this would be completely automated.

The forecasted commission we would gain from implementing this on the above sites is around £53,000 per year. This is based on the current conversion
rates as per the existing solution on shop.telegraph.co.uk and does not take in to account increased conversions (potentially up to 50% better) from
sending emails within an hour of basket abandonment.
Further opportunities exist in other areas:

http://puzzles.telegraph.co.uk
http://fantasyfootball.telegraph.co.uk
http://www.telegraph.co.uk/subscriptions/

Three Options
Krux
This is our existing Data Management Platform so it makes sense to consider using it for this too, however, this functionality is not available out of the box
with Krux and would require development in augment their product. Also the data would only be available in a nightly feed which does not address the
timeliness problem, for this reason alone it doesn't seem worth pursuing.
Ken has estimated the cost of the work with Krux as £14,000.
Sub2
This is a third party that Ken has approached as they offer an "out-of-the-box" solution for this functionality. The implementation is basically the coding of
some Javascript on each site that will capture the user details and progress through the purchase process. This implementation would be done by each
white label site in consultation with Sub2. The 3rd parties should be keen to undertake this as the increased sales on each platform should be significant.
Other advantages of going with Sub 2 are, that they have experience in this field (specifically the retail sector) and can advise us on how to make best use
of their software in order to maximise the conversions from the emails. Also Ken has been told that there is a way that we could integrate Sub2 directly with
Adobe Campaign in the future via APIs.
I believe their cost model to be based on volume of emails sent, however I have to confirm this. Ken has estimated the cost as £2000 a month.
I am waiting for a contact from Ken so I can have a call with them to discuss the implementation, costs and Campaign API integration.

Adobe Campaign
Campaign is the logical target for this kind of functionality going forward. However there is a question around our readiness to use it, its only just started to
be used, and the complexity of the set up for these types of campaigns. As this is a product we have already purchased the only costs would potentially
be development time and costs.
I have discussed the high level integration with Sean Crouch and James Elliot from Adobe and they ensure us that this use case is possible with Adobe
Campaign and Analytics. However the integration between the two is not currently real-time enough to be able to send emails faster than next day. Adobe
are to respond to us with the timelines on this integration upgrade in the next week (potentially Thursday 19th Feb).

Next Steps
Adobe Campaign (with Analytics) is the long term strategic solution of choice however there are doubts about when the integration between Analytics and
Campaign will be real-time enough in order to send these emails in a timely fashion. We await their response on the timescale of the upgrade of the
integration.
As Kens team is keen to get this up an running quickly we are happy for Ken to put forward the business case to use Sub2, at least in the short to medium
term. We suggested that the contract contain a way for us to break out if required. Also that we continue to pursue with Adobe the long term strategy.

86
Related material
Business Case from Ken MacPherson
Sub2 Implementation Guide
Sub2 Client responsibilities flow diagram

87
Adobe Social Communities

88
Adobe Live Article Service Pack
Packages Installation Instructions
Packages folders contain three packages. Follow the following steps in order to install from the CRX/DE package share interface:

1. Download the latest package from Adobe (see list below for releases)
2. Go to http://localhost:4502/crx/packmgr/index.jsp and click Upload Package
3. Upload the telegraph-livearticle-content package first then the other content package
4. Upload oembedComments-1.zip

89
Options for Migrating comments from Disqus to AEM
These appear to be our high-level options for extracting the comments from Disqus. We have around 12.7 million comments in Disqus (as of Dec 2014).

1. Export all comments to XML


This would be a one-off process so either there would have to be a definitive cut-off date or we do multiple exports and try to determine the
increasingly small delta until the cut-off date.
I expect this file will be huge given the 12.7 million comments we have. This could make it unwieldy to process.

2. Create a sync process


We set up a sync process that copies back all existing comments using calls to their API - and then all comments subsequently created - to a local data
store under our control.

This sounds like more development effort would be required as we would need to setup a DB to store the comments
Also this would be effort for a very temporary migration approach.
Might it be possible to model these in the Data Hub?

Once we have the comments locally


Once we have the comments (in XML or in a data store) we'll have to write a process to recreate the comments in our system of choice - here we will have
to map the existing fields from Disqus, e.g.

comment_id (char 32)


thread_id (char 32)
thread_link (char 200)
forum_id (char 32)
parent_comment_id (char 32)
body (text)
author_name (char 200)
author_email (char 200)
author_url (char 200)
date (datetime)

to the equivalent concepts in AEM Social Communities. This would need more work to actually map everything across and ensure that we were able to
still link the thread with the article (at the moment the Escenic Id is used to map threads to articles so as long as the Escenic Id is available in AEM then we
should be ok.

90
Front-end

91
New Slider/Gallery
Overview
The objective is to replace the current Royal-Slider gallery with purpose built script.

In the past Royal-Slider as proved to be hard to implement and maintain, it's support for mobile is patchy and has required an undue about of dev effort to
achieve a fairly un-inspiring result. The goal of building an bespoke solution is to create a simpler, easier to maintain, configurable product that works
nicely on mobile platforms and integrates well with our existing scripts, e.g. lazy loading images and lazy/on demand/ loading.

Questions
What devices/browsers do we need to support
How many slides should be preloaded
Should this be configurable in the component
Should the slider have an auto scroll functionality
Should this be configurable in the component
Should this pause on hover
Should this be capable of being open sourced
Should the slider loop (Go back to the start once finished its loop)
Should this be configurable in the component
How should it be laid out
Should this be able to be used on other platforms besides AEM
Should the slider have a fullscreen option

Requirements
The sliders should be able to support images, videos, html, AEM/CQ component.
The images and videos should be able to be added from the content finder / dam.
The slider needs to be responsive
SEO

Every slide should have it's own page


That page should be navigable to by non-js browsers
The url of the page should be progressively enhanced
The pagination of the images should be SEO compliant
The child slides should be children of the main page
The AJAX of the progressive enhancement should translate to the non-javascript
Each slide page should be furnished with contextualised WAI compliant circumstance
Build the slider with one slide per page for non-js users and enhance for js users (smooth transitions etc)
URL should be sharable to js and non-js recipients
Added a powerpoint: Gallery Vision.pptx
Events
The slider must support horizontal swipe pan events to progress through the slides
The slider needs to support next a previous events for both touch and non touch devices.
The slider should have events for javascript developers to hook for customisability.
The slider should be using css transitions and animations if supported.
The slider should be able to configure the number of slides before you see and interstitial advertisement or turn them off all together.
The slider should have the ability to toggle both the visibility and the position of its thumbnails.
The content should be progressively loaded for a faster initial load.

Tasks
Setup project;

Identify component modules

Create HTML mock pages with current use cases

Setup test framework

Development

Testing

92
Nitro Integration
AEM Content Retrieval (JSON-LD Selector)
AEM Cross Domain Ajax Requests to TMG's Core API
AEM Data Driven Pages (Nitro Entity Roadmap)

93
AEM Content Retrieval (JSON-LD Selector)

94
AEM Article -> Canonical Model mapping
This page discusses the mapping from AEM pages to the Telegraph Canonical Model per discussion with Frederic Dran, Giuseppe Saltini and Unknown
User (mocchettir).

This mapping will be used by AEM when exposing pages to Nitro using the JSON-LD selector.

Note: AEM articles, reviews and any type of authored page are mapped to the Article class in the Canonical Model.

Article entity

Class Property How to populate? Relevant AEM Comments


components

Article activateDate First date the article was published at Page

blacklist n/a n/a

copyright "Telegraph" n/a

customByLine Author, date, place (As one string)

customUrl n/a n/a

deliveryMedium "web" n/a

escenicId n/a n/a

escenicVersionId n/a n/a

footballCompetition n/a n/a

footballMatch n/a n/a

forIPad n/a n/a

gallery List of gallery entities in the page, both images and videos.

googleKeywords Populate with keywords meta tag metaTag

headline Article Headline headline

icon Favicon public URL Page

newsSpeed n/a n/a

picture List of images on the page - Excluding galleries All components which Unknown User (mocchettir) will
have images rename to "image"

relatedArticle List of related articles - Only if list is curated. If dynamic, leave CuratedList
empty

section List of sections (Corresponds with topic pages in AEM).


Note the list should also include sections parents as shown in
the page breadcrumbs.

standfirst Standfirst text standfirst

standoutMetatag n/a n/a

state published / unpublished Page

statistics n/a n/a

statusChangeDate Date of last status change (activate/deactivate) Page

story Story entity (See below) n/a

syndication n/a n/a

trackingUrl n/a n/a

video List of all videos in the page - Excluding videos in galleries video player

webtrendsEdcgPar n/a n/a


ameter

windowTitle Page title Page

children list all first level child pages as an array of aem relative paths n/a

Creative aemPath AEM path of the creative content Page Unknown User (mocchettir) will add
Work to schema
(Super
class)

author Article author n/a

95
contributor n/a n/a

createdDate Date when created Page

creator Page creator (May or may not be same as author) Page

entity Related entity/es. The entities are coming from Nitro so only Page
URIs should be provided

genre n/a n/a

language n/a n/a

modifiedDate Last modified date Page

publishedDate Same as activated date Page

publisher n/a n/a

title n/a n/a

Thing accessible n/a n/a


(Super
class)

article n/a n/a

category n/a n/a

code n/a n/a

description n/a n/a

label n/a n/a

name n/a n/a

poster Lead image

status n/a n/a

tag Array of strings corresponding to the page tags Page / Entity ?

thumbnail Page Thumbnail (Thumbnail rendition of the lead image?)

tmgId n/a (Provided by Nitro) n/a

url Page public URL Page

Story entity

Class Property How to populate? Relevant AEM Comments


components

Story body Article Body HTML Article Body

customByLi Same as article


ne

headline Same as article

location Geographical location of the story


if available.

pullquote List of quotes used in the story Quote Unknown User (mocchettir) to create a quote class so that quotes and quote
sources will be linked.

pullquoteso List of quote sources used in the Quote


urce story

standfirst Same as article

storyNotes n/a

CreativeW <ALL> Same as article


ork
(Super
class)

Thing <ALL> Same as article


(Super
class)

96
97
AEM Cross Domain Ajax Requests to TMG's Core API
Background
In order for the AEM CORE team to integrate with the CORE API for both login and registration:

1. The AEM FE components to be developed will be AJAX based


2. For security reasons, browsers tend to unilaterally block any calls and resources being made to URLs outside the domain that served the current
page.

Approach

In order to make the "proxy" generic the call from the client to AEM should be:

/bin/core/proxyservlet/

passing the following types in the header eg.

API-Protocol : HTTPS

API-Method : POST

API-Host : datareg-sit.aws.telegraph.co.uk

API-Path: /commerce/accounts

API-Auth: true

API-Strip-Cookies: true

And the body should be the JSON serialised form inline with the data structure of the API request

The servlet then can read the header values and forward the request

98
99
AEM Data Driven Pages (Nitro Entity Roadmap)
Overview
This page lists the development milestones required to implement the Nitro driven AEM entity model.
For each milestone, a list of stories is included. Once the new model architecture is approved, this stories will be created in JIRA.

See CCORE-933 - Allow AEM to use Nitro provided entities as a native entities. TO DO

1.1. Nitro Class Extender Framework


Objective of this milestone: Provide underling infrastructure for extending the Nitro schema on a class level.
Dependencies: None

Consume a Nitro class from the Nitro schema


Extend the Nitro class with additional properties from the Nitro class override resource stored in AEM.
jsonld selector to expose the extended class schema, i.e. http://localhost:4502/bin/nitro/class.movie.jsonld

1.2 Nitro Class Extender Console


Objective of this milestone: Console allowing Data administrators to define new properties for Nitro classes.
Dependencies: 1.1

Create a dynamic management console for Nitro Classes. potential location of the console http://localhost:4502/bin/nitro/class.movie.html
Data administrators can add new properties which are not available in the Nitro schema.
Need more analysis to understand what else can be added to the Nitro Classes metadata apart from extra properties. Additions to the class will
be used across the board, so no channel specific stuff allowed.

2.1 Nitro Resource Extender Framework


Objective of this milestone - Provide underling infrastructure for accessing and utilising Nitro resources.
Dependencies: 1.1

Consume a Nitro resource from Nitro (Including it's linked resources)


Augment the Nitro resource with Nitro Override resource stored in AEM, use the Nitro class override to control the allowed properties.
Create and utilise an in-memory Hash to ensure the same resource is not requested/augmented twice in a specific scope (i.e. page rendering
process).
Expose Nitro resources to Sightly via BindingValuesProvider
jsonld selector which expose the augmented resource, i.e. http://localhost:4502/bin/nitro/resource.5f4918f9-b63d-34ed-9e15-3d4e1f9e3418.jsonld

2.2 Nitro Resource Extender Console


Objective of this milestone - Console allowing authors to extend/augment Nitro resources.
Dependencies: 2.1

Create a dynamic management console for Nitro resources. potential location of the console http://localhost:4502/bin/nitro/resource.5f4918f9-
b63d-34ed-9e15-3d4e1f9e3418.html
Dialog displays all properties available in the Nitro classes which the resource belongs to, as well as extended properties defined in AEM for their
classes.
Authors can then edit the properties and save.
Enhancement option 1: Properties where values are coming from Nitro will be locked (Lock icon next to property). To edit the property, authors
will need to unlock it (Click the lock). Authors will also be able to revert a property to its Nitro value by re-locking it (Click the lock again)
Enhancement option 2: Console will display the resource as well as related resources, so authors can work on a resource and it's related
resources in the same time. i.e. work on a film resource and actors resources in the same page. Every resource will be shown in a different panel
with a "Save" button in the panel bottom, there will also be a "Save all" button to save changes for all resources in one click.

3.1 Nitro Resource Navigator


Objective of this milestone - Front-end lightbox allowing navigation on top of Nitro resources. Used by authors when they need to find a Nitro resource, i.
e. to author it or associate it with a page.
Dependencies: None - This is a front-end piece which should be isolated from AEM and depend on Nitro discovery API only. JS based hooks will be used
to connect this with AEM.

Navigator to be built in pure JS, can be wrapped as a jQuery plugin or something similar.
Navigator can either show as a lightbox, or work inside a provided div (So we can wrap it as an AEM console)
Input parameters for the Navigator object: Nitro server, auth keys, starting resource (optional), starting class(es), target class(es).
The navigator displays with an initial list of resources based on either the starting class(es) or the starting resource.

100
User can then navigate through the resources, or filter lists using keywords.
A "Select" button is shown in the bottom of the navigator, when the selected resource belongs to one of the target classes, the select button
becomes enabled.
When the user clicks select, the navigator triggers a select event with the selected resource URI as it's payload.

3.2 Associating pages with Nitro resources


Objective of this milestone - Being able to associate a page with a Nitro resource, including tools for navigating and authoring Nitro resources
Dependencies: 2.2 , 3.1

Design dialog used to associate a specific template with Nitro class(es). i.e. a film review page should be associated with a film class resource.
The page properties dialog contains a Nitro tab.
The Nitro tab allows navigating over Nitro to associate the page with a Nitro resource (By hooking the dialog with the navigator described in 3.1)
The Nitro tab contains a button for editing the Nitro resource - Calls the dialog defined in 2.2
Enhancement option 1: Support for a secondary Nitro resource, or a list of Nitro resources? Use case is pages that require curating 2 non
related resources.

101
Script Management
OpenTag Overview And Release Cycle
1. Introduction
This document provides a high level summary of TMG’s Opentag tag management solution for the purposes of Technology support. Qubit's Opentag
service lets TMG group tags into containers and uses the ‘asynchronous deferred’ loading method. This enables visual elements of TCUK pages to be
loaded first whilst other elements are loaded behind the scenes, resulting in a better user experience. Using containers also helps TMG deploy tags more
quickly and at lower cost by de-coupling tag deployment from core website development, although telegraph.co.uk (TCUK) tags will be deployed in
alignment with Web Ops release management process for supportability. The diagram below illustrates Qubit’s hosted Opentag solution.

Tags are deployed by STS Web Ops using the Administrator Account (bottom left in diagram above) to TCUK (Client Websites on the top left of the
diagram).

2. Implementation across TCUK Content Management Platforms


TMG uses Qubit's hosted Opentag solution to serve tags through container tags deployed across TCUK. Qubit Opentag uses Amazon Cloudfront CDN, a
leading Content Delivery Network with 34 points of presence across the world with a monthly uptime of at least 99.9%. Information on the Opentag service
can be found here: http://www.qubitproducts.com/tag-management/key-features#container.

Opentag is implemented on Escenic 4 sections including mobile, Escenic 5.3 including travel (but excluding E5 mobile), SAM, Luxury and Blogs. More
recently, OpenTag has been extended to AEM powered sites including Cars. The document on the link below summarises the status of Opentag
implementation across the main TCUK platforms:

https://docs.google.com/a/telegraph.co.uk/spreadsheet/ccc?key=0AoODymutT-wqdHNoRktsYUJpRXVoZTlyWU1iaHc0MWc&usp=drive_web#gid=0

For the specific AEM implementation, please see :


https://docs.google.com/a/telegraph.co.uk/document/d/1u3qDaVxi7IcSZ3302tPhjKMO4cYeCE6Zh_osC9TdGBY/edit

102
The OpenTag containers used can be summarised as below:

Dev Test UAT Proxy ‘Sandbox’ Prod

Container A Container A Container A Container B Container C

Where:

Container A is shared by all environments except production & Opentag Proxy.


Container B is used by OpenTag Proxy.
Container C is used by Production.

103
Video
Scope
TMG is tightly coupled to Ooyala who provides a video platform that enables the publishing, management (including tagging and playlists), monetisation,
and analysis of online video content. The platform is advertised as modular and extendable via a well documented API - the Backlot API - while providing
real-time analysis capability. Although the platform has proven problematic at times for the Telegraph (ie performance, Analytics discrepancies...), this
association is unlikely to change anytime soon:

At the time of this writing, the contract with Ooyala was just renewed for another 18 months.

Migration to a different video platform would require extensive analysis since TMG's video advertising heavily relies on the Ooyala video players (Flash and
HTML5) as well as the Backlot API.

1. Data feeds

Third party feed provided either as a manifest file, via REST or SOAP providing TMG with the data associated with a video asset

Video feeds
Third party feed provided either as a manifest file, via REST or SOAP providing TMG with the physical location where TMG can source a video asset.

1. Tagging
The design that will enable the Strategy to be set by project URS will be presented to TRS in a separate session. For the video ingest discussion,
we will assume that tagging will be possible at the time of ingest from a pool of existing tags.

2. Live video content

Current video Sources

Currently Videos have several different sources for TMG:

1. Third party video feeds (existing feeds include ITN, APN, MyMovies)
2. TMG Internal (from Studios , commissioned from third parties or via mobile devices)

Current ingest process

Steps:

1. Third party feeds


All videos included in a feed are uploaded to Ooyala including assets that are not used resulting in garbage content staying in Ooyala forever.
2. Internal videos
Manual upload to Ooyala by the editorial team of video assets at a specific size and quality (pre-defined mezzanine file).

Sync script
A sync script exists between Ooyala and Escenic

Film (issues surfaced by Film)

Press Association
PA has been selected as the data source for the Film channel

Rights
Because of rights and contracts in the UK (we are only allowed to show the videos from PA during UK cinematic screening), the video assets will
NOT be sourced from the Press Association Feed but will be uploaded manually

Entity Creation
The process for creating a Film entity page would therefore be result in this horrific manual scenario

Workflow changes

Options

Option 1

Option 2

Tactical Approach

Front end styling

104
Dynamic Image Filters
Introduction
Quickstart
DIF Components
1. Image Filters
2. Image Transformers
Defining a New Image Transformer
3. Image Transformer Alias
Defining a New Image Transformer Alias
4. Image Servlets
How URLS are transformed
URL Transformer Services
Available Image Transformers
Technologies Used

Introduction
Dynamic Image Filters (DIF) allow content authors and template creators to dynamically and on-the-fly apply filters & effects to images without any manual
backend processing (e.g. Photoshop) or the storage of additional rendition/assets.

Original Image Image with Twirl, Colour Shif

Previously, to display a blurred image to users, content authors would be required to take the original image, apply Photoshop effects, upload this to the
AEM DAM and wait for AEM to generate the different sized renditions of the new blurred image. DIF utilises several pieces of technology to ensure these
manual steps are now automated, the images are responsively delivered and renditions do not become unmanageable.

Quickstart
Use any image as before (call directly, embed in an <img> tag etc.) but change the image path URL from:

<filename>.<extension>

to

<filename>-<renditionSize>_<imageTransformAlias>.<extension>

Note: Image transforms are limited to only work if you include the rendition size. For example, /fileName_myAlias.jpg will not work - /fileName-
small_myAlias.jpg is needed.

An Image Transformer Alias is all that is needed start transforming your image. The alias allows you to wrap several filters and their settings, such as 'blur
50%, grayscale and rotate the image 90 degrees' in one easy to call alias such as 'myfilter'. You can then call your image using:

Original Image http://localhost/content/dam/toaster.jpg

Original Image with TMG rendition size selector http://localhost/content/dam/toaster-xlarge.jpg

105
Original Image with TMG rendition size selector and Transformer Alias http://localhost/content/dam/toaster-xlarge_myfilter.jpg

Although DIF comes with many predefined Image Filters, DIF does not come with any aliases. See Defining a New Image Transformer Alias for
instructions on defining your first alias.

DIF Components
1. Image Filters
Image Filters process images and apply the complicated mathematics responsible for of turning one image into another (such as blurring, distortion etc).
Image Filters are exposed for use by creating a wrapper around them, called Image Transformers.

DIF utilises some basic filters from AEM and more advanced filters from the JH Labs Java Image Filter libraries. There are many more filters available
in JH Labs Java Image Filter that are not currently implemented in DIF. However, all that is needed to expose them is the implementation of an Image
Transformer. See Defining a New Image Transformer.

2. Image Transformers
Image Transformers expose the Image Filters as a named OSGI configuration, with standard properties. DIF utilises Named Transform Image Servlet from
ACS AEM Commons to provide this functionality.

Defining a New Image Transformer


In this example, we will create an Image Transformer that scales an image. Again, note we will not be implementing the actual code to do the image
transform. We will use third party libraries to do this.

Step Task

1. Create a new Java class that implements com.adobe.acs.commons.images.ImageTransformer. In this example, we will call it
'ScaleTransformer.java'

@Component(label = "Image Transformer - Scale")


@Properties({ @Property(name = ImageTransformer.PROP_TYPE, value = ScaleTransformer.TYPE,
propertyPrivate = true) })
@Service
public class ScaleTransformer implements ImageTransformer

2. Ensure the new class has a static string 'TYPE'. The value of this is used to refer to the Image Transformer in any Image Transformer Aliases.

static final String TYPE = "scale";

3. Define parameters that should/could be used to pass along to the code that is doing the image transform. These parameters can then be set
by a user in an Image Transformer Aliases.

Ensure the parameters are read and consider using a default (such as 0) if no value is specified in the Alias.

private static final String KEY_SCALEAMOUNT = "amount";

...

final int scaleAmount = properties.get(KEY_SCALEAMOUNT, 0);

4. Finally, set up the Image Filter (using a third party library), pass it any necessary parameters, and apply the transformation. Return it as a new
layer.

@Override
public final Layer transform(final Layer layer, final ValueMap properties) {
final int scaleAmount = properties.get(KEY_SCALEAMOUNT, 0);

106
final ScaleFilter scaleFilter = new ScaleFilter();
scaleFilter.setScaleAmount(scaleAmount);
Layer newScaledLayer = scaleFilter.scale(layer);
return new Layer(newScaledLayer);
}

5. The completed Java class can be seen here by selecting 'Expand source':

package my.image.transformers;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.resource.ValueMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.adobe.acs.commons.images.ImageTransformer;
import com.day.image.Layer;
import my.third.party.ScaleFilter;
@Component(label = "Image Transformer - Scale")
@Properties({ @Property(name = ImageTransformer.PROP_TYPE, value = ScaleTransformer.TYPE,
propertyPrivate = true) })
@Service
public class ScaleTransformer implements ImageTransformer {
private static final Logger log = LoggerFactory.getLogger(ScaleTransformer.class);
static final String TYPE = "scale";
private static final String KEY_SCALEAMOUNT = "amount";
@Override
public final Layer transform(final Layer layer, final ValueMap properties) {
final int scaleAmount = properties.get(KEY_SCALEAMOUNT, 0);
final ScaleFilter scaleFilter = new ScaleFilter();
scaleFilter.setScaleAmount(scaleAmount);
Layer newScaledLayer = scaleFilter.scale(layer);
return new Layer(newScaledLayer);

}
}

6. Once deployed, this new Image Transformer may be used in any Image Transformer Aliases (note how we use scale and amount as specified
in the class):

3. Image Transformer Alias


Image Transformer Aliases allow the grouping of image transformers and image transformer properties into one easily addressable alias. This allows
effects and settings to be quickly and repeatedly used.

Defining a New Image Transformer Alias


In this example, we will create an Image Transformer Alias called 'mytransform' that applies blur, grayscale and rotation to any image.

Step Task

1. Navigate to http://localhost:4502/system/console/configMgr/com.adobe.acs.commons.images.impl.NamedImageTransformerImpl

2. Specify the alias name (transform name).

107
3. Specify the Image Transformers to be used and any corresponding settings. In this example, we apply a Gaussian blur (and specify its radius or 'strength')

(other blur algorithms are available, see here), a grayscale transform and a rotate transform.

4. Press save to commit your transform settings.

5. Test your new Image Transformation Alias

Image URL http://localhost/content/dam/toaster-medium.jpg

Image with Transformer Alias URL http://localhost/content/dam/toaster-medium_mytransform.jpg

4. Image Servlets
DIF utilises Sling Selectors to ensure Image Transformers are easily accessible (and SEO friendly) by using Image Transformer Aliases in the image URL.

How URLS are transformed


When www.telegraph.co.uk/content/dam/toaster-large_mytransform.jpg is accessed, the following takes place behind the scenes:

108
Step Old URL New URL Process

1. /content/dam/toaster-large_mytransform /content/dam/toaster.jpg/jcr:content/renditions/cq ImageRenditionSelectorService assess which rendition to use,


.jpg 5dam.web.480.480_mytransform.jpg based on the final -<size>.

The appropriate rendition is then selected (depending on OSGI


configuration 'TMG - Image Redirect Service') and the URL is
transformed.

The DIF Image Transformation Alias is left at the end of the path,
before the file extension.

2. /content/dam/toaster.jpg/jcr:content /content/dam/toaster.jpg/jcr:content/renditions/cq ImageTransformerPathService is then responsible for taking the


/renditions/cq5dam.web.480.480_mytra 5dam.web.480.480.jpg.transform/mytransform Alias and turning it into an internally recognised selector,
nsform.jpg /image.jpg
in the format .transformer/aliasName/image.jpg

URL Transformer Services


The two services used in conjunction to ensure the correct rendition and correct image transformer is used are:

Class Name Purpose

uk.co.telegraph.core.foundation. Service that resolves path to a rendition based on a suffix appended to image path just before the
image.ImageRenditionSelectorService extension. Preserves an image transformer name when present in the path.

Example: given an image with path /content/dam/image-name.jpg by configuring breakpoint of


small=cq.small.rendition when /content/dam/image-name-small.jpg is requested

/content/dam/image-name.jpg/jcr:content/renditions/cq.small.rendition will be returned.

uk.co.telegraph.core.foundation. Service that resolves a path based on a suffix appended to image path just before the extension,
image.ImageTransformerPathService using the given suffix transform name to form the new path.

When no transform name is found in the given path, does nothing and returns the given path.

Example: given image path to image rendition with a suffix '_blur' when /content/dam/film/Wild
/Appalachian-Trail.jpg/jcr:content/renditions/cq5dam.web.1280.1280_blur.jpeg

is requested then /content/dam/film/Wild/Appalachian-Trail.jpg/jcr:content/renditions/cq5dam.web.


1280.1280.jpeg.transform/blur/image.jpg will be returned.

Available Image Transformers


Image filters that have been implemented in DIF (by creating an Image Transformer wrapper). These are thus available to be used in Image Transform
Aliases:

Name Effect Parameters Example

boxblur Blur effect. Fast and approximates (but wont look as good radius
as) a Gaussian blur
iterations

gaussian Blur effect. Slower but best looking blur effect available. radius
blur

greyscale Converts the image to greyscale. <none> greyscale

resize Resizes the image. width=[width in px] resize:width=200


height=[height in px] resize:height=300
Accepts two Integer params: height and width. upscale=true/false resize:
width=400&height=400&upsc
The other dimension scale automatically to maintain the ale=true
original aspect ratio.

If the original image is smaller than the configured


dimensions the image won’t be resized.

Upscale param can be set to true to allow upscaling


smaller images.

rotate Rotates the image a given number of degrees degrees=[degrees to rotate] rotate:degrees=180

crop Crops the image to the specified bounds. bounds=[x,y,width,height] crop:bounds=150,


smart=true/false (defaults to true) 100,100,100
Smart bounding will attempt to shift the specified crop- crop:bounds=150,
zone to fit within the image dimensions 100,100,100&smart=false

109
if the crop-zone falls outside the images dimensions.

quality Adjusts the quality of the output image. quality=[0..100] (0 is lowest quality, 100 is highest) quality:quality=75
If quality number is “out of bounds”, 82 will be used.
Only works on JPEG and GIF image types (PNG is not
supported).

adjust Adjusts the brightness and contrast of the image. brightness=[-255 to 255] (dark to light) adjust:
contrast=[0.0 to positive float] (< 1.0 lowers contrast and > 1.0 brightness=120&contrast=0.3
enhances contrast)

multiply Multiplies all of the RGB values of the image against a alpha=[0.0..1.0] (Opacity, percentage) multiply:alpha=.
base color. color=[000000..FFFFFF] 75&color=3366FF
multiply:alpha=.
Follows specification of Multiply blend from Adobe (Hex Color for use in blending; if specified, overrides all red 75&red=51&green=102&blue
Photoshop /green/blue parameters) =255
red=[0..255] (Red value for use in blending; not required if using
(http://helpx.adobe.com/after-effects/using/blending- color parameter; default value: 255)
modes-layer-styles.html#Multiply) green=[0..255] (Green value for use in blending; not required if
using color parameter; default value: 255)
blue=[0..255] (Blue value for use in blending; not required if
using color parameter; default value: 255)

rgb-shift Shifts the color of all pixels in an image. Parameters are a red=[-1.0..1.0] (Percentage, amount of red to shift the image) rgb-shift:red=.5&green=.
percentage of R/G/B value. green=[-1.0..1.0] (Percentage, amount of green to shift the 25&blue=-.60
image)
Omit or set R/G/B shift value to 0 to keep current value. blue=[-1.0..1.0] (Percentage, amount of blue to shift the image)

If any element of the color is shifted beyond min/max


allowed (0..255) the min/max value is used.

Based on http://pixastic.com/lib/docs/actions/coloradjust/

Technologies Used
Named Transform Image Servlet from ACS AEM Commons
Sling Selectors
JH Labs Java Image Filters
Responsive Rendition Sizes from TMG

110
Param Crop
General
This page describes our custom image transformer, which can be used for cropping images, based on parameters in the URL.

Overall
To implement crop with URL parameters, ACS AEM Commons project was forked and it is available here: https://stash.aws.telegraph.co.uk/projects
/CHEET/repos/acs-aem-commons/browse

This repository contains additional ImageTransformer which allows to put in the image URL name of the transformer, crop X coordinate, crop Y coordinate,
crop width and crop height. All values, by default, are in the base point units.

Let's say that image with size 1000 x 750 should be cropped. We want to start cropping at 100px from the left, and 150px from the top. New image should
have width of 500 pixels and height should be set to 250pixels.

To get such image URL must look like that:

/path/to/your/original/image_paramcrop_1000_2000_5000_3333.png

I will explain now part which is bold:

paramcrop - this is the name of the transformer, if you will use default configuration, it has to be named like that
1000 - this is X coordinate, where crop should start. By default it is in base point unit so it will be 1000/10000 of the original image width, so it is
10%. Width of our image is 1000px, so the result will be 100px.
2000 - this is the Y coordinate, where crop should start. By default it is in base point unit so it will be 2000/10000 of the original image height, so it
will be 20%. Height of our image is 750px, so the result will be 150px.
5000 - this is the width of our cropped image. By default it is in base point unit so it will be 5000/10000 of the original image width, so it will 50%.
Width of our image is 1000px, so new width will be 500 px.
3333 - this is the height of our cropped image. By default it is in base point unit so it will be 333/10000 of the original image height, so it will
around 33%. Height of our image is 750px, so new height will be 250px.

Configuration
Image transformer configuration can be added in OSGI Configuration manager to ACS AEM Commons - Named Image Transformer Factory.

Default configuration looks like this:

What is important, without addUrlParams=true, crop won't work, because parameters from the URL won't be added. If you want to apply the same crop for
every image, please use default crop transformer, and it's bounds parameter.

Size
There is also possibility to configure param crop to put pixels instead of base point unit.

There are two parameters to configure that:

xyCoordinatesUnit - if will be set to px, X and Y coordinates will be in pixels


sizeUnit - if will be set to px, width and height will be in pixels

So if the Image transformers in configuration will be: paramcrop:addUrlParams=true&xyCoordinatesUnit=px&sizeUnit=true

then if we will take image from previous example:

/path/to/your/original/image_paramcrop_100_200_500_333.png

Crop will start at 100px from the left and 200 px from the top, and it will have 500 px width and 333 px height.

111
Important

Please be careful with using crop sizes in pixels, as the same parameters are also applied for renditions. Given crop parameters will be invalid
for rendition which size is 96x96. In such case that rendition won't be cropped.

112
Embeds

113
Image renditions offloading to Amazon web services
General
This page describes the journey on externalising image renditions generation using aws lambda function(s) and integration to AEM.

AWS lambda code can be found here. It has nodejs javascript function which is using grahicsmagick & async libraries to generate renditions.

AEM code can be found here. This is ongoing development which can be merged to develop at any point of time to go live with this approach.

Approach 1

Diagram explained end to end.


1. User uploads image to AEM, AEM triggers DAM Update Asset workflow which uploads an image to S3 bucket using aws java sdk.
2. Upload to s3 event triggers lambda function to generate thumbnail renditions.
3. Lambda function generates thumbnail renditions, stores them in the other S3 bucket and writes a message to SQS.
4. AEM polls the queue to receive the message. If the message says success aem deletes the message and continue to next step. if message
doesn't say success, it deletes the message and suspends the workflow.

For each 7 web renditions, AEM repeats the following steps as a part of custom workflow step

It calls web renditions lambda with different width and height.


lambda generates web rendition and stores in other S3 bucket.
returns the message to aem.
aem checks the message to see if the rendition generation successful, if success it moves on to next step else it suspends the workflow.

5. AEM downloads all 11 renditions to aem and creates renditions nodes.

Pros
Less CPU load as aem doesn't need to generate renditions.
It is scalable.
It's cheap compare to any other offloading services.

Cons

114
It takes a very long time to have renditions available back in aem i.e. finishing the workflow. It's 10 times slower when bulk images(medium to large
size) are uploaded to aem using aem out of the box workflow.

Reasons behind slowness & solution to consider


Current workflow has so many steps to generate renditions.
Solution : Implement fanout in aws which can generate all renditions in parallel reducing number of workflow steps.
It is using SQS which is a polling queue and AEM has to poll to see if the thumbnail renditions are generated.
Solution : Remove SQS completely from the design by decoupling s3 and lambda.
AEM is calling web rendition generation lambda function 7 times sequentially to generate web renditions hence we are not taking advantage of
aws parallel execution using this design.
Solution : Fanout should reduce number of steps and we can take advantage of aws parallel execution capability.
AEM downloads all 11 renditions from S3 and create nodes in cq dam.
Solution : Add a logic in ImageRedirectServlet in telegraph-component codebase to serve image from s3 instead of serving from dam. Some
research is required to support crop and blur if we do this. JIRA tickets AEM-4494, AEM-4531

Approach 2 - Above 3 solutions implemented.

Approach 2

Diagram explained end to end.

1. User uploads image to AEM, AEM triggers DAM Update Asset workflow which uploads an image to S3 bucket using aws java sdk.
2. AEM calls master lambda function, which invokes 8 lambda functions in parallel, each web lambda generates web rendition of different sizes and
stores it in another s3 bucket. thumbnail lambda generates 4 thumbnail renditions and stores them in another s3 bucket.
3. AEM gets the response from master lambda, it checks the response message to know if the result is success, if it is then it moves on to next step,
if not then it suspends the workflow.
4. AEM downloads all 11 renditions back to aem and finishes workflow.

Note : In the above approach, rather than having each individual function for web rendition, we would have used just one lambda and call it parallel with
different width & height. The reason behind not doing this is, "At any point of time, we can have 1000 parallel requests per lambda". To maximize number
of parallel requests, multiple web lambdas are used.

Comparison with AEM after implementing above approach

AEM

Uploaded 78 images(medium to large size) to dam using cq - It took around 2-3 minutes.

AEM-AWS

Uploaded same 78 images using approach 2 and it took around 1-2 minutes.

How to Deploy AWS lambda code

Download code from the stash repository


Make a zip using js & node_modules, rename it to match the name of the js file.

115
Login to AWS account.
Navigate to Lambda
Go to Code tab and upload the zip file.

Configuring AWS parameters in AEM components before deploying AEM code which has integration with AWS approach.

There are default values which will be used if nothing is configured.

116
Processes

117
Ways of Working

118
Mocks Process
Currently we use a standalone ‘Sandbox’ for developing mock versions of the components and pages before they are created as usable component and
pages in AEM.

This was mainly done because of it not requiring a maven build to see the changes.

In AEM 6 we now have options to overcome the need to constantly deploy code and even have a livereload even take place when we make our changes (h
ttps://confluence.aws.telegraph.co.uk/display/Engineering/Configuring+LiveReload+to+work+with+local+AEM).

In addition to the ability to push the code easily into AEM new additions to Sightly gives us the new Javascript USE-API that allows front end developers to
write the java response models/objects in Javascript to be consumed by the Sightly html template engine. (http://docs.adobe.com/docs/en/aem/6-0/develop
/sightly/use-api-in-javascript.html)

The Javascript USE-API is not ready for use on the live site but could work very nicely to improve the way we look at prototyping.

This API inside of Sightly can give us more cohesion between the frontend and backend developers as data structures can more easily be agreed upon
and followed from the beginning of any component or page.

Example
Inside the html file of telegraph/core/commons/components/imageGroup change

data-sly-use.imagegroup="uk.co.telegraph.core.article.gallery.ImageGroupModel"

to

data-sly-use.imagegroup="imageGroup.js"

In the same directory add a new file called imageGroup.js and place the code below inside it

use(function () {
var imagegroup = {
imageAssets: [{
smallRenditionItem: {
src: "/content/dam/cars/2014-Fiat-Punto-1-thumbnail.JPG",
height: "200",
width: "320"
},
renditionsJson: "[{'src':'/content/dam/cars/2014-Fiat-Punto-1-thumbnail.JPG','width':
140,'height':87},{'src':'/content/dam/cars/2014-Fiat-Punto-1-xsmall.JPG','width':160,'height':100},{'src':'
/content/dam/cars/2014-Fiat-Punto-1-small.JPG','width':320,'height':200},{'src':'/content/dam/cars/2014-Fiat-
Punto-1-medium.JPG','width':480,'height':300},{'src':'/content/dam/cars/2014-Fiat-Punto-1-large.JPG','width':
720,'height':450},{'src':'/content/dam/cars/2014-Fiat-Punto-1-xlarge.JPG','width':1280,'height':800}]",
aspectRatio: "1.60",
caption: "caption",
copyright: "© 2015"
},{
smallRenditionItem: {
src: "/content/dam/cars/2014-Fiat-Punto-2-thumbnail.Jpg",
height: "200",
width: "320"
},
renditionsJson: "[{'src':'/content/dam/cars/2014-Fiat-Punto-2-thumbnail.Jpg','width':
140,'height':87},{'src':'/content/dam/cars/2014-Fiat-Punto-2-xsmall.Jpg','width':160,'height':100},{'src':'
/content/dam/cars/2014-Fiat-Punto-2-small.Jpg','width':320,'height':200},{'src':'/content/dam/cars/2014-Fiat-
Punto-2-medium.Jpg','width':480,'height':300},{'src':'/content/dam/cars/2014-Fiat-Punto-2-large.Jpg','width':
720,'height':450},{'src':'/content/dam/cars/2014-Fiat-Punto-2-xlarge.Jpg','width':1280,'height':800}]",
aspectRatio: "1.60",
caption: "caption",
copyright: "© 2015"

119
}]
};

return imagegroup;
});

When you build and use the component now it will take the images from the JSON object returned by the Javascript and ignore the images inside of the
dialog.xml

Using this method to call an API model

Sightly syntax for implementing API model via getRequest

data-sly-use.imagegroup="${'aem.cq.getRequest.js' @url='http://your.api.endpoint/here'}"

New Development Workflow


Data structure agreed with Java and UI developers.
Attach data structure to ticket to help testers know the data structure needed.
UI developers build the markup and the styling inside the AEM file structure.
UI developers use the Javascript USE-API to populate the markup based on the agreed structure above.
Whilst the UI developers are working JAVA developers write the backend models.
When both the JAVA and UI work is complete the JAVA developer can simply replace the JS call with the call to the JAVA model.
Alternatively the developer could add a switch toggle between the real (JAVA CLASS) and the mocked data(JS).

120
AEM Clientlib inheritance
All the sites for the Lifestyle (Monza) project should all have the same CSS,JS etc but there will be cases where we will need to do changes on a site by
site basis. For this we should use the clientlib embed and dependancy properties.

The basic principle for this is that we will have a clientlib for Lifestyle (Monza) and then any changes for the channels/sites underneath its umbrella will
have there own clientlib (i.e. lifestyle-fashion) only containing the changes that will have an embedded dependancy of lifestyle.

I have mocked this up using the cars styles placing a cars-child clientlib inside of cars. Extract cars.zip and install into your local AEM to see this in action.

121
Projects

122
Data Registration

123
Solution

124
Infrastructure

125
Process Flows

126
AEM Structure

127
Administration
(include user access and user roles)

128
Escenic Changes

129
Integration Points

130
Analytics and Segmentation

131
Core API

132
Data Registration: Adobe Campaign

133
Data Registration: Script Management

134
Proxy

135
Technical Debt

136
Archive (To be deleted)

137
Launching a new TMG channel
Overarching Principles
Third parties that act as agents of TMG extend the technology group. As such:

They must be involved in the analysis and requirement phase


They must adhere to TMG’s guiding principles including Enterprise Non-Functional Requirements
It must adhere to TMG's development principles and methodologies
It must allow for its development to be incorporated back into the CORE stream when possible to prevent the proliferation and support of
a large number of component versions

Technology Governance
The Core Team provides overall governance on all platform matters:

a. It is responsible for the creation and support of the Core platform components (including Core bundles and custom core bundles)
b. It is responsible for the installation and support of third party platform components
c. It is responsible for Channel Setup and the delivery of an AEM stack that can be maintained and ran by channel teams (wether they are
internal or external). This includes:
i. Define (with the Product Managers) the data schema adequate to support the new channel at MVP and Target states
ii. Provide the AEM Canonical Data mapping which will allow for integration with NITRO
d. Management of infrastructure and environment specifications. Provisioning of a new channel’s infrastructure must be validated by the
CORE Team. Any changes or requests outside of the specifications provided must be validated by the CORE team and presented at
TRS.

CORE Inheritance
By default, Channels inherit the overall platform architecture including technology stack, users types and information architecture.
However, specific requirements are to be assessed at Channel setup by the CORE Team to identify changes to this overarching architecture and
principles.
All changes which have an implicit impact on the Platform must be validated by the CORE Team.

Technology Architecture
1. Environments
2. Content Delivery
3. Caching
4. Backup and Disaster Recovery
5. Testing and support

Information Architecture
1. Define channel specific data schema

Business Architecture
1. Identify Capabilities changes
2. Identify Workflows changes

Application Architecture
1. Component gap analysis and backlog building
2. Channel specific integration points

138
404 pages

This page describes the strategy for delivering 404 pages across the AEM platform.

Functional Requirements
When an unknown url is requested on the AEM platform the following should happen.

A 404 response code will be returned to the requester


The requested URL will stay in the browser location
The window title will indicate this is a 404 page
If the URL that returns a 404 contains a recognisable channel hosted on AEM:
the response page will display apology text with options for users next action
this will be the same text on every channel, so any edits only need to be done in one place
the response page will display channel specific masthead and navigation (this will be the same as delivered on the channel pages)
the response page will display channel specific footer (this will be the same as delivered on the channel pages)
the response page will display channel specific list of 10 "latest" content items
"latest" does not need to be up to the minute content - we could cache the results for some time
If the url does not contain a recognisable channel then initially the standard escenic 404 will be displayed
once the root of the telegraph.co.uk domain is hosted on AEM (when this fits in the roadmap is tbc) then the default 404 will be from the
news channel (ie. with news branding and news latest content)
It will be possible to display ads on the 404 page
The pages will be responsive and will work with the standard breakpoints defined for the Base v1.1 styling code
Analytics requirements to be confirmed

Design Requirements
Wireframes are visible here:
[CLT-122] Culture - 404 Pages r0.pdf
Visuals are visible here:
[CLT-122] Culture - 404 Pages 1008px r0.jpg
[CLT-122] Culture - 404 Pages 730px r0.jpg
[CLT-122] Culture - 404 Pages 480px r0.jpg

Non-Functional Requirements
The 404 pages should be performant
The 404 pages should be cacheable so that we can limit the possible load generated by a Denial of Service attack

Assumptions
All channel 404 pages will have the same design and component layout
It is understood that providing dynamic content (latest articles and channel navigation) will make the delivery of the 404 slower than if it were a
static HTML page (as per the current Escenic 404)
We can attempt to mitigate this but a dynamic page will inherently always be slower than a static HTML page
It is understood that on creating a new channel in AEM a specific 404 page will need to be configured (or it will default to the standard 404 - either
the escenic 404 or the AEM news 404)
The design will broadly match the basic wireframes that have been supplied

Out of Scope
Search functionality
Links to latest content from other channels
404 pages for any channels not on AEM
404 pages for any channels using AEM but not using the standard base v1.1 codebase

Solution
The Cars site already has a basic solution for this. See here for the page: http://www.telegraph.co.uk/cars/asdfasdf/

The page is stored like any other in AEM, it can contain components that pull in lists of content or text and images.

139
Instead using "Error page" template that was used on cars use "Generic Error Page" template in mentioned structure for all channels using the standard
base v1.1 codebase

This page is delivered whenever there is a 404, once a 404 has been delivered once then the 404 itself can come from cache.

We can set the cache time for the 404 so the "latest" content doesn't become too stale, for example if we set the cache time to 30 minutes the first 404
every 30 minutes would recompile the page for all subsequent 404s.

The following flow will be followed:

1. A URL is requested
2. If present in Dispatcher cache then the page is delivered as normal
3. If it it not in Cache then the Dispatcher requests it of the Publisher
4. The Publisher determines if the request is for a valid page or if it should return a 404
5. Valid pages are compiled, sent to the Dispatcher and cached there before passing on the requester
6. If its a 404 response the 404 is sent back to the Dispatcher
7. The Dispatcher checks if there is a valid Channel in the requested URL (if not then if defaults to News) and the request for the 404 page is made
8. First the Dispatcher checks if the channel 404 page is in cache, if so it can be delivered straight from there to the requester
9. If not then it asks the Publisher to compile the channel 404 page which can then be cached at the Dispatcher before delivering to the requester

140
NOTE: As mentioned in the Requirements until the root telegraph.co.uk is moved to AEM step 7 will send the user to the Escenic 404 page, the
diagram shows the target state when the root of the domain is delivered by AEM

Expected Implementation
It is expected that this will be implemented as an AEM Template that will be available to all channels. The template will contain the default text and a list
component that will have to be configured per channel when the page is created.

141
Moving channels from Escenic to AEM
This page describes the process and considerations for moving a channel (or subsection) from Escenic to AEM. It is work in Progress

NOTE: This page assumes that all the development work has been done for the channel on AEM and the page structure is already set
up. Essentially you have 2 sites and need to switch delivery from one platform to the other.

The first two sections below are key to understanding the challenges involved and the reasoning behind the recommendations for moving channels.

1. Akamai origin direction


Our CDN Akamai handles all URLs requested of us and decides which origin server to send it to. The Origin servers we currently have are Escenic 4.3,
Escenic 5.3, Escenic 5.4, AEM, .Net, Wordpress etc.

This direction is performed based on the URL pattern requested, for example (most specific match wins, * denotes anything underneath this URL stem):

URL pattern Origin server Akamai directs traffic to

http://www.telegraph.co.uk/* Escenic 4.3

http://www.telegraph.co.uk/travel/ Escenic 5.3

http://www.telegraph.co.uk/travel/cruises/*

http://www.telegraph.co.uk/travel/hotel/*

http://www.telegraph.co.uk/travel/destination/*

http://www.telegraph.co.uk/subscriptions/*

http://www.telegraph.co.uk/luxury/* Escenic 5.4

http://blogs.telegraph.co.uk/* Wordpress

http://my.telegraph.co.uk/* Wordpress (Buddy Press)

http://fashion.telegraph.co.uk/* .Net

http://www.telegraph.co.uk/cars/* AEM

http://www.telegraph.co.uk/best/*

http://www.telegraph.co.uk/film/*

It is key to understand that the URL stem is the thing that defines which platform the page will be delivered from.

2. Content Migration strategies


If we consider there are 3 types of content on Escenic.

New content: Articles that will be written after the new AEM channel is Live (and while getting ready for launch)
Old valued content: Articles that are published through Escenic and a still driving good traffic
Old archive content: The rest of the archive published on Escenic

New Content

This content will be written on the lead up to launch and post launch directly in the AEM interface. It will make use of all AEM functionality that we have
built for launch, and will show as per the new designs for this channel. All content will authored with the new templates in mind, images etc will fit the
template.

Old valued content

142
This content will have to be recreated in AEM. This will allow us to gain the best presentation for these valued articles. They will have to be manually cut
and paste from Escenic to AEM. Some parts of the content may require resourcing, for example the original images displayed on Escenic/.Net may not be
the right size/ratio for the new AEM templates. Once transferred to AEM the article can be edited the same as New content.

We will have to redirect old URLs to the new AEM URLs. I expect this will have to be managed by Operations on an article by article basis.

Old archive content

There are 2 recommendations for this:

1. The target architecture for this is to expose Escenic content to AEM through the Content API. Requests for old URLs should be recognised and AEM
should deliver a generic page that will pull in the article content from the API and present it through AEM.

2. The target described above will not be in place for the first set of channels moving to AEM. In the short term then it is recommended that we redirect
any old article URLs to the front page of the corresponding channel.

NOTE: there is a desire from editorial and product to maintain any old article URLs - ie. deliver them from the old site/platform. The points below
will describe why this may prove difficult.

3. Moving Channels
There are a few different cases of moving sections that need to be considered.

1. Moving an Escenic channel to AEM keeping the channel name and URL the same (probably the majority of moves ie. http://www.telegraph.co.uk/
health/ to http://www.telegraph.co.uk/health/)
2. Moving a subsection of an Escenic channel to an AEM channel (eg. http://www.telegraph.co.uk/sport/cycling/ to http://www.telegraph.co.uk/cycling
/)
3. Moving a subdomain site from Escenic/.Net to an AEM channel (http://fashion.telegraph.co.uk to http://www.telegraph.co.uk/fashion/

3.1 Channel to Channel (maintaining the url)


Lets take the example of moving:

Escenic (from) AEM (to)

http://www.telegraph.co.uk/health/ http://www.telegraph.co.uk/health/

As the URLs are the same there is no option* but to point /health/ to the AEM platform so all URLs that begin /health will be delivered by the AEM platform.

The consequences of this are that:

1. Any redirects for /health URLs will have to be managed on the AEM platform (as /health will be moved to there).
2. Any old article URLs will cease to work (unless we can find a URL pattern that we can keep on the Escenic platform for the old archive content)
3. The Syndication process will no longer include content for this channel
4. The Site Search will no longer include content from this channel
5. The Sitemaps will no longer include content from this channel

*NOTE: There is a possible way to deliver archive content on Escenic and new Content on AEM as long as a rule can be found to distinguish the
old URLs from the new URLs. For example if we can always say that a URL that ends with ".html" will always be delivered from Escenic then
this could be put in to Akamai configuration (with appropriate testing).

3.2 Subsection to Channel


Lets take the example of moving:

Escenic (from) AEM (to)

http://www.telegraph.co.uk/sport/cycling/ http://www.telegraph.co.uk/cycling/

As the URLs on the new AEM site are previously unused URLs on Escenic it is easy for us to have the 2 URLs running in parallel delivered by the different
platforms.

The consequences of this are that:

1.

143
1. Any redirects for sections or manually migrated old valued content will have to be managed on the Escenic platform (as /sport will still be
delivered there)
2. Old archive content not migrated to AEM could still be delivered through Escenic however:
a. Navigation on the old Escenic site may need changing to point at AEM pages
b. Some components and Page furniture on the old Escenic site may need changing or removing
c. Analytics for this channel will be split across different URLs and will require extra work to collate
d. Advertising may have to do more work to book ads across a channel that is split across multiple platforms
e. The Syndication process will no longer include content for this channel
f. The Site Search will no longer include content from this channel
g. The Sitemaps will no longer include content from this channel

3.3 Subdomain to Channel (specific to Fashion)


Lets take the example of moving:

Escenic (from) AEM (to)

http://fashion.telegraph.co.uk/ http://www.telegraph.co.uk/fashion/

As the URLs on the new AEM site are previously unused URLs on .Net it is easy for us to have the 2 URLs running in parallel delivered by the different
platforms.

The consequences of this are that:

1. Any redirects for sections or manually migrated old valued content will have to be managed on the .Net platform (as fashion.telegraph.co.uk will
still be delivered there)
2. Old archive content not migrated to AEM could still be delivered through .Net however:
a. Navigation on the old .Net site may need changing to point at AEM pages
b. Some components and Page furniture on the old .Net site may need changing or removing
c. Analytics for this channel will be split across different URLs and will require extra work to collate
d. Advertising may have to do more work to book ads across a channel that is split across multiple platforms
e. The Syndication process will no longer include content for this channel
f. The Site Search will no longer include content from this channel
g. The Sitemaps will no longer include content from this channel

144
Risks and Issues
Issues
Description Owner Impact Total Actions

Release process is cumbersome and Unknown 2 AMBER SR3 team has been working on improvements. This has been delayed by
costly User CI environment investigation and fixes.
(porterc)

Unstable Continuous Integration Unknown 3 AMBER Head of Engineering is seeking external expertise to fix the release
environment preventing fast releases to User process; a specialist is due to start on 20/04. Conduct manual integration
production from taking place (porterc) testing to enable quick deployments on production while environment is
being fixed

Risks
Description Owner Probability Impact Total Actions

Platform stability and performance: Stability and performance is unknown / unproven. 2 5 10


Most recent performance test run again was worse than previously with page loads 3x MEDIUM
slower than in January 2015.

Can't do releases without stopping environment. Current release requires editors to Unknown 5 5 25 Not
stop publishing content during the release which can take over an hour. For busy User HIGH decided.
sections like News this is not acceptable. (holdichk)

145
Web Font Register
This page contains a register of web fonts* used in the AEM environment. (not including iconfont/font-awsome)

* Web Fonts: Unlike web safe fonts, web fonts are not pre-installed on the user's system. The fonts are downloaded by the user's browser while
rendering the webpage, and then applied to your text. The main drawbacks of using web fonts is it will slow your site's load time.

Font download behaviour


Web Font behaviour differs on the main user agents...

IE immediately renders text with the fallback font and re-renders it once the font download is complete.
Firefox holds font rendering for up to 3 seconds, after which it uses a fallback font, and once the font download has finished it re-renders the text
once more with the downloaded font.
Chrome and Safari hold font rendering until the font download is complete.

(see https://www.igvita.com/2014/01/31/optimizing-web-font-rendering-performance/ for more info)

Font optimisations
Font Subsetting: create font files that only contain the characters needed (use a hosted service like google fonts or create font files using a
service like Font Squirrel to host locally)
Compression: insure font files are served compressed - currently the dispatcher configuration does not compress fonts (WOFF is pre-
compressed) but this serves to Akami. What is the Akami configuration?
Caching: insure font files have far future expire headers - What are the Akami cache settings?

Font frequency

"Austin News Deck Roman"


article-body-image
article-body-list
article-body-standfirst
lead-asset
list-of-links
list-of-entities
polarme
quote
standfirst
video-player

"Austin News Deck Semibold"


gallery-article
section-navigation
list-of-entities
list-of-links
hero-block
headline

"Austin News Deck Medium Italic"


list-of-links
article-body-list
quote
author (post AEM-1249)
image-gallery (post AEM-1249)

"Austin News Text Semibold"


image-gallery
logo-bar
gallery-teaser
author

146
"Austin News Text Italic" (see AEM-1249)
author
image-gallery

"Austin News Text Roman"


author
article-body-text
list-of-links
breadcrumbs
image-gallery
inline-content

"Telesans Text Regular"


article-body-image
article-body-text
article-date
gallery-teaser
hero-block
image-gallery
lead-asset
list-of-entities
polarme
social-share
video-player
article
gallery-article

"Telesans Text bold"


list-of-links
page-article
list-of-tags

Channel Font (eg. Mariam for beauty)


headline
hero block

Candidates for consolidation:

Austin News Text Italic + Austin News Medium Italic


This has been consolidated

Telesans Text bold (use telesans text regular with bold font weight?)
It has been decided that this is not a sufficient substitute - Telesans bold will remain

147
Austin News Deck vs News Text
Should consider this (no image available)

One of the Austin news:


Conversation in progress

Candidates for reduction to Latin1


Channel font
Everything not body text?

Font events (recommendation) - stop flicker and improve cached performance


http://www.filamentgroup.com/lab/font-events.html

148
Investigate font optimisation AEM-1708

Channel Headers (e.g. Marian Poster in Fashion Hero Block)


Body fonts (e.g. Austin News Deck in list links)

Channel Headers (e.g. Marian Poster in Fashion Hero Block)


Change Upside Downside Further investigation/Comments

Replace existing text with SVG (Scalable Vector Would this infringe font copyright?
Graphic) Scales Not editable by content Author
No need to embed Needs to be exported from Illustrator - http://jsfiddle.net/clanceyp/sa8fotkf/1/
font at all up front design task
Needs development on existing
component(s) - extend to use
embedded SVG if appropriate

Individual character SVG - to be implemented in ditto the above Maybe difficult to implement - needs spike Is this possible? (needs a spike)
the same way as font-awesome.
Would this infringe font copyright?

How would Authors administer headings


done in this method?

Font Subsetting - use ascii subset We already do this. Do we use this enough? (No!)

Currently it's only on the "Marian Poster"


in Fashion and "Austin News Deck Web *"
in Culture

Saving around 70% This should be extended to all fonts.


over full set
How the browser handles unknown
chars...

http://jsfiddle.net/clanceyp/88jxujvz/1/

http://app.crossbrowsertesting.com
/screenshots/658940?
size=small&type=windowed

Dynamic Font Subsetting - requesting just the We would need to use a hosted third party
characters required reduces the font size service for fonts such as Google WebFonts.
substantially
Potentially slower response times (or setup
e.g. css?family=Josefin+Slab:100: proxy and cache)
latin&text=FASHION

90% saving over ascii

149
Body fonts (e.g. Austin News Deck in list links)
Change Upside Downside Further investigation
/Comments

Implement JavaScript WebFont Loader We can lazy load a font and switch from fallback font to
desired font when the font loads. This gives us more control Possibl
to load fonts used predominantly below the fold after fonts e
used at the top of the page. flicker
when
font
switch
occurs

Consolidate fonts: The designers had a look at this and we Investigate more possible
have recently reduced the amount of fonts needed. We consolidation candidates,
should be mindful of not adding new fonts unless get approval to remove
absolutely necessary though. from UX and remove

Maybe we can remove the single weight fonts such as "Aus


tin News Deck Semibold", "Austin News Text Semibold", "T
elesans Text Bold" and use it's nearest match.

http://web1.aem-dev9.awspreprod.telegraph.co.uk/fashion
/font-test.html

150
Browser Support Matrix
Currently support browser matrix for the AEM site:

TMG Target Browsers - see the "Current" tab

151
Adobe Managed Services
Adobe Contact Details
Name E-Mail Role

Chris Goodman rma32042@adobe.com Project Manager

Opkar Gill ogill@adobe.com Engineer

Amit Gautam jca20105@adobe.com Engineer

Arup Vidyerthy vidyerth@adobe.com Engineer

TMG Contact Details


Name E-Mail Role

Toby Wright toby.wright@telegraph.co.uk Project Sponsor

Dave Sanders dave.sanders@telegraph.co.uk Architect

James Bodkin james.bodkin@telegraph.co.uk Engineer

Ather Mughal ather.mughal@telegraph.co.uk Engineer

152
File lists
Create file list

Title Creator Modified

Reference Material Dave Sanders Nov 08, 2016

153
Reference Material

File Modified

PDF File Book of Architectures - TMG use case - 1.1.pdf Nov 04, 2016 by Dave Sanders

PNG File AEM - Architecture.png Nov 04, 2016 by Dave Sanders

Drag and drop to upload or browse for files

Download All

Links

AEM Environments

AMS Topic List

154
Invalidation Caching Strategy
The first step of this custom invalidation strategy is carried by a preprocessor (uk.co.telegraph.core.commons.listreferences.listeners.
InvalidationServiceListener) on the author instance, it kicks in just before each replication event fires and given the resource to be replicated will take care
of evaluating all the references that will need to be invalidated/re-fetched.

The evaluation is carried through a series of handler services implementing the uk.co.telegraph.core.commons.listreferences.references.handlers.
ReferencesHandler interface; more implementations can be easily added to handle different scenarios.

These create the list (no duplicates) of pages to invalidate/re-fetch.

The list is posted to a servlet (uk.co.telegraph.core.commons.listreferences.components.servlets.FlushReceiverServlet) on the publish instances. This


servlet puts the replicated resource along with the references in a references-map waiting for the actual replication to be finished on the publish.

The replication on the publish instance is monitored through a listener (uk.co.telegraph.core.commons.listreferences.listeners.ReplicationListener) when
the listener fires the replication is completed on the publish and the references-map is accessed and the references put in the queue for invalidation/re-
fetch.

Note: the queue has unique entries to avoid to invalidate/re-fetch the same resource twice if not needed

A scheduled job (uk.co.telegraph.core.commons.listreferences.jobs.FlushQueuesJob) polls and processes elements in the queue.

The job runs every 5 seconds (configurable) and polls batches of 5 elements (configurable); the job posts the elements to the dispatcher for invalidation/re-
fetch.

155
Handlers
There are currently two handlers implemented:

ListComponentHandler: If the node activated is a Page this handler fetches all the pages containing a list component configured with the same tag as the
activated page.

GalleryItemComponent: If the node activated is a Gallery slide this handler fetches the parent Gallery Page the slide belongs to.

156
List with Sling Dynamic Include
Steps performed for SDI Proof of concept.

How SDI works


SDI bundle built and deployed, generated bundle can be found here.
Install the bundle in [AEM-PUBLISH]/system/console/bundles
Configure dispatcher to allow nocache selector.
sudo vi /etc/httpd/dispatcher/dispatcher.any

#allow .nocache selector

/0115 {/type "allow" /glob "GET *.nocache.html *"}


Configure List component in the SDI configuration

"include-filter.config.required_header" will preserve the publish view.


Save the bundle and SSI for list component will be added dynamically in the html view of the page.
More pages on dispatcher will be created with nocache selector implemented by SDI.

157
Metered Paywall
Implementing the Paywall in AEM

Step-by-step guide
The basic POC was done including the ESI tags inside the main Page Rendered component that most of the pages in TMG use /apps/telegraph/core
/commons/renderers/pageRenderer/body.html

The tag loaded from Akamai, makes a call to the Evolok auth api which require at least 2 main parameters: contentMetadata.sectionId, contentMe
tadata.articleId (this last one has to be unique per page) - in the current example I'm just passing the full publish URL of the article

1. Basic ESI tag

ESI tag

<div data-sly-use.tmgpage="uk.co.telegraph.core.commons.page.PageView" data-sly-unwrap>


<!--esi
<esi:assign name="authorizationResult">['AUTHORIZED']</esi:assign>
<esi:try>
<esi:attempt>
<esi:choose>
<esi:when test="$(GEO{'country_code'}) == 'GB' || $(GEO{'country_code'}) == 'JE' || $(GEO
{'country_code'}) == 'GG' || $(GEO{'country_code'}) == 'IM' ">
<esi:eval src="http://origin-meter.telegraph.co.uk/evolok-authz-web/api/esi/authorize?contentMetadata.
sectionId=cars&contentMetadata.articleId=${tmgpage.publishUrl @context='unsafe'}&contentMetadata.
channel=web&contentMetadata.meteredSection=true" dca="none" maxwait="10000"/>
</esi:when>
<esi:otherwise>
<esi:eval src="http://origin-meter.telegraph.co.uk/evolok-authz-web/api/esi/authorize?contentMetadata.
sectionId=cars&contentMetadata.articleId=${tmgpage.publishUrl @context='unsafe'}&contentMetadata.
channel=international&contentMetadata.meteredSection=true" dca="none" maxwait="10000"/>
</esi:otherwise>
</esi:choose>
</esi:attempt>
<esi:except>
<div style="display: none;">Unable to check access level</div>
</esi:except>
</esi:try>
-->
</div>

2. Basic Alert window that will be called once reached a total number of 20 (UK) or 10 (International) unique page visited

authorizationResult

<script type="text/javascript">
<esi:choose>
<esi:when test="$(authorizationResult)=='[\'AUTHORIZED\']'">
<esi:text>
console.log("AUTHORIZED");
</esi:text>
</esi:when>
<esi:otherwise>
<esi:choose>
<esi:when test="$(HTTP_USER_AGENT) matches_i '/Mobile|iP(hone|od|ad)
|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)
|Blazer|Dolfin|Dolphin|Skyfire|Zune/'" matchname="touchmatch">
<esi:text>
alert("(MOBILE) YOU HAVE REACHED YOUR 10 ARTICLE\nLIMIT FOR THIS
MONTH");
</esi:text>
</esi:when>
<esi:otherwise>
<esi:text>
alert("(DESK) YOU HAVE REACHED YOUR 10 ARTICLE\nLIMIT FOR THIS
MONTH");

158
</esi:text>
</esi:otherwise>
</esi:choose>

</esi:otherwise>
</esi:choose>
</script>

WS-2163 - Re(enable) Akamai access to AEM Demo with IP restriction CLOSED

In order to have the POC working we used the Adobe VPN (Ireland) to have an external IP and we temporary allowed this in Akamai, so we
could hit the TMG Demo environment from outside.

Related articles
Customer is forced to login or subscribe although he is logged in an existing subscriber
Article takes too long to load/HTTP 404 error page
Customer being forced to log in or subscribe
Enforcer not been shown for users accessing the website from Non-UK I.P addresses
Hard Regwall (ESI)

159
Replication Offloading
After analysis following the findings and consideration around offloading the replication to a separate author instance.

Following points need to be taken in to account

1. Offloading idea is itself around the use of replication to send content/jobs to a different instance to be processed; as a consequence this could
end up in replacing replication with replication.
2. From an author perspective the Replication itself is not one of the heaviest job; adding resources to the Agents' queues is generally fast. How fast
the queue elements are processed is mostly given by how quickly the publish perform.

A simple idea to implement could be as shown in the below image:

In general I can't see a real vantage as this still relies on a successful replication from author to authorProxy; so if author has issues the publish process
could still be broken. It's only a way to move the agents configuration to a different instance but it's not enough in my opinion to justify a more complex
configuration.

There is a lot of custom logic going on during replication events, hooked to listeners; "offloading" it as well could be a good point but this could lead to the
need to have the offloading instance in sync with the master one. If we start cloning the Proxy instance from the master then replication should keep things
in sync. An example of logic that could be offloaded is the listener to evaluate cache-references to be send to the publish for cache invalidation.

A different scenario to consider is when Author will run on a cluster of mongo instances; the idea would be to configure the replication-topic events to be
executed only on specific instances of the cluster, in this case instances, as part of the cluster would be already in sync and there would be no-need to
transfer the content to replicate. As mongo is still not available in TMG and the scope of this was exploring options this has not been tested and further
analysis is needed.

160
In conclusion, mostly because of [ 2 ] there are not huge benefits in offloading the replication and as far of now it doesn't seem to fully make the process
more reliable; replication queues are single threaded and if a queue is blocked due to failure on publish instance this shouldn't have a big impact on
performances on author.

161
URL to Resource mapping for Year, Month and Date
content hierarchy - Externalise mapping to Redis
Introduction
Some of the TMG channels such as Sport and News may have large number of articles. Having large number article pages under a section adversely
affect AEM performance and the authoring experience with finding and editing the pages in flat shallow hierarchy. These pages can be grouped under Year
/Month/Date hierarchy which which would assist in browsing to these pages and help with AEM performance. This however generates a URL with year
/month/date which is not desirable. Business would like an ability map pages deep under sections hierarchy to friendly URLs.

Resource Mapping

URL Path Resource Path

/eight-things-you- /content/telegraph/gardening/2015
didnt-know-about- /11/17/eight-things-you-didnt-know-
magic-mushrooms about-magic-mushrooms

/in-praise-of-the- /content/telegraph/gardening/2015
asian-pear /11/17/in-praise-of-the-asian-pear

/what-are-the- /content/telegraph/gardening/2015
healthiest- /11/17/what-are-the-healthiest-
vegetables-to-grow vegetables-to-grow

/green-shoots-of-a- /content/telegraph/gardening/2015
vegetable- /11/17/green-shoots-of-a-
revolution vegetable-revolution

/brew-it-yourself- /content/telegraph/gardening/2015
down-on-the- /11/17/brew-it-yourself-down-on-
allotment the-allotment

There are couple of OOTB options available to handle this requirements.

1. Apache Rewrite Rules


2. AEM Vanity URLs

Both options listed above fall short to satisfy the requirement due requirement of frequent update to large number mapping rules and performance related
concern using large number of vanity URLs in AEM.

URL to Resource Mapping - Redis Store


Friendly URLs to AEM resource mappings can be potentially externalised to KEY / VALUE store such as REDIS DB and managed centrally. This will
provide business better control over the URLs which can be mapped to different types of content stores.

Ref : AEM-3176 - Validate and approach for grouping content pages under year/month/date CLOSED

Solution -1 : Apache RewriteMap for forward mapping and Sling Rewriter for reverse mapping
Apache RewriteMap provides an ability to wire in mapping rules which can be updated without having to restart the service. Mapping rules can be
managed in text file or can be wired in programatically. This solution makes use of REDIS database to store the mapping rules and use PYTHON script
with RewriteMap to find and apply those rules for forward mapping

162
Add following config snippet in TMG rewrite rules file /etc/httpd/conf-enabled/rewrite.conf on Apache

#REDIS RewriteMap
RewriteMap tmgmap prg:/etc/httpd/rewritemap/redis-read-keys.py
RewriteCond %{REQUEST_URI} !^/(etc|content\/dam\/)
RewriteRule ^(\/.*)$ ${tmgmap:$1} [PT]

Create python script file redis-read-keys.py in location as set in above config block. It is a long running script which keeps connection to REDIS and find
mappings for KEY passed in by RewriteMap

#!/usr/bin/python
import sys
import redis
# Connect to redis
r = redis.Redis(host='10.0.200.40', port=6379, db=0)
def main():
while True:
input = sys.stdin.readline().strip()
try:
key = 'tmgmap:' + input
output = r.get(key)
if output == None:
output = "/" + input
print output
sys.stdout.flush()
except:
return None
if __name__ == '__main__':
main()

163
Final HTML response contains deep links to related resources. Sling Rewriter functionality provides an ability to map these resources it back to friendly
URL before final HTML response is passed back and rendered on user browser.

Solution - 2 : Servlet Filter for forward mapping and Sling Rewrite for reverse mapping
It is also possible to use Servlet Filter to provide forward mapping.

An OSGI Servlet filter intercepts HTTP request and when enabled and selects a mapping from REDIS DB, if found, request is then forwarded to mapped
resource.

The reverse mapping is again provided by Sling Rewriter

164
Pros and Cons :
Comparative Load test of both the solutions shows that first solution using Apache RewriteMap provides better performance than Servlet Filter option. It is
SSI friendly and non intrusive to AEM cache/flush operations. It also future proof to potential problem with Servlet Filter ordering.

Testing
Test content and JMeter test plan is attached to this page. Each page has links to 5 Pages for Sling Rewriter to write back friendly URL.

Set Up :
1. Redis database vagrant VM, 2 Cores, 1 GB
2. TMG WEB Vagrant VM, 2 Cores, 1 GB
3. TMG Publish Vagrant VM, 2 Cores, 1 GB
4. JMeter Load test, 2 users browse 5 pages 100 times which 1 second pause between each browsing operation. This should produce 1000 samples

5. Insert following mappings into REDIS DB, You will notice that entries need to be created for both forward and reverse mapping

System Key Value

Apache tmgmap:/eight-things-you-didnt-know-about-magic- /content/telegraph/gardening/2015/11/17/eight-things-you-


RewriteMap mushrooms didnt-know-about-magic-mushrooms.html

tmgmap:/in-praise-of-the-asian-pear /content/telegraph/gardening/2015/11/17/in-praise-of-the-asian-
pear.html

tmgmap:/what-are-the-healthiest-vegetables-to-grow /content/telegraph/gardening/2015/11/17/what-are-the-
healthiest-vegetables-to-grow.html

tmgmap:/green-shoots-of-a-vegetable-revolution /content/telegraph/gardening/2015/11/17/green-shoots-of-a-
vegetable-revolution.html

tmgmap:/brew-it-yourself-down-on-the-allotment /content/telegraph/gardening/2015/11/17/brew-it-yourself-
down-on-the-allotment.html

Servlet /eight-things-you-didnt-know-about-magic-mushrooms /content/telegraph/gardening/2015/11/17/eight-things-you-


Filter didnt-know-about-magic-mushrooms.html

/in-praise-of-the-asian-pear /content/telegraph/gardening/2015/11/17/in-praise-of-the-asian-
pear.html

/what-are-the-healthiest-vegetables-to-grow /content/telegraph/gardening/2015/11/17/what-are-the-
healthiest-vegetables-to-grow.html

/green-shoots-of-a-vegetable-revolution /content/telegraph/gardening/2015/11/17/green-shoots-of-a-
vegetable-revolution.html

165
/brew-it-yourself-down-on-the-allotment /content/telegraph/gardening/2015/11/17/brew-it-yourself-
down-on-the-allotment.html

/content/telegraph/gardening/2015/11/17/eight-things-you- /eight-things-you-didnt-know-about-magic-mushrooms
didnt-know-about-magic-mushrooms
Sling
Rewriter /content/telegraph/gardening/2015/11/17/in-praise-of-the- /in-praise-of-the-asian-pear
asian-pear

/content/telegraph/gardening/2015/11/17/what-are-the- /what-are-the-healthiest-vegetables-to-grow
healthiest-vegetables-to-grow

/content/telegraph/gardening/2015/11/17/green-shoots-of-a- /green-shoots-of-a-vegetable-revolution
vegetable-revolution

/content/telegraph/gardening/2015/11/17/brew-it-yourself- /brew-it-yourself-down-on-the-allotment
down-on-the-allotment

Results :

Solution Apache Servlet Filter

Average
response
time

Response
over time

166
Component and Template requirements
Add Product requirements

Title Developers Document QA Target Theme User User Version


status Sprint Story Story
Release Creator Owner

Article Page Template Copied Delivered Article Page Lindsay Ed 1


Overview from Template Flitton Keohane
Cheetah

Author Content (ID) Lead Draft Lead Sprint 6 & Author Content Lindsay Ed 0.1
Component Requirement Developer Test 7 (ID) Component Flitton Keohane
Overview er

Body Copy Component Lead Draft Lead Body Copy Lindsay Ed 0.1
Requirement Overview Developer Test Component Flitton Keohane
er

167
Article Page Template Overview
Target Sprint Release Delivered

Version 1

Theme Article Page Template

Document status Copied from Cheetah

User Story Creator Lindsay Flitton

User Story Owner Ed Keohane

Developers

QA

Template Mind Map

Overview

Component Name
Article Page

Component Description
Page that contains several components to create an article on telegraph.co.uk

Users and Workflow

168
Users
Describe users of the Component and how they will utilise it.

User User Description Key User Needs Internal


Name or
External

Editor Section Editor is responsible for the e.g. understanding customer engagement, optimising content placement and testing
management of a section page and all presentation options to optimise KPIs such as views and social sharing, ensuring SEO is Internal
related content. world class.

Journalist Authors article content Internal

Telegraph. Customer of the telegraph.co.uk who reads External


co.uk the articles online
reader

Configuration

Dependencies
List of components that the template being delivered within the User Story has.

Component Component Description Dependency e.g. used Component Overview Page


Name by or used for Link

Headline Component Capability to display a headline within the article Used for article creation Headline Component Requirement
Overview

Article Date and Capability to display the date and time an article was published to telegraph. Date & Time Component
Time component co.uk Requirement Overview

Article Body Text Capability to display the text content within an article Body Copy Component
component Requirement Overview

Article URL Capability to apply and display a readable URL to an article URL Component Requirement
Overview

Stand-first text Capability to display a text summary on the article (displayed beneath the Standfirst Component Requirement
component primary headline / headline of an article) Overview

Author component Capability to add the author details to an article using a pre-created Author Content (ID) Component
component Requirement Overview

Image component Capability to display an appropriate image to the article

Options
Please list the key configuration options that are available when this component is being used.

Option Name Option Description Default?

e.g. Preview There are two options available: portrait and landscape Landscape
orientation

e.g. Stylesheet The default stylesheet used by the component can be overwritten and the user can specify which one Uses inherited styles
to use instead

e.g. Show Image? Allow the option to use a thumbnail image for the article Yes (if an image is
available)

169
Component Bible
Component Nickname Synopsis Screenshot(s)
Name (s)

Ad Blocker Ad A message
Detector Blocker to be
Message. displayed to
Ad visitors of
Blocker the
Blocker, A Telegraph
d Blocker website
Detector, who are
The using ad
Blocka' blocking
Blocka' software. At
the time of
implementat
ion, this
worked for:

AdBlock
AdBlock
Plus
Adgaurd
AdBlocker
uBlock
Origin

N
o
o
n
e
h
a
s
b
e
e
n
p
ut
in
c
h
a
r
g
e
of
m
ai
nt
ai
ni
n
g
th
is
m
e
c
h
a
ni
s
m
in
r
el
at
io
n
to

170
A
d
B
lo
c
k
e
r
e
v
ol
ut
io
n.
It
is
r
e
a
s
o
n
a
bl
e
to
e
x
p
e
ct
th
at
it
s
ef
fe
ct
iv
e
n
e
s
s
w
ill
d
et
e
ri
o
r
at
e
o
v
e
r
ti
m
e
a
s
a
d
bl
o
c
ki
n
g
s
of
t
w
a
r
e
a

171
d
a
pt
s
to
th
e
te
c
h
ni
q
u
e
s
u
s
e
d.

For a
description
of the
necessary
configuratio
n steps, go
to the Ad
Blocker
Message
how-to
guide.

Advert Advert

Advert Advert A page in


Management Managem the Tools
ent Page section that
allows the
user to
configure
advert
behaviour
for a
section of
the site
(identified
by path in
the content
structure).

Article 2 Article 2
Template

172
Article Body Article Article Body
Image Body Image is a
Image wrapper for
image from
DAM or
from the file
system. It
enables a
caption,
credit and
other
properties
to be
recorded,
which are
rendered.

Article Body Article


Text Body Text

173
Article List The New The Article
List List
Compone displays
nt, Article queried
List content
Compone stored on
nt, List v2 the
telegraph
website.
Allowing
editors to
list articles
or galleries
based on
tags.

Author 2 Author 2, Displays a


Template Author list of
Template articles
2 written by a
specific
author and
biographical
information
regarding
the author.

Author Bio Author Bio Component


in use to
provides
information
about the
author or
create
profile page
for author.
Is used by
default in Au
thor 2
Template

174
and it can
be added
as a
component
to other
pages.

It works in
conjunction
with and as
the data
source for B
yline
component.

It is also the
data source
for the
Headline
Item Screenshot
component
on the Auth
or 2 Author Bio preview (with Headline) in preview mode
Template.

Author Bio (with Headline) in edit mode

Author Bio component configuration tab

Author Bio component image tab

(for Author's image)

175
Author Bio component image tab

(for Author's image alt text)

176
Autotweeting Autotweeti A service
ng, Autom that posts
atic tweets on
tweeting behalf of
the
Telegraph's
accounts
whenever a
new article
is published.

Autotweeting Autotweeti
ng, Autom
atic
tweeting

Blank Blank
Template Template

Box Box
Component

Breadcrumb Breadcru
Bar mbs

Byline Byline

The Byline component can accept multiple authors:

Cluster Cluster
template Template

177
Component N/A
Styles

Content Content
structure - structure
Channels, -
Sections Channels,
and Articles Sections
and
Articles

Curated List Curated


& Curated List (not
List Tile to be
confused
with Curat
ed List 2)

Curated List Curated


2 & Curated List 2
List Tile 2

Entities Entities A (sort-of) ?


(Cars, Film, common
Best) data model
for content
from the old

178
Cars, Film
and Best
pages.

Error Pages Error


Pages, 404
, 500

Folder Folder
Template Template

Gallery Gallery
Teaser Teaser

Gallery Gallery
Template Template,
Gallery, I
mage
Gallery

179
Google Google A Proof of
AMP POC AMP, AMP Concept
, GAMP, supporting
Accelerate Acceletated
d Mobile Mobile
Pages Pages in
AEM https://
www.
ampproject.
org/

Google Google A Proof of


AMP POC AMP, AMP Concept
, GAMP, supporting
Accelerate Acceletated
d Mobile Mobile
Pages Pages in

180
AEM https://
www.
ampproject.
org/

Header Header The page


"Header"
contains
navigation
elements,
please see
Navigation
for more
information.

Headline Headline

Headline displays - Her Story, review

HTML Html
Embed Embed
(writing
document
in
progress)

Hub Hub
Template Template

Image Image The Picture


Report Report Desk team
needs to
get an auto-
generated
usage
report
compiled
from the
image
credit fields
in AEM.

The Picture
Desk use
this report
to assist
with
working out
how much
money to
pay image
contributors.

Lead Asset Lead Displays a

181
Asset, Le prominent
ad Image image
serving as
the main
illustration
of an article.

Lead Asset Lead Displays a


Asset, Le prominent
ad Image image
serving as
the main
illustration
of an article.

182
List (The) List, List
of Entities
(referred
to as
such by
designers)
, Dynamic
List
(phrase
encounter
ed in the
Java
code
distinguish
ing the List
componen
t from the
Curated
List
componen
ts)

List of Tags List of


Tags

Metatags Metatags Different


types of
meta tags
rendered in
each
page's head
section can
be set up in
the CMS.
Most of
them can

183
be set up
on the
Metatag
configuratio
n pages in
the Tools
section.

184
185
Most Most
Viewed List Viewed
List, MVL

Navigation Navigation Allows


, global users to
nav, navigate
primary the website
nav,
overlay
nav, rich
nav,
feature
rich
navigation

Ooyala Ooyala Service for


overlay embedding
videos

186
Snippet & Snippet Snippets
Snippet Reference enable the
Reference , Snippet users to
define
reusable
bits of
content.
Every
snippet is a
page,
based on
the Snippet
template,
with a
single
paragraph
system
inside
which an
author can
place
arbitrary
components
. The partial
HTML
document
rendered by
the
resulting
page can
then be
included on
other pages
by the Snipp
et
Reference
component.

Social Social Some examples of the Social Follow component from across different channels
Follow Follow
Item Business example

Component

Channel
config

187
188
Social follow works by using the FB api which is initialised on certain pages when FB related functionality is detected.

FB requires an app to exist on a specified developer account on FB itself and for the code initialising the FB api object

The FB appID is set on the portal (Telegraph) page of the website and can be configured from within page properties.

This appID is used by all FB sharing functionality not just Social Follow.

DO NOT CHANGE THE APPID UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING AND HAVE CREATED AN

FACEBOOK RELATED FUNCTIONALITY ON THE SITE.

Social Share Social


Item Business example
Share

Social Share on desktop

Social Share on mobile

(adds WhatsApp if configured)

Channel page config

The Social Share component has its own config. This is given default setting when placed on new articles and gallerie

189
Social share works by using api's for the particular sharing device being used. In the case of FB this means that it uses

detected. FB requires an app to exist on a specified developer account on FB itself and for the code initialising the FB

The FB appID is set on the portal (Telegraph) page of the website and can be configured from within page properties.

This appID is used by all FB sharing functionality not just Social Share.

DO NOT CHANGE THE APPID UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING AND HAVE CREATED AN

FACEBOOK RELATED FUNCTIONALITY ON THE SITE.

Sponsored Sponsore
Content d Content

190
Sticky Sticky A button in
Preview Preview, the Sidekick
Fast that allows
Preview the user to
quickly
preview a
page in
WCM Mode
Disabled
and without
loading the
ads. Meant
as a quick
preview.

191
Sticky-Ad Sticky-Ad (currently
updating...)

Tag Tag
Mapping Mapping
Admin
Interface

Topic Pages Topic


pages

Topic Topic
Template Template

192
Ad Blocker Detector
Component

Ad Blocker Message. Ad Blocker Blocker, Ad Blocker Detector, The Blocka' Blocka'


Nickname
(s)

A message to be displayed to visitors of the Telegraph website who are using ad blocking software. At the time of implementation, this worked for:
Synopsis
AdBlock
AdBlock Plus
Adgaurd AdBlocker
uBlock Origin

No one has been put in charge of maintaining this mechanism in relation to Ad Blocker evolution. It is reasonable to expect that its effectiveness will deteriorate over time as ad blocking
software adapts to the techniques used.

For a description of the necessary configuration steps, go to the Ad Blocker Message how-to guide.

Displays a mesage to visitors of the Telegraph website who are using ad blocking software.
Description
The activation of an ad blocker in the user's browser is determined by the script in etc/designs/telegraph/core/clientlibs/core/js/components/component.adblocker-detector.js

The script creates a div with a selection of classes that the AdBlockers use to hide.

If the div is hidden, it displays the message to the user.

This is only displayed to non-subscribers.

This script creates a div on the page and checks if AdBlockers hide it or not
Interactions

Restrictions

Screenshot
(s)

Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Extend ad Sep 23, Nov 15, Andrzej Tomasz RELEASED Unresolved
6749 blocker 2016 2016 Dolinski [X] Niedzwiedz
message [X]
configuration
AEM- Feature Sep 09, Nov 15, Grzegorz Gavin Kirk RELEASED Unresolved
6626 switch for Ad 2016 2016 Bednarski [X] [X]
Blocker
Detected
message
AEM- Ad Blocker Jul 15, 2016 Nov 22, Grzegorz Gavin Kirk RELEASED Unresolved
6236 detection & 2016 Bednarski [X] [X]
message

193
3 issues

Other

Component Properties
Name Type Description

194
Advert
Component

Nickname Advert
(s)

Description The advert component itself is simply a wrapper which is used by the Ad Ops GPT code to insert adverts into appropriate places
on the various templates.

There are three basic types of advert currently utilised by TMG. These are 'Banner', 'MPU' and 'HPG'. These terms are used by
AdOps and in the Advert management pages for setup. However, on the main article templates these are referred to as ad slot A
(banner) ad slot b (MPU) and ad slot c (hpg)

When the page loads each ad slot is initialised by the advert component js file. The important thing to remember here is in the
sightly code the adlocation and breakpoints are hardcoded for each adslot:

dataOptionsJson='{ \'adLocation\': \'head\', \'adType\': \'ban\', \'breakpoints\': \'xxs,xs,


sm,md,lg,xl\' }'

This information is then parsed and passed to the the GPT function call - tmgAdsBuildAd()

GPT itself handles the response and the generation of the advert within the specified Ad slot.

Interactions

Restrictions

Screenshot
(s)

Location /apps/telegraph/core/commons/components/advert

JIRA

Other Ad slot C (hpg) has special functionality on mobile breakpoints. Because it is baked in at the bottom of the sidebar this means that
at smaller breakpoints when the sidebar responsively drops below the main content Ad slot C would end up very far down the
mobile page after the rest of the sidebar content.

In order to get around this issue Ad slot C is a special case where it actually appears on the page twice. Once in the bottom of the
sidebar and once in the body content of the page. The body content version is hidden and using the dataOptionsJson method
above only calls to GPT on the xxs, xs and sm breakpoints.

Likewise the sidebar version only makes a call to the advert code on the md, lg & xl breakpoints.

However there is a further trick. The hidden body ad slot C is when displayed actually dynamically inserted into the content at a
predetermined position measured by the number of components/paragraphs of text in the body content. This defaults to 5.

/**
* Moves an Ad block depending on the existence of selectors and current breakpoint, see spec.
component.advert.js for usage example
* @memberof Advert
* @return {undefined}
*/
shiftMe : function(){
var apply = true,
shift = this.config.shift,
selectors = shift.when.selectors || [],
deselectors = shift.when.deselectors || [],
activeBreakpoints = shift.when.breakpoints || [],
$target,
i = 0;
if (activeBreakpoints.indexOf(tmg.getMediaQuery()) === -1){
return;
}
for (;i < selectors.length; i++){
apply = !!$(selectors[i]).length;
if (!apply){

195
return;
}
}
for (i=0;i < deselectors.length; i++){
apply = $(deselectors[i]).length === 0;
if (!apply){
return;
}
}
$target = $(shift.to.selector);
if (!!$target[shift.to.jqapi]){
$target[shift.to.jqapi]( this.$elem );
} else {
throw new Error("Method Not Implemented; $.fn." + shift.to.jqapi );
}
}

Component Properties
Name Type Description

196
Advert Management
Component

Advert Management Page


Nickname
(s)

A page in the Tools section that allows the user to configure advert behaviour for a section of the site (identified by path in the content structure).
Synopsis

There are three distinct parts to the Advert Management page (to be found in /etc/telegraph/admin/advert-management.html):
Description
1. Ab blocker message configuration
2. Advert Management Rules
3. Advert Rule Mapping

You can read more about the background and steps to configure advert rules and mappings on the Advert Management background and usage page.

Ad blocker message
This section allows the user to configure a message to be displayed to the visitors of the Telegraph website who use Ad blocking software. For more information on how this should be configured, see Ad
Blocker Message. For technical documentation on the way the message is displayed go to Ad Blocker Detector.

The message can be previewed by clicking the button under the configuration box.

Advert Management Rules

197
The Advert Management Rules allow the user to group a number of settings regarding Ad behaviour and reference them later in the Advert Rule Mapping section.

Rule Name - the name of the rule, serves as an identifier


Model - a string referencing the Ad Model. Currently one of the values: Banner and MPU (Mid-Page Unit). This is used by externally loaded JavaScript.
Min height threshold - scroll depth in pixels at which adverts should stick
Sticky ad refresh rate - how often sticky ads should be refreshed
Sticky banner cycles - how many times a sticky banner should cycle through all loaded ads until it disappers

Advert Rule Mapping

The Advert Management Rules can be assigned to paths, which allows the user to bind them to the site's content structure. Every mapping assigns a specific Advert Management Rule to a content path.
Usually, this is going to be the path of a channel but the choice of other pages is unrestricted.

Based on Advert Rule Mapping, a different object will be assigned to the tmgAds.model variable at the front-end when a page (the one indicated by the path or one of the descendants of such a page) is
rendered. This object is later consumed by scripts loaded from the Ad server. The initialisation of the script can be found in apps/telegraph/core/commons/renderers/pageRenderer
/advertManagement.html

The specific script is Server-Side Included if the page is requested via the Dispatcher.

The component uses SSI.


Interactions

Restrictions

Screenshot
(s)

Admin page interface:


Location
src/main/cq/jcr_root/apps/telegraph/wcm/admin/advertManagement (components used on this page are also defined in the same folder)

HTL script responsible for rendering the tmgAds.model initialisation script on all pages:

src/main/cq/jcr_root/apps/telegraph/core/commons/renderers/pageRenderer/advertManagement.html

OSGi service responsible for the lookup of the data to render (based on the data on the configuration page):

uk.co.telegraph.core.commons.advertmanagement.AdvertManagementService

JIRA AEM-5539 - Management of Ads models RELEASED

Related:

198
T Key Summary Assignee Reporter P Status Resolution Created Updated Due

AEM- Ads do not Andrzej Zeid Hadi [X] RELEASED Unresolved Jun 01, Jun 09, 2016
5889 display on hub Dolinski [X] 2016
pages
AEM- SBoM - Sticky Zeid Hadi [X] Gavin Kirk RELEASED Unresolved Jul 08, 2016 Sep 02,
6193 Banner on [X] 2016
Mobile -
Management
AEM- Management Unassigned Gavin Kirk RELEASED Unresolved Apr 27, Dec 06,
5539 of Ads models [X] 2016 2016
AEM- Social share Krzysztof Anna Dezor RELEASED Unresolved May 30, Jul 05, 2016
5845 icons not Gorzynski [X] [X] 2016
visible for
existing pages
AEM- Ads are not Simon Ward Michael RELEASED Unresolved May 27, Jun 02, 2016
5835 visible [X] Goszczynski 2016
AEM- Configuration Andrzej Tomasz RELEASED Unresolved Aug 25, Sep 26,
6560 pages are Dolinski [X] Niedzwiedz 2016 2016
publicly [X]
available
AEM- Sticky Banner Unassigned Ian Curtis [X] TO Unresolved Nov 17, Nov 17,
7053 on Index on REFINE 2016 2016
Single
Column
Viewports
AEM- Bottom Border Blazej Blazej RELEASED Unresolved Aug 25, Sep 16,
6559 is missing Kacikowski Kacikowski 2016 2016
[X] [X]
AEM- Banner is Unassigned Andrzej TO Unresolved Jun 07, Jun 10, 2016
5941 present when Dolinski [X] REFINE 2016
sticky MPU is
set for the
page
AEM- User is able to Unassigned Andrzej TO Unresolved May 25, May 27,
5801 choose model Dolinski [X] REFINE 2016 2016
with keyboard
AEM- Configuration Blazej Blazej RELEASED Unresolved Aug 25, Sep 16,
6558 page is Kacikowski Kacikowski 2016 2016
available on [X] [X]
dispatcher
level
AEM- Improve Gareth Clubb Gareth Clubb CLOSED Done May 09, Feb 17, 2017
6340 advert [X] [X] 2016
delivery
AEM- Ad slot C's Simon Ward None INTEGRATION Unresolved Aug 27, Oct 15, 2015
2160 mobile [X] TESTING 2015
equivalent
goes missing
when viewed
in mobile
AEM- User Interface Unassigned None TO Unresolved Mar 09, May 23,
4756 moving REFINE 2016 2016
around whilst
3rd party
loading
AEM- Fix headline Unassigned None INTEGRATION Unresolved Aug 20, Oct 15, 2015
2077 sizes across TESTING 2015
all list variants
AEM- Portal feature Unassigned None RELEASED Unresolved Feb 16, Mar 07, 2016
4431 settings 2016
defaults
AEM- SMoG - Sticky Simon Ward Gavin Kirk RELEASED Unresolved Aug 15, Dec 12,
6465 MPU on [X] [X] 2016 2016
Gallery pages
AEM- Article body: Unassigned Mark Cyrson CLOSED Done Dec 06, Jun 18, 2018
7134 use consistent 2016
value for Std
/Review
Articles
AEM- Improvements Unassigned None CLOSED Done Jun 12, Apr 28, 2016
1135 to Video 2015

199
Player
AEM- Grapeshot Unassigned Mark Cyrson RELEASED Unresolved Sep 11, Jul 11, 2017
2405 2015

Showing 20 out of 21 issues

Other
This component may have to be refactored in a way similar to the Tag Mapping page. The Advert Management Rules and Advert Management Mapping entries are just components kept in
flat paragraph systems. This does not scale beyond a hundred or so entries.

The advert management page uses its own clientlib found in /apps/telegraph/core/design/clientlibs/adblocker

It may be beneficial to unify this code with similar custom code implemented for the Tag Mapping page and possibly other similar pages.

Component Properties
Name Type Description

200
Advert Management background and usage

Background
Advert Management page
Create an Advert Rule
Create an Advert Rule Mapping
Spark Advert Management Mapping component
Default Rule
Editing a rule
Deleting a rule
Ad Rule Details
Data object

Background
Ads are delivered onto the site in three broadly different ways known as models. Each model define number of ads on the page, their position and whether
or not they are sticky.

When the site was first migrated onto AEM only one model was support which basically ensured that there were always 3 ads of a page except for
galleries which had one. Once other models were implemented this first way became known as the Standrard model. The diagram below shows the
positions on desktop breakpoints across the various page types. On mobile breakpoints the ads stack on the index pages and articles and on galleries
they are inserted between slices as the user navigates between slides.

Standard Model:

This the advent of the industry called for ads to become 100% viewable two new models were implemented - firstly the sticky MPU and then the sticky
banner.

The three models are:

Standard - The page has three ads (1 banner & 2 MPU's) that all scroll away with the page.
MPU - The page has only one ad which is a sticky MPU in the right rail
Banner - The page has only one ad which is a sticky banner

Any page that has a model applied to it that is not supported on its template will fall back to the Standard model.

Advert Management page


The Ad Management interface was been built to enable the Ads team to set up and manage rules in AEM and to map these rules to wherever they like on
the site. Typically rules are mapped to the Portal and channel although they can be mapped to anywhere. Once a rule is mapped to a page then that
page and its child pages will all be rendered with a data object detailing the applied rules. However as mentioned above the model applied to a page will
only have any effect on the page if the template has been implemented to react to the that model. At time of writing index pages (Portal, Hub, Destination,
Topics, etc) will not deliver sticky ads even when the MPU or Banner models are applied to them (there are plans to make index pages to have a sticky
banners on mobile breakpoints but this is on hold at time of writing).

To apply an ad rule to a page you must first create a rule and then apply that rule to the page. Applying a rule to a page is done my mapping it. Both
creating and mapping of rules is done of the Advert Management page in the Tools section of AEM (/miscadmin#/etc/telegraph/admin/advert-
management). The Advert Management has one section for managing the rules and another below it for managing the rule mappings.

Creating an Advert Rule will not do anything to the ads on the site. A rule will only take effect once it is mapped to a page (or pages).

Create an Advert Rule

201
1. Open the Advert Management page (/miscadmin#/etc/telegraph/admin/advert-management)
2. Drag an Advert Management Rule component from Sidekick into the List of advert rules section
3. Edit the component by providing:
a. Rule name: Rules Name should be unique as they are used as the key for rule mapping (at time of writing there is no validation to
check whether Rule Name is unique so this is author responsibility)
b. Model
c. Min height threshold
d. Sticky ad refresh rate
e. Sticky banner cycles
4. Click OK to save the component configuration

Create an Advert Rule Mapping


1. Open the Advert Management page (/miscadmin#/etc/telegraph/admin/advert-management) so scroll down to the Advert Management Mapping
section.
2. Drag an Advert Management Mapping or a Spark Advert Management Mapping component from Sidekick into the Advert rules mappings section.
3. Edit the component by providing:
a. Page path
b. A rule for each of the breakpoints in the Advert Management Mapping component (only a single rule is needed in the Spark
Advert Management Mapping component)
a. Click OK to save the component configuration.
4. Activate the Advert Management page for the rule to take effect
a. As part of the Advert Management is release the cache will be invalidated across the entire site. From this point on then every time any
rules and rule mappings are added, edited or deleted and the Advert Management page is activated then the changes will take effect
immediately (i.e.: without having the reactivate the articles that the rule has been applied to).

202
Spark Advert Management Mapping component
Spark tend not to want to use sticky ads in the sponsored sections they create for client. This is because they would tend towards using Sticky Branding an
d this would clash with sticky ads if they have been set up on the channel. As Spark place their content within Editorial channels which may have sticky
MPU or sticky banner model configured, Spark wanted a simple way to knock out sticky ads without having to set the mapping on every breakpoint. For
this reason the Spark Advert Management Mapping component was created. With it the user can ad a page path and a single rule that is applied
automatically across all of the breakpoints. The would usually set this with a rule that has "None" as the ad rule.

Using thie component sticky prints out all an entry for all of the breakpoints in the data object but they will all be the the same.

Default Rule
It is envisaged that the portal page will always have a rule mapped to it that is called Default. This will then be inherited to all pages across the site that do
not have another rule applied explicitly or at some other parent level such as a channel or section. It is author responsibility to ensure that a Default rule
has been created and that it is mapped to the portal page. If an area of the site somehow has no rule mapped to it then the tmgads.model data object will
still be present on the page but will be empty. The Ad Ops GPT code has been written to handle both populate and empty data object.

Editing a rule
Any rule that is already mapped to a page (or pages) can be edited so that the settings can be tweaked at Ad Ops discretion. Any changed made will take
effect without requiring reactivation of any of the articles.

1. Open an existing Advert Management Rule component.


2. Edit any of the properties as required.
a. Changing the Rule Name of a rule will destroy its mapping as it is used as the key between rules and mappings.
3. Click OK to save the changes to the component.
4. Activate the Advert Management page (this will immediately update the rule to all pages it is mapped to and the descendant pages).

203
Deleting a rule
If a rule is no longer required then it can be deleted, however care should be take to ensure that the mapped rule is not mapped. If it is mapped then its
rule mapping/s should also be deleted.

1. Check to see if the rule to be deleted has any mappings and if they exist delete those Advert Management Mapping components.
2. Delete the Advert Management Rule component.
3. Activate the Advert Management page.

Ad Rule Details
Each rule has the following properties which are all mandatory:

Rule Description
property

Rule name* Freetext (recommended use a naming convention)

Rules Name should be unique as they are used as the key for rule mapping (at time of writing there is no validation to check
whether Rule Name is unique so this is author responsibility)

Model* Offer the choice of None, MPU and Banner

Min Height Number of pixels of the viewport used by Ad Op to decide the height of the sticky ad (i.e.: has no impact on AEM functionality). Also
Threshold* note that this is not the height reserved for the ad.

This does not apply to the None model so recommend entering '0' when this is selected (if a non-zero number is entered it will have
no impact on functionality when the Model = None).

Sticky ad Number giving the amount of milliseconds between ad calls.


refresh rate*
Note however AEM merely delivers the number into the data object and Ad Ops code controls the number refresh rate of the ads.

This does not apply to the None model so recommend entering '0' when this is selected.

Sticky Integer giving the number of ads to be called when the ad model is set to Banner. Not used in the other models (None or MPU).
banner
cycles* Note AEM delivers the number into the data object, Ad Ops code controls the delivery of each ad cycle and after the configured cycles
have all completed then AEM code will remove the sticky banner from the page

This does not apply to the None or MPU models so recommend entering '0' when either of these are selected.

Data object
All pages on the site should have a data object, tmgAds.model, in the <head> section of the page. Setting up a rule and mapping it to a page changes the
data output into tmgAds.model. The Ad Ops GPT code reads this data an uses it to control the ads that they deliver to the page.

Once a rule has been created, mapped and the Avert Management page has been activated then the mapped page and its descendant pages will reflect
the rule in tmgAds.model.

The following table shows examples the data object that should be fond on every page of the site. If tmgAds.modal is missing from a page then either
activate the page or request Web Ops to invalidate the cache in the page or channel where you have seen is missing.

Case Example tmgAds.model data object

Parent
page or <script id="tmg-ads-model-init">
current var tmgAds = tmgAds || {};
page has tmgAds.cmd = tmgAds.cmd || [];
a mapped tmgAds.model = [
rule {"ruleName":"MPU 680px 15secs","model":"mpu","minHeight":680,"refreshRate":15000,"
refreshCycle":0,"viewport":"x"},
{"ruleName":"MPU 680px 15secs","model":"mpu","minHeight":680,"refreshRate":15000,"
refreshCycle":0,"viewport":"l"},
{"ruleName":"MobBan 30secs NoRefresh","model":"ban","minHeight":0,"refreshRate":30000,"
refreshCycle":1,"viewport":"m"},{"ruleName":"MobBan 30secs NoRefresh","model":"ban","
minHeight":0,"refreshRate":30000,"refreshCycle":1,"viewport":"s"},{"ruleName":"MobBan 30secs
NoRefresh","model":"ban","minHeight":0,"refreshRate":30000,"refreshCycle":1,"viewport":"xs"}
];
</script>

204
Note the matrix of five rules, one for each breakpoint (viewport).

No rule on
current <script type="text/javascript">
page or on var tmgAds = tmgAds || {};
any parent tmgAds.cmd = tmgAds.cmd || [];
page tmgAds.model = { };
</script>

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

WEB- SBoI - Configuration on Nov 17, May 17, Deep Ian Curtis RELEASED Done
99 Sticky Banner 2016 2017 Liyanage [X] [X]

AEM- SMoG - Sticky MPU on Aug 15, Dec 12, Simon Ward Gavin Kirk RELEASED Unresolved
6465 Gallery pages 2016 2016 [X] [X]

AEM- SBoM - Sticky Banner on Jul 08, Sep 02, Zeid Hadi [X] Gavin Kirk RELEASED Unresolved
6193 Mobile - Management 2016 2016 [X]

AEM- Deprecate old Sticky Ads May 19, Jun 03, Andrzej Gavin Kirk RELEASED Unresolved
5728 2016 2016 Dolinski [X] [X]

AEM- Sticky Ads Apr 27, Nov 17, Unassigned Gavin Kirk TO Unresolved
5540 2016 2016 [X] REFINE

AEM- Management of Ads Apr 27, Dec 06, Unassigned Gavin Kirk RELEASED Unresolved
5539 models 2016 2016 [X]

AEM- SBoM - Sticky Banner on Apr 25, Sep 02, Simon Ward Gavin Kirk RELEASED Unresolved
5505 Mobile 2016 2016 [X] [X]

AEM- Sticky MPU on Article 2 Apr 25, Jun 28, Andrzej Gavin Kirk RELEASED Unresolved
5504 2016 2016 Dolinski [X] [X]

8 issues

205
Article 2 Template
Component

Article 2
Nickname
(s)

General use across site for all articles. Used to structure articles on creation. Article 2 renderer inherits from PageRenderer in rendering the page.
Description

Interactions

Restrictions

Screenshot
(s)

/apps/telegraph/core/commons/renderers/articleRenderer2 (code in telegraph-component)


Location /apps/telegraph/core/commons/templates/articleTemplate2 (code in telegraph component)

JIRA AEM-37 - Create new articleTemplate in core RELEASED

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Refactor Jul 02, 2015 Feb 11, 2016 Unassigned None CLOSED Done
1434 advert
functionality in
article 2
template
AEM- Article 2 Apr 23, Jun 02, 2015 Unassigned Gavin Kirk RELEASED Unresolved
351 template 2015 [X]
Content Type
meta data
AEM- Sly tag in Aug 14, May 16, Unassigned Patrick CLOSED Done
1975 Article 2 2015 2016 Clancey [X]
template
AEM- Article 2 Jun 02, Jun 15, 2015 Unassigned Patrycja CLOSED Done
925 template 2015 Kurkowiak
hasn't been [X]
loaded proper
AEM- Restore lead Jun 19, Jun 26, 2015 Anna None RELEASED Unresolved

206
1220 asset to 2015 Karkkainen
Article 2 [X]
template
AEM- Play Video is Jun 09, Jun 24, 2015 Unassigned Patrycja READY Done
1053 not possible 2015 Kurkowiak FOR
RELEASE
on article 2 [X]
template
AEM- GPT - Article Jun 03, Jun 15, 2015 Patrycja Patrycja CLOSED Done
948 2 template 2015 Kurkowiak [X] Kurkowiak
(Fashion) [X]
doesn't
contain
sideBar and
parsys
AEM- Curated list Sep 11, Jan 14, 2016 Unassigned None CLOSED Done
2388 component on 2015
article 2
template
breaks the
inline
component
AEM- Disable May 06, Jun 22, 2015 Tomasz Tomasz RELEASED Unresolved
491 floating/counts 2015 Niedzwiedz Niedzwiedz
of the Social [X] [X]
Sharing
component in
Article 2
template.
AEM- Difficult to edit Jun 19, Jun 26, 2015 Bartosz None RELEASED Unresolved
1224 the lead asset 2015 Borowski
component on
Article 2
template
AEM- When setting Jul 03, 2015 Oct 02, 2015 Unassigned None RELEASED Unresolved
1454 up for
exmaple
author on
article 2 page
template -
default
selection
disappear
AEM- Video as Lead May 13, Jul 15, 2015 Unassigned Gavin Kirk RELEASED Unresolved
608 Asset 2015 [X]
AEM- W3C error: Aug 11, Oct 29, 2015 Unassigned Patrycja RELEASED Unresolved
1930 datetime 2015 Kurkowiak
format on [X]
author
component
AEM- Spike[2days]: Jun 19, Jul 22, 2015 Unassigned None CLOSED Done
1229 Sticky MPU's 2015
on hub
template
AEM- Film entity link Aug 11, Sep 04, Unassigned Luis RELEASED Unresolved
1938 - performance 2015 2015 Khamashta
very slow
AEM- Excluded Sep 01, Oct 02, 2015 Unassigned Jedrzej CLOSED Done
2213 templates 2015 Osinski [X]
count
AEM- Add Video to Sep 21, Feb 03, 2016 Unassigned None RELEASED Unresolved
2521 Lead Asset 2015
using Ooyala
Id
AEM- Any page Jul 07, 2015 Jul 16, 2015 Unassigned None CLOSED Done
1487 (template)
under hub,
when on hub
ads are
disabled, are
also disabled
AEM- Remove Aug 18, Oct 20, 2015 Unassigned None RELEASED Unresolved
2028 "Authoring- 2015
Article" from
Authoring
"Create"
dropdown

207
AEM- NonIAB is Jun 12, Oct 02, 2015 Unassigned Patrycja RELEASED Unresolved
1123 visible also on 2015 Kurkowiak
another [X]
templates
than Hub and
Article2
template

Showing 20 out of 350 issues

The article page utilises sticky MPU functionality (whole sidebar does not scroll until bottom of the page approaches) and also sticky banner on mobile 9sticky banner ad at bottom of the page)
Other
This functionality is dependant on Ad management settings and also the actual length of the article content vs sidebar content.

Component Properties
Name Type Description

208
Article Body Image
Component

Article Body Image


Nickname
(s)

Article Body Image is a wrapper for image from DAM or from the file system. It enables a caption, credit and other properties to be recorded, which are rendered.
Synopsis

Description

Interactions

Restrictions

Screenshot
(s)

/apps/telegraph/core/commons/components/articleBodyImage (telegraph-component)
Location /apps/telegraph/core/commons/components/leadAsset (telegraph-component)

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Investigate Jul 08, 2015 Jul 14, 2015 Lukasz None CLOSED Done
1513 inline editing Blaszynski [X]
of image
embed within
the article
body [2
DAYS]
AEM- placeholder of Oct 27, Nov 10, Unassigned None RELEASED Unresolved
3069 missing image 2015 2015
in article body
does not work
AEM- Small images Feb 24, Nov 25, Unassigned None TO Unresolved
291 in Article Body 2015 2016 REFINE

AEM- Article Body May 07, Aug 18, Unassigned None CLOSED Done
500 Image 2015 2015
component
styling
AEM- Drag image Oct 08, Mar 10, 2016 Unassigned Mark Cyrson CLOSED Done
2823 directly into 2015
'Article Body
Image'
component
AEM- Change ratio Feb 24, Jun 10, 2015 Unassigned None CLOSED Unresolved
201 crop for image 2015
in Article Body

209
AEM- Add and Feb 02, Jul 16, 2015 Lukasz None RELEASED Unresolved
180 remove Image 2015 Blaszynski [X]
from Article
Body
AEM- View and Edit Feb 24, Jun 25, 2015 Unassigned None CLOSED Done
205 Caption for 2015
image in
Article Body
AEM- View Feb 24, Jun 24, 2015 Unassigned None CLOSED Done
200 metadata for 2015
image added
to Article Body
AEM- Article Body Oct 10, Dec 02, Unassigned Andrzej CLOSED Done
6856 Image in live 2016 2016 Dolinski [X]
article is not
visible after
page load
AEM- Edit image Jan 18, Nov 25, Unassigned None TO Unresolved
4028 information 2016 2016 REFINE
inline in Article
Body & Live
Posts
AEM- Speed of use Oct 19, Nov 03, Unassigned Jo Harris [X] RELEASED Unresolved
2935 of Article Body 2015 2015
noticeably
slows down
when images
are uploading
AEM- Credit label May 19, Jul 17, 2015 Tomasz Gavin Kirk CLOSED Done
658 text incorrect 2015 Niedzwiedz [X]
for Lead Asset [X]
& Article Body
Image
AEM- Copy images Sep 22, Sep 23, Unassigned Jo Harris [X] TO Unresolved
6742 from Live 2016 2016 REFINE
Article Post to
Body or Lead
Asset
AEM- Override DAM Jun 02, Jul 08, 2015 Unassigned None RELEASED Unresolved
904 defaults for 2015
Copyright and
Creator in
Article Body
Image
component
AEM- Add more Sep 08, Nov 07, Unassigned None CLOSED Done
2301 than one 2015 2016
already
uploaded
image at a
time to Article
Body and
Gallery
AEM- Aligning May 11, May 18, Unassigned Gavin Kirk CLOSED Done
535 behaviour 2015 2016 [X]
Article Body
Image, Lead
Asset &
Gallery Slide
when
inheriting data
from the DAM
AEM- Film - enable Sep 09, Apr 28, 2016 Unassigned None CLOSED Done
2315 insertion of 2015
html embed
and article
body image
components
in sidebar on
index pages
AEM- Select image Feb 24, Jun 10, 2015 Unassigned None CLOSED Unresolved
199 ratio to be 2015
used in article
body
AEM- Restore Article Apr 18, Jul 06, 2017 Ather Mughal Ather Mughal RELEASED Unresolved
7417 /Live Article - 2017 [X] [X]
Embed image

210
in article body

Showing 20 out of 189 issues

Other

211
Component Properties
Tab Name Type Description

Image N/A Drag and drop Enables image to be added or removed from file system

Image Configuration Component Heading text

Image Link browser Enables image to be linked from JCR

Caption text

Disable Image Caption checkbox

Override DAM information checkbox

Credit text

Source text

Styles Style dropdown No styles available

212
Article Body Text
Component

Nickname Article Body Text


(s)

Description Article Body Text component is used to include a section of text on an Article Page.

It is only permitted for this component to be in a parsys. By default you are presented with an empty text area. In order to insert
the article body text at least one character must be inserted. In terms of formatting, there is a basic text editor with features such
as lists, hyperlinks, text alignment, indentation, cut, copy, paste, bold, italics and underline. For the styling of the text you are given
tree options from the drop down menu - paragraph, heading 3 and heading 4.

The "Styles" tab is an optional extra to change the style of the component, default is set to 'none'. Other options are - Version 1
and Drop caps (displayed in the main screen shot)

Interactions

Restrictions

Screenshot
(s)

Location

JIRA

Other

213
Component Properties
Name Type Description

214
Article Date
Article Date
Nickname
(s)

The component displays the publish date of an article, although having said that editors can change the date manually to be anything they like.
Description
By default the component is added to all articles (Article 2 Template) with no value. In this case the component displays the value in from Publication Date Override field (see Overrides tab in Page
Properties). The editor can also enter a date and time manually to override this automatic date time stamp.

This component loads data from pages the Publication Date Override (see Overrides tab in Page Properties).
Interactions

Restrictions

Screenshot Item Screenshot


(s)

Standard styling

Comment piece styling

Component config

Publication Date Override

215
Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Apply Nov 16, May 18, Unassigned Gavin Kirk CLOSED Done
3298 sponsored 2015 2016 [X]
campaigns to
date-driven
articles
AEM- Article Date May 07, Aug 18, Unassigned Gavin Kirk CLOSED Done
511 component 2015 2015 [X]
styling
AEM- [SEO] May 07, May 08, Melinda None CLOSED Done
492 Changing the 2015 2015 Rogers [X]
publish date
on an article
should be
optional
AEM- Standardise Mar 19, Sep 04, Anna Dezor Melinda RELEASED Unresolved
465 Publication 2015 2015 [X] Rogers [X]
Date
treatment in
Articles &
Lists
AEM- Change Mar 02, Sep 15, Unassigned None RELEASED Unresolved
157 Visible 2015 2015
Publish time
of story

5 issues

Other

216
Article List
Component

The New List Component, Article List Component, List v2


Nickname
(s)

The Article List displays queried content stored on the telegraph website. Allowing editors to list articles or galleries based on tags.
Synopsis

This component uses an external list service (see repo here https://github.com/telegraph/list-service) to retrieve content stored on the telegraph website. The content that is listed in the component is based
Description on what is configured in the "Configuration" tab in the component dialog.

To view Swagger definition http://alb.api-platforms.telegraph.co.uk/list-service/api-docs


Interactions

Restrictions

Screenshot
(s)

Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

WEB- SEO feedback Dec 05, Dec 05, Unassigned Rima Amin TO Unresolved
3391 tweaks 2019 2019 DO

WEB- Integrate Dec 04, Dec 06, Javier Furio Chris Boakes IN Unresolved
3389 Paywall 2019 2019 DEV
switches into
new article
WEB- Create Dec 03, Dec 03, Unassigned Chris Boakes TO Unresolved
3388 targetkill URL 2019 2019 DO
parameter
WEB- Demo Dec 03, Dec 05, David White David White IN CODE Unresolved
3387 feedback 2019 2019 REVIEW
tweaks
WEB- Replace Dec 02, Dec 02, Unassigned Chris Boakes TO Unresolved
3383 Telegraph 2019 2019 DO
Logo With
Properly Set
Logo
WEB- Remove code Dec 02, Dec 02, Unassigned Rima Amin TO Unresolved
3382 developed for 2019 2019 DO
WEB-3210
WEB- Final Design Dec 02, Dec 05, David White Rima Amin IN Unresolved
3381 Tweaks 2019 2019 DEV
(timeboxed 2
hrs)
WEB- Groovy script / Dec 02, Dec 05, Javier Furio Javier Furio IN Unresolved
3379 pre-configure 2019 2019 QA
the article
right rail
snippets for

217
new article
page
WEB- Integration of Dec 02, Dec 05, Jonathan Chris Boakes READY FOR Done
3377 Piano logic 2019 2019 James INTEGRATION
and markup
into new
article
WEB- SPIKE: Nov 29, Nov 29, Unassigned Chris Boakes TO Unresolved
3374 Gracefully 2019 2019 DO
handle
reliance on ad
script for YT
videos
WEB- New article Nov 29, Dec 03, Jonathan Chris Boakes READY FOR Done
3373 right hand rail 2019 2019 James INTEGRATION
tweaks
WEB- Voucher Nov 28, Dec 05, David White David White READY FOR Unresolved
3372 codes 2019 2019 QA
component
WEB- Migration Nov 28, Dec 02, James James READY FOR Unresolved
3371 script for 2019 2019 Appleby Appleby REVIEW
commenting
configuration
WEB- Hide lead Nov 27, Dec 04, Javier Furio Javier Furio RELEASED Done
3367 asset and 2019 2019
lead video
from telegraph
components
WEB- List Service Nov 25, Dec 03, Jonathan Rachana READY FOR Done
3361 for New Video 2019 2019 James Mehta INTEGRATION
Articles
WEB- Problem Nov 22, Dec 05, David White Hugh Morris IN CODE Unresolved
3358 adding 2019 2019 REVIEW
Authors on
AEM articles
WEB- Style for when Nov 20, Dec 05, Anand David White READY FOR Unresolved
3355 journalist has 2019 2019 Shirkande REVIEW
added
comment
WEB- POC for Nov 20, Dec 02, Unassigned Rima Amin TO Unresolved
3354 truncation on 2019 2019 DO
new article
page using %
WEB- End to end Nov 19, Dec 05, Jonathan Rima Amin IN Unresolved
3352 testing with 2019 2019 James QA
Newsroom
WEB- Design Nov 19, Dec 04, Chris Boakes Chris Boakes RELEASED Done
3348 Tweaks: 2019 2019
Onward
Journey

Showing 20 out of 1169 issues

Other

Component Properties
Name Type Description

Configuration

(Include) Pages matching Radio any of the following

all of the following

(Include) Tags Tag

(Exclude) Exclude pages Radio with any of the below tags

with all of the below tags

218
(Exclude) Tags Tag

Type Dropdo Article


wn
Gallery

Any

Premium Only Check Tick to show only premium articles


box

Starting index Number

Maximum number of items Number


to display

List ordering Radio Latest first

Oldest first

Design

Component heading Text

Layout Dropdo 4 col


wn
3 col

2 col

Hide publication dates Check To hide the publication date from displaying on the list items
box

Advertising

Advert position Number

Repeat adverts? Check Check box to allow adverts to repeat in the defined advert position e.g. if advert position is 2, advert slots would
box be inserted at position 2,4,6 etc.

Related Documents:
Document

The List Component MVP architecture

Error Handling

List Service stack

Run List service url AEM Core Pub Load balancer url
mode

Pre-prod http://alb.api-platforms-preprod.telegraph.co.uk http://internal-tmg-stg-64-INT-LIST-PUBS-1061199707.eu-west-1.elb.


/list-service/ amazonaws.com:4503/bin/list-service-adaptor

Prod http://alb.api-platforms.telegraph.co.uk/list- http://internal-tmg-prod-64-INT-LIST-PUBS-1229447255.eu-west-1.


service/ elb.amazonaws.com:4503/bin/list-service-adaptor

Pre- http://alb.api-platforms-preprod.telegraph.co.uk "curatedAdapter": "http://pub.aem-qa4.platforms-preprod-gcp.


prod-qa /list-service-qa/list-service/ telegraph.co.uk/bin/curated-list-service-adaptor",

"dynamicAdapter": "http://pub.aem-qa4.platforms-preprod-gcp.
telegraph.co.uk/bin/list-service-adaptor"

Pre- http://alb.api-platforms-preprod.telegraph.co.uk "curatedAdapter": "http://pub.aem-training.platforms-preprod-gcp.


prod- /list-service-training/list-service/ telegraph.co.uk/bin/curated-list-service-adaptor",
training
"dynamicAdapter": "http://pub.aem-training.platforms-preprod-gcp.
telegraph.co.uk/bin/list-service-adaptor"

219
Jenkins pipeline for list service : https://jenkins-prod.api-platforms.telegraph.co.uk/job/Pipeline/job/list-service/

List Service AWS accounts

Run mode AWS Account

Pre-prod https://130692012581.signin.aws.amazon.com/console

Prod https://385050320367.signin.aws.amazon.com/console

To fix any production issue, please install following package which will revert it back to original health page.

https://chase.telegraph.co.uk/crx/packmgr/index.jsp#/etc/packages/my_packages/health-backup.zip

After installing page, activate it from chase at this location activate the page from chase at this location cf#/content/telegraph/topics/things/h/health.html

Check Akamai cache expiry time of the page,

Run following command

curl -v -o /dev/null -H "Host: telegraph.co.uk" https://origin-www.telegraph.co.uk/health/

check

< Edge-Control: !no-store,max-age=1800,downstream-ttl=1800


< Cache-Control: max-age=1800

Monitoring List Service

https://eu-west-1.console.aws.amazon.com/ec2/v2/home?region=eu-west-1#TargetGroups:search=arn:aws:elasticloadbalancing:eu-west-1:385050320367:
targetgroup/list-ECSLo-1WWFT3CPE1CIK/25bf588e030526f5;sort=targetGroupName

List Service pre-prod logs - kibana url

220
Author 2 Template
Component

Nickname Author 2, Author Template 2


(s)

Synopsis Displays a list of articles written by a specific author and biographical information regarding the author.

Description Displays a list of articles written by a specific author and biographical information regarding the author. Serves as a data source
for the Byline component.

Interactions Serves as a data source for the Byline component.

Restrictions

Screenshot
(s)

Location /apps/telegraph/core/commons/templates/authorTemplate2

/apps/telegraph/core/commons/renderers/authorRenderer2

JIRA AEM-1560 - New Author page RELEASED

AEM-2276 - Convert existing Author pages to new Author 2 template RELEASED

Other
WARNING

At time of writing all of the author pages are currently located under the /telegraph/authors node. The sheer number
authors is far greater than was envisaged and has lead to there being many more items (pages) directly beneath the /t
elegraph/authors node than Adobe recommend.

The Adobe recommend that there should not be more than 1000 items directly under a single node. The reason given
for this is that the amount of data the browser needs to load can slow it greatly and possibly even crash it.

To resolve this problem it may be worth looking at bucketing the author pages, say by first letter of the authors' first
names (e.g.: /telegraph/authors/aaron-gillies might become /telegraph/authors/a/aaron-gillies).

221
Component Properties
Name Type Description

222
Author Bio
Component

Author Bio
Nickname
(s)

Component in use to provides information about the author or create profile page for author. Is used by default in Author 2 Template and it can be added as a component to other pages.
Synopsis
It works in conjunction with and as the data source for Byline component.

It is also the data source for the Headline component on the Author 2 Template.

Description

Interactions

Restrictions

Screenshot
(s)

Item Screenshot

Author Bio preview (with


Headline) in preview mode

Author Bio (with Headline)


in edit mode

Author Bio component


configuration tab

223
Author Bio component
image tab

(for Author's image)

Author Bio component


image tab

(for Author's image alt text)

224
Location telegraph-component/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/authorBio

Java Package
uk.co.telegraph.core.article.author

Classes:
Author.java
AuthorAdapterFactory
AuthorListItem
AuthorPath
AuthorTemplatePathFieldPredicate
AuthorUtil

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Author Bio Aug 19, Nov 21, Tomasz Tomasz RELEASED Unresolved
6510 component 2016 2016 Niedzwiedz Niedzwiedz
using unsafe [X] [X]
context
AEM- Meter - ESI Nov 09, Feb 03, 2016 Piotr Rzasa None RELEASED Unresolved
3221 tag changes 2015 [X]
to support
upgraded
meter - option
A
AEM- New Author Jul 13, 2015 Dec 14, Blazej Gavin Kirk RELEASED Unresolved
1560 page 2016 Kacikowski [X]
[X]
AEM- Author 2 page Nov 16, Feb 05, 2016 Michal None RELEASED Unresolved
3284 seems to stop 2015 Boruczkowski
render [X]
authors data
AEM- Curated List 2 Apr 12, Jun 29, 2016 Unassigned Gavin Kirk TO Unresolved
5295 does not pull 2016 [X] REFINE
in Author
page data
correctly

225
AEM- Byline Jul 10, 2015 Nov 02, Unassigned Gavin Kirk RELEASED Unresolved
1552 component 2015 [X]
implementatio
n
AEM- og:image Mar 08, Apr 21, 2016 Tomasz None RELEASED Unresolved
4722 meta not 2016 Niedzwiedz
present on [X]
author pages
AEM- Parse.ly May 21, Mar 01, 2016 Anna None RELEASED Unresolved
713 reporting 2015 Karkkainen
integration [X]
with ByLine
component
AEM- Update Author Sep 04, Sep 14, Blazej Gavin Kirk CLOSED Done
2277 meta tag so 2015 2015 Kacikowski [X]
can handle [X]
multiple
authors
AEM- Change the Jul 24, 2015 May 18, Unassigned Gavin Kirk CLOSED Done
1699 Twitter Handle 2016 [X]
meta tag to
take the
channel
setting
AEM- List treatment Nov 24, Dec 07, Unassigned Gavin Kirk CLOSED Done
3437 hierarchy for 2015 2015 [X]
Live &
Comment
articles
AEM- Google AMP - Jan 13, Mar 08, 2016 Unassigned Gavin Kirk CLOSED Done
3975 Basic article 2016 [X]
without
embeds, Ads
or Spark
AEM- CI - Review all May 15, Aug 25, Unassigned None RELEASED Unresolved
637 usage of wait 2015 2015
and sleep in
tests

13 issues

Other

Component Properties
Name Type Description

226
Autotweeting
Component
WARNING

At time of writing we have been advised by Digital Publishing that this feature is neither used in production nor wanted in the foreseeable
future.

At present is causes problems when developer or test instances are created that have valid autotweeting configured and then tweets start
going out to actual Telegraph twitter feeds with links to articles and/or galleries that are on developer of QA environments.

It would be desirable to route out how this keeps happening and remove/amend any content packages that autotweeting set up on any
channels.

Nickname Autotweeting, Automatic tweeting


(s)

Synopsis A service that posts tweets on behalf of the Telegraph's accounts whenever a new article is published.

Description Automatic tweeting can be configured on a per-channel basis in the Tools section. Pages based on the Twitter Configuration
template can be created in the channel-specific folders (each configuration page like this must be named twitter-config).

Each page based on this template has a Twitter Configuration Properties component, which allows the user to:

Toggle auto-tweeting for a given channel


Set up the API credentials for a twitter account associated with the channel.

227
Disabling autotweeting for a section
An arbitrary section of the content tree can be excluded form autotweeting by a checking the Disable Auto Tweet checkbox
available in the page properties on all commonly used page types.

Interactions

Restrictions

Screenshot
(s)

Location The package uk.co.telegraph.core.commons.tweeting contains the relevant Java code. Specifically, the TweetOnRepli
cationPreprocessor service is responsible for sending the tweets. It implements the com.day.cq.replication.
Preprocessor interface and it is invoked on page replication. Based on the configuration available, it may send a tweet linking
to the page being replicated.

For the configuration tools, see:

/apps/telegraph/core/commons/templates/twitterConfigTemplate - the tamplate, based on which twitter


configuration pages can be created

228
/apps/telegraph/core/commons/components/twitterConfig - the component from the configuration page in Tools

The Social tab that allows us to disable autotweeting for a content sub-tree can be found in tab_socials.xml

JIRA AEM-1230 - Social Media - Auto Tweet Article URL When Article First Published on AEM Live Production Server
RELEASED

Other
Do not copy autotweeting configuration from Production to a local instance. This can result in one or more of the
Telegraph's twitter accounts posting links to your local environment!

Component Properties
Name Type Description

229
Component

Nickname Autotweeting, Automatic tweeting


(s)

Synopsis

Description Automatic tweeting can be configured on a per-channel basis in the Tools section. Pages based on the Twitter Configuration
template can be created in the channel-specific folders (each configuration page like this must be named twitter-config).

Each page based on this template has a Twitter Configuration Properties component, which allows the user to:

Toggle auto-tweeting for a given channel


Set up the API credentials for a twitter account associated with the channel.

230
Disabling autotweeting for a section
An arbitrary section of the content tree can be excluded form autotweeting by a checking the _

Disable Auto Tweet

available in the page properties

Interactions

Restrictions

Screenshot
(s)

Location The package uk.co.telegraph.core.commons.tweeting contains the relevant Java code. Specifically, the TweetOnRepli
cationProcessor service is responsible for sending the tweets. It implements the com.day.cq.replication.
Preprocessor interface and it is invoked on page replication. Based on the configuration available, it may send a tweet linking
to the page being replicated.

For the configuration tools, see:

/apps/telegraph/core/commons/templates/twitterConfigTemplate - the tamplate, based on which twitter


configuration pages can be created

/apps/telegraph/core/commons/components/twitterConfig - the component from the configuration page in Tools

JIRA

Other
Do not copy autotweeting configuration from Production to a local instance. This can result in one or more of the
Telegraph's twitter accounts posting links to your local environment!

231
Component Properties
Name Type Description

232
Blank Template
Component

Nickname Blank Template


(s)

Description Blank Template used as place holder to create Blank page or to add other content, BlankRenderer (inherits from PageRenderer)
over-riding BodyText.html

Interactions

Restrictions

Screenshot
(s)

Location /apps/telegraph/core/commons/templates/blankTemplate (code in telegraph component)


/apps/telegraph/core/commons/renderers/blankRenderer (code in telegraph-component)

JIRA

Other

Component Properties
Name Type Description

233
Box Component
Component

Nickname(s) Box

Description

Interactions

Restrictions

Screenshot(s)

Location

JIRA

Other

Component Properties
Name Type Description

234
Breadcrumb Bar
Component

Breadcrumbs
Nickname
(s)

Displays the parents pages of the current page as a directory chain


Description

None
Interactions

This component is only available in the Sidekick on Bare pages. It's baked into the Article 2 and Gallery templates and cannot be added or removed to them.
Restrictions
Displaying of the breadcrumb can be enabled/disabled on a per-channel basis on the Feature Settings page found at /etc/telegraph/admin/features.html on the author instance.

JSON-LD representation
The breadcrumb component renders its JSON-LD representation in addition to the HTML with the links. It's going to appear as a script element with the type ld+json embedded into the Breadcrumb's
HTML.

Example representation of a breadcrumb in JSON-LD

<script type="application/ld+json" id="breadcrumb-json-ld-markup">


{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"item": {
"@id": "http://www.telegraph.co.uk/",
"name": "Telegraph"
}
},
{
"@type": "ListItem",
"position": 2,
"item": {
"@id": "http://www.telegraph.co.uk/lifestyle/",
"name":"Lifestyle"
}
},
{
"@type": "ListItem",
"position": 3,
"item": {
"@id": "http://www.telegraph.co.uk/fashion/",
"name": "Fashion"
}
},
{
"@type": "ListItem",
"position": 4,
"item": {
"@id": "http://www.telegraph.co.uk/fashion/shopping/",
"name": "Shopping"
}
}
]
}
</script>

Screenshot
(s)

/apps/telegraph/core/commons/components/breadcrumb
Location

235
JIRA
T Key Summary Assignee Reporter P Status Resolution Created Updated Due

CCORE- [SEO] Joe Young [X] None DONE Done Jul 30, 2014 Nov 06,
957 Breadcrumb / 2014
parental
taxonomy
mechanism
CLAR- Creating Daniel Joyce TO Unresolved Feb 14, May 22,
91 breadcrumb Cherino Adetula DO 2017 2017
TTCT- PROD - Unassigned Ioana Rahau CLOSED Done Jun 14, Mar 31, 2018
178 Breadcrumb [X] 2017
not correct for
Cruises
AEM- Author is Andrzej Andrzej RELEASED Unresolved Mar 10, Mar 24, 2016
4785 unable to use Dolinski [X] Dolinski [X] 2016
breadcrumb
component
TT-156 Breadcrumbs Tomek None CLOSED Done Jun 19, Jul 29, 2015
Component Stachowiak 2015
[X]
AEM- Breadcrumb Unassigned Mathias RELEASED Unresolved Aug 28, Oct 20, 2015
2188 changes Douchet 2015
AEM- Update Anna None RELEASED Unresolved Jun 26, May 25,
1363 breadcrumb Karkkainen 2015 2016
[X]
AEM-76 Breadcrumbs Unassigned None TO Unresolved Apr 10, Apr 10, 2015
REFINE 2015
TT-1152 UI left - Add Samantha Austin Harris RELEASED Unresolved Jan 07, Mar 21, 2016
breadcrumb to Edwards [X] [X] 2016
all pages
TTT-280 breadcrumbs Alan Churley Oana CLOSED Done Feb 24, Feb 28, 2017
overlapped by [X] Popescu [X] 2017
the drag&drop
component
MZUX- Breadcrumbs Unassigned None CLOSED Done Jan 07, May 12,
50 2015 2015
CHN- Breadcrumbs Luis None TO Unresolved Feb 26, Mar 24, 2015
1842 on Inner Khamashta DO 2015
Pages
AEM- Fashion and Unassigned None CLOSED Done Jul 07, 2015 Jul 09, 2015
1498 Beauty Article
breadcrumb
regression
WEB- Remove Deep Gareth Clubb RELEASED Done Dec 07, Jan 09, 2019
2076 Breadcrumb Liyanage [X] [X] 2018
on new Index
Channel
pages
WEB- Primary topic - Unassigned Anna Dezor CANCELLED Done Apr 14, Feb 06, 2019
300 No primary [X] 2017
tag is added
breadcrumbs
CCORE- Breadcrumb Unassigned None DONE Done Oct 27, Oct 29, 2014
1195 shows up on 2014
the Cars 404
error page
TTT- [FE] Create Bartosz sunil sidhu CLOSED Done Feb 27, Nov 07,
3933 Breadcrumbs Wisniewski [X] 2019 2019
on the New
Travel Index
Pages
CCORE- Error with Joe Young [X] Joe Young DONE Done Oct 20, Dec 15,
1172 Breadcrumb [X] 2014 2014
styling on
shop template
and
navigation
AEM- Too big gap Unassigned Anna RELEASED Unresolved Oct 09, Oct 20, 2015
2847 between the Karkkainen 2015
main header [X]
and
breadcrumb

236
AEM- Strip date Anna Gavin Kirk Unresolved Sep 28, Jan 13, 2016
RELEASED
2684 from Karkkainen [X] 2015
breadcrumb in [X]
dated articles

Showing 20 out of 226 issues

Other

Component Properties
This component has no dialog.

237
Byline
Component

Byline
Nickname
(s)

The component makes it possible to add one or more authors details such as name, role (optional) and location (optional) to an article and also serves as a link to the author's profile page which include
Description list of articles already posted by the author.

The position of the Byline component is different in Comment articles than what is displayed by other article types.

This component loads data from pages based on the Author Bio component on the Author 2 Template
Interactions

Restrictions

Screenshot
(s)

The Byline component can accept multiple authors:

/apps/telegraph/core/commons/components/byline
Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Byline Jul 10, 2015 Nov 02, Unassigned Gavin Kirk RELEASED Unresolved
1552 component 2015 [X]
implementatio
n
AEM- Display Byline Feb 11, Dec 17, Unassigned None RELEASED Unresolved
160 Preview 2015 2015
AEM- Manage Story Apr 16, Sep 29, Unassigned None TO Unresolved
169 Authors and 2015 2016 REFINE

238
Byline
AEM- Authors, May 27, Jun 23, 2015 Unassigned None READY Done
851 Byline and 2015 FOR
RELEASE
Byline
Preview
AEM- Style Byline & Aug 06, Aug 13, Thomas None TO Unresolved
1891 Date 2015 2015 Hartwig REFINE
Component
(UX)
AEM- Parse.ly May 21, Mar 01, 2016 Anna None RELEASED Unresolved
713 reporting 2015 Karkkainen
integration [X]
with ByLine
component
AEM- No tracking Feb 16, Mar 22, 2016 Unassigned Jedrzej RELEASED Unresolved
4451 for byline 2016 Osinski [X]
AEM- View Author May 20, Jun 25, 2015 Mel None CLOSED Done
665 Byline details 2015 Hambarsoomi
on the Finder an [X]
for each
Article
AEM- Make author Sep 08, Feb 18, 2016 Unassigned Gavin Kirk RELEASED Unresolved
2309 names in 2015 [X]
Byline link to
Author pages
AEM- Add byline to Jan 12, Mar 04, 2016 Unassigned None RELEASED Unresolved
3948 AMP article 2016
AEM- Reorder Mar 06, Mar 16, 2016 Unassigned None CLOSED Done
218 Authors in 2015
Byline
AEM- Replace Jul 10, 2015 Nov 02, Blazej Gavin Kirk CLOSED Done
1553 Author for 2015 Kacikowski [X]
Byline [X]
component
AEM- byline and Nov 17, Dec 01, Rachana Rachana CLOSED Done
3324 authorPath 2015 2015 Mehta Mehta
component
AEM- Byline styling Nov 04, Nov 04, Unassigned Grzegorz TO Unresolved
7008 issue 2016 2016 Bednarski [X] REFINE

AEM- Byline Sep 28, Oct 02, 2015 Unassigned Jedrzej CLOSED Done
2671 component 2015 Osinski [X]
not displayed
AEM- Comment in Mar 07, Jun 18, 2018 Michal None CLOSED Done
4711 lists - empty 2016 Boruczkowski
byline photo [X]
replaced by
lead asset
AEM- Styling and Jun 01, Aug 27, Unassigned None CLOSED Done
900 authoring of 2015 2015
the byline
component on
CQ
AEM- Display Apr 30, Aug 25, Unassigned None CLOSED Done
442 Author image 2015 2015
in Byline for
Contributors
AEM- Byline missing Dec 07, Jan 18, 2016 Unassigned Jo Harris [X] CLOSED Done
3664 from 2015
published
page
AEM- Spacing of Apr 12, Apr 21, 2016 Unassigned Jo Harris [X] RELEASED Unresolved
5297 byline 2016
placeholder
gone awry

Showing 20 out of 123 issues

Other

239
Component Properties
Name Type Description

240
Cluster template
Component

Nickname Cluster Template


(s)

Description Index page originally intended for Cluster pages. Is still in use the Cluster page but the Hub template does everything this could
be retired and should not be used when creating new cluster pages.
Cluster Template used for Page creation and Cluster Renderer renders the page

Interactions

Restrictions

Screenshot
(s)

Location

JIRA /apps/telegraph/core/commons/templates/clusterTemplate (code in telegraph component)


/apps/telegraph/core/commons/renderers/clusterRenderer (code in telegraph component)

Other

Component Properties
Name Type Description

241
Component Styles
Component Styles

Nickname N/A
(s)

Description Rather than a component, this is a mechanism used by multiple (almost all) components. AEM provides a way to provide different
styling versions for the same component. This can be configured by means of an ExtJS widget with the xtype of componentsty
les.

The widget makes a call to the component, using a selector, in order to obtain a list of applicable styles. This servlet is
customised, see uk.co.telegraph.core.commons.configuration.styling.CustomStylesServlet and it reads the
available styles for each component from etc/designs/telegraph/core/clientlibs/tmgchannels/jcr:content
node.

The base list of styles available on a per-component basis is defined in etc/designs/telegraph/core/clientlibs


/tmgchannels/.content.xml in telegraph-component

<versions
jcr:primaryType="nt:unstructured">
<version1
jcr:primaryType="nt:unstructured"
cssClass="version-1"
versionName="Version 1"/>
<version2
jcr:primaryType="nt:unstructured"
cssClass="version-2"
versionName="Drop caps"/>
</versions>

The cssClass value is the value added to the actual markup class attribute whilst the 'versionName' value is a more descriptive
term which will be displayed in the styles dropdown for authors.

The list of custom styles available for each component can be overridden per-channel but this capability has not been used to
date.

The setting appears in the Styles tab in the dialogs of various components. List, Curated List 2, Headline, to name a few.

Interactions Most TMG components

Restrictions

Screenshot
(s)

Location

JIRA AEM-376 - Make only applicable component styles available in AEM component dialogue CLOSED

242
AEM-437 - XML driven custom styles for component dropdown RELEASED

Other

Component Properties (Setting appears in multiple components)


Name Type Description

Style Dropdown List of styles available for a given component

243
Content structure - Channels, Sections and Articles
Component

Content structure - Channels, Sections and Articles


Nickname
(s)

At its most simple the site structure is comprised of the following parts:
Description

Item Description Templates Page Location in structure


Type

Portal Telegraph home page Portal Index /content/telegraph

Cluster A top level page that groups together channels by adding a Cluster link to the Header. Hub Index /content/telegraph/cluster

Usually, although not necessarily, aligned with the Business Segment. Cluster(1)

Channel Top level page splitting the site into its broadest categories. Hub Index /content/telegraph/channel

Section Second level page Index /content/telegraph/channel/section

Sub- Third level Index /content/telegraph/channel/section/sub-section


section

Date Folders in the content path to help organise content into a dated folder structure. Folder names follow the Folder Folder(2) /content/telegraph/channel/YYYY/MM/DD
Folder format of YYYY, MM or DD depending on whether they

Author A folder in the content path serving as a common parent for all author pages. Folder Folder(2) /content/telegraph/authors
Folder

Author A page listing all articles written (or endorsed) by a specifi person. Author 2 Index /content/telegraph/authors/firstname-lastname

Article An article page. Can exist in 3 distinct states all using the same template. General articles (story), Live Articles Article 2 Story /content/telegraph/channel/YYYY/MM/DD/article-name (if using the date-driven model)
and Video article (where the lead asset is an Ooyala video.
Live /content/telegraph/channel/section/article-name (if using the section driven model)

Video /content/telegraph/channel/section/sub-section/article-name (Spark sometimes organise their


clients commissioned content into sections and sub-sections)

Gallery The first page of a gallery. Gallery Gallery /content/telegraph/channel/YYYY/MM/DD/gallery-home (if using the date-driven model)

/content/telegraph/channel/section/gallery-home-page (if using the section driven model)

Gallery The slides of a gallery. Slides can each be navigated to directly via their unique deeplink URL. The exception is Gallery Slide Gallery(3) /content/telegraph/channel/YYYY/MM/DD/gallery-home-page/slide-name (if using the date-
Slide the first slide which can be reached via the gallery home URL. driven model)

/content/telegraph/channel/section/gallery-home-page/slide-name (if using the section driven


model)

Topic A page containing lists of article and galleries that all tagged with the same Topic tag. Topics Index /content/telegraph/topics/events/a/an-event-topic

There are 6 categories of generic topic pages: /content/telegraph/topics/in-the-news/a/a-concept-in-the-news-topic-page

Events /content/telegraph/topics/organisations/a/an-organisations-topic-page
In the news
Organsations
People /content/telegraph/topics/people/a/a-persons-topic-page
Places
Things /content/telegraph/topics/places/a/a-place-topic-page

There are also Branded topics pages which are just topic pages that are located within a channel.
/content/telegraph/topics/things/a/a-thing-topic

/content/telegraph/channel/topics/category/a-topic-page

(1) The Cluster concept began with some bespoke requirements that over and above those fulfilled by the Hub template. As the AEM migration project progressively released channels these requirement melted away and
page (www.telegraph.co.uk/culture) has already been released to production using the Cluster Template by the time this happened. This page page remains the only page on the site that uses this template. There is no te
could be decommissioned.

(2) Folder pages are not accessible to the public. They form part of the public facing URL but is a visitor tries to go to he page directly they will get a 404 page of the parent channel.

(3) See Gallery Template to read more about how the gallery and gallery slides are rendered.

Code Overview

Page creation using the required templates causes page properties to be inherited from applicable channel or main site.

The applicable templates have been defined.

Channels have optional "application" folders containing settings for styling, look of logos, navigation, side bars, error pages and snippets. These override settings of the Telegraph look.

New components added to a page pull on the existing Page properties set.

Interactions

Restrictions

Screenshot
(s)

Every template listed here can be found in /apps/telegraph/core/commons/templates and will have a corresponding Renderer (a component responsible for rendering an entire page). Renderers can be found in
Location

JIRA

Other Item Rugby Union Header (channel with a cluster) Culture Header (channel with a cluster)

244
Cluster
page

Channel
page

Header of Section page Header of Section page


Section
page
(and
lower
level
pages)

Link a
Cluster
to a
Channel

245
Item News Header (channel without a cluster) Business Header (channel without a clu

Header of Channel page Header of Channel page


Channel
page

Header of Section page Header of Section page


Section
page
(and
lower
level
pages)

Link a
Cluster

246
to a
Channel

Component Properties
Name Type Description

247
Curated List 2 & Curated List Tile 2
Curated List 2
This page replaces Curated List 2

Curated List 2
Nickname
(s)

Description Curated List 2


This component supersedes the Curated List. It allows authors to manually build lists very much like the ones rendered by the List component. As of Curated List 2, the same list item code is used
regardless of the component, which makes styling easier.

The Curated List 2 itself is simply a container for Curated List 2 Tiles. It provides a common parent for them for styling purposes and ensures a consistent content structure in which the tiles are the only
components allowed inside the Curated List 2.

The Curated List 2 is used when the editors want to have explicit control over what's in the list and don't want the content to update. One common use case are Editors' Picks.

Curated List Tile 2


The curated List Tile 2 is the component providing the actual link to a page. There are two ways a Tile can be configured.

1. Automatic configuration - all the user provides is a path of the page. All that's necessary to display the list item will be pulled in automatically by the back-end code.
2. Manual configuration - the author provides explicit values that override some or all of the elements displayed in the list item

If both field sets are populated, the component will render the list item based on what's on the page selected in the path field but it will overwrite the values with those provided in the manual
configurations (wherever applicable).

List items displayed by the Curated List Tile 2 are consistent with the List Items displayed by the List component when the same pages are displayed.

The Curated List component also supports Major News Blocke Tiles, described separately.

The Curated List 2 component uses the OverridingInjector, a custom Sling Models injector that allows for overriding model fields with request parameter values (matching by name).
Interactions

Only Curated List 2 Tiles and Major News Block Tiles can be placed inside a Curated List.
Restrictions

Screenshot
(s)

248
The component itself: /apps/telegraph/core/commons/components/curatedList2 (code in telegraph-component)
Location
The Java code implicitly using the OverridingInjector is scattered across uk.co.telegraph.core.commons.curatedlist2.Tile and the models behind the List Items, such as uk.co.
telegraph.core.article.model.Article2ListItem, uk.co.telegraph.core.commons.gallery.GalleryListItem, etc.

The latter models are used internally by the listItem.html HTL scripts for the various renderers. These are the same scripts as the ones used by the List component. In contrast to the List
component ,the Curated List 2 component only ever includes these by using data-sly-resource and does not use SSI.

The styles are shared with the List component, see /etc/designs/telegraph/core/clientlibs/core/sass/components/_component.list-of-entities.scss and related files.

JIRA Originally implemented as AEM-3888 - New Curated List (using common list item renditions) RELEASED

For a rough view of the components history, have a look at:

T Key Summary Assignee Reporter P Status Resolution Created Updated Due

AEM- Curated List 2 Unassigned Gavin Kirk TO Unresolved Apr 22, Oct 25, 2016
5495 fixes [X] REFINE 2016
AEM- Curated List 2 Unassigned Gavin Kirk TO Unresolved Apr 12, Jun 29, 2016
5295 does not pull [X] REFINE 2016
in Author
page data
correctly
AEM- Migrate Unassigned Jo Mitchell TO Unresolved Mar 31, Jul 07, 2016
5130 functionality [X] REFINE 2016
from Curated
List to
Curated List 2
- Slider
AEM- Curated List 2 Unassigned Gavin Kirk CLOSED Done Apr 11, Jun 18, 2018
5276 not respecting [X] 2016
sponsored list
items logic
AEM- Hide primary Tomasz Jo Mitchell IN Unresolved Jul 19, 2016 Nov 17,
6258 tag from Niedzwiedz [X] DEV 2016
Curated List 2 [X]
items
AEM- Wrong Unassigned None CLOSED Done Mar 14, Mar 15, 2016
4850 markup for 2016
Curated List 2

249
AEM- Spike: Moving Unassigned Jo Mitchell CLOSED Done May 13, Jun 18, 2018
5694 hero block to [X] 2016
curated list 2
AEM- Amend LV20 Blazej Mark Cyrson RELEASED Unresolved Mar 18, Mar 24, 2016
4955 (opinion) to Kacikowski 2016
use Curated [X]
List 2
AEM- Label: not Unassigned None RELEASED Unresolved Mar 03, Apr 05, 2016
4663 colored for 2016
curated list tile
2 on MNB
AEM- Curated List Unassigned Gavin Kirk TO Unresolved Apr 22, Jul 07, 2016
5497 Tile 2 - [X] REFINE 2016
general fixes
AEM- Curated List 2 Krzysztof Robert RELEASED Unresolved Mar 10, Apr 12, 2016
4787 Tile can be Gorzynski [X] Toshman 2016
added to a
Video Hub
Template
Parsys
without the
Curated List 2
component
AEM- Most Viewed Daniel Gavin Kirk IN Unresolved Oct 25, Oct 28, 2016
6977 List to use Madejek [X] [X] DEV 2016
Curated List 2
as its core
AEM- Migrate Unassigned Jo Mitchell TO Unresolved Jul 07, 2016 Jul 07, 2016
6179 functionality [X] REFINE
from List to
Curated List 2
- Time Breaks
AEM- Migrate Unassigned Jo Mitchell TO Unresolved Jul 07, 2016 Jul 07, 2016
6178 functionality [X] REFINE
from List to
Curated List 2
- Time Labels
AEM- Video - Anna Dezor Robert RELEASED Unresolved Mar 03, May 05,
4671 Sponsorship [X] Toshman 2016 2016
and
Sponsored -
Sponsored in
the List or
Curated List 2
AEM- Curated list 2 Unassigned Jedrzej TO Unresolved Oct 19, Oct 19, 2016
6946 tile removed if Osinski [X] REFINE 2016
the link set to
a listing page
AEM- Hide date/time Andrzej Gavin Kirk RELEASED Unresolved Jun 27, Aug 01,
6116 from Curated Dolinski [X] [X] 2016 2016
List 2 tiles
AEM- Live article Unassigned Anand CLOSED Done Oct 20, Feb 12, 2018
7700 heading is not Shirkande 2017
displayed if
added to
curated list 2.
AEM- Missing Anna Krzysztof CLOSED Done Mar 14, Apr 04, 2016
4852 invalidation Karkkainen Gorzynski [X] 2016
lead image in [X]
curated list 2
item
AEM- Curated List 2 Unassigned Gavin Kirk TO Unresolved Apr 20, Jun 29, 2016
5426 - external links [X] REFINE 2016
should be
open in a new
window

Showing 20 out of 210 issues

Other
The Curated List 2 uses the same styles as the List component

250
The Curated List 2 does not use Server Side Includes. It only gets updated together with the containing page. However, content based on Curated List 2 can be shared between pages
using Snippets.

The Curated List 2 component has about 20 styling variants that it shares with the List component. It can look very different to what's depicted in the screenshots above depending on the
chosen layout. See the Style Guide for examples.

Component Properties

Curated List 2

Tab Name Type Description

Configuration Hide date/time Checkbox Removes timestamps from all list items (they're not actually removed from the markup, just hidden)

Heading and footer Component Heading Text An optional heading to display above the list

Component Heading Link Path field The heading can be a link to a page. Use this field to configure where it should lead to.

Component Subheading Text Optional text to display below the heading.

Component Footer Link Label Text A piece of text to display after all the list items.

Component Footer Link Path field A link to a page

Styles Style Dropdown The styling variant of the list.

Branding Branding Dropdown Choose if the list is supposed to be displayed as a list of premium articles.

251
Curated List & Curated List Tile
Component

Nickname Curated List (not to be confused with Curated List 2)


(s)

Description Conceptually similar to the Curated List 2, the major exception being that the Curated List Tile does not use the same views to
render List Items as the Curated List Tile 2. This resulted in markup inconsistencies that were difficult to style. The Curated List
component has been deprecated and should only be used by Spark at the moment. However, it's still quite commonplace on the
live site.

In contrast to the List and Curated List 2 components, which delegate the rendering of the items to the listItem scripts defined
by each supported renderer, the Curated List uses its own presentation-layer code based on custom scripts and a set of HTL
templates (some of which are shared with List, which makes it neither consistent with, nor independent from the List component ).
It also doesn't use SSI or data-sly-resource and instead relies on a separate Java model to adapt the underlying content of
the pages being linked to.

Interactions

Restrictions

Screenshot
(s)

Location /apps/telegraph/core/commons/components/curatedList

uk.co.telegraph.core.commons.curatedlist.CuratedTile

JIRA

Other
Kill it with fire

Component Properties
Name Type Description

252
Entities (Cars, Film, Best)
Component

Nickname Entities
(s)

Synopsis A (sort-of) common data model for content from the old Cars, Film and Best pages.

Description See:

Entities
Related Entities

Entities are NOT supposed to be used any more. None of the current Channels uses entities. Certain components,
such as List and Metatag refer to Entities in their configuration. These options are used in old code that should be
removed. If it hasn't been removed, it's due to the prevalence of those components in the automated tests from cheeta
h-automation, specifically complex scenarios tying multiple components together. In most cases, those scenarios
test actually used components but their implementation heavily relies on templates and components that have been
deprecated.

Interactions ?

Restrictions ?

Screenshot ?
(s)

Location ?

JIRA ?

Other

Component Properties
Name Type Description

253
Error Pages
Component

Error Pages, 404, 500


Nickname
(s)

Error pages are just simple pages with basic component that display text and imagery. The status codes are determined by Sling, this mechanism is not customised in direct relation to the Error Page
Description templates/renderers. The selection of the page to serve upon facing an error status code is determined by Apache. This is configured using standard ErrorDocument directives.

Code Overview
Settings in the Apache configuration at tmg-aem through error page "document location matches" enable the correct 404 html pages to be invoked. Application folder 404 html files in each channel
inherit branding and styling making them different from other 404 html files.

The telegraph root 404 html pages is created with the defaultErrorPageTemplate, which is rendered with the defaultErrorPageRenderer (This is most likely a content issue and not the desired
situation!), and for the channel error pages the genericErrorPageTemplate and the genericErrorPageRenderer are used.

The error Page Template use the following templates:

Headline
Standfirst
Lead Asset
Article Body Text

Interactions

Restrictions

Screenshot
(s)

254
/apps/telegraph/core/commons/templates/defaultErrorPageTemplate (code in telegraph component)
Location /apps/telegraph/core/commons/templates/genericErrorPageTemplate (code in telegraph component)
/apps/telegraph/core/commons/renderers/defaultErrorPageRenderer (code in telegraph component)
/apps/telegraph/core/commons/renderers/genericErrorPageRenderer (code in telegraph component)

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Add Analytics Sep 28, Aug 09, Unassigned Gavin Kirk IN Unresolved
2677 to 404 error 2015 2017 [X] DEV
pages
AEM- Lack of error Jul 11, 2016 Jun 18, 2018 Owen Tuz [X] Anna Dezor CLOSED Done
6197 page - topic [X]
page
AEM- Generic Error Jul 03, 2015 Jul 07, 2015 Unassigned Patrycja CLOSED Done
1459 page: The Kurkowiak

255
'ban' advert is [X]
too wide on
tablet (portrait
view)
AEM- Film: creation Apr 15, Apr 27, 2015 Anna Melinda CLOSED Unresolved
126 of new Index 2015 Karkkainen Rogers [X]
page error [X]
AEM- When Feb 12, Jul 11, 2016 Michal None CLOSED Done
4403 activating 2016 Boruczkowski
portal page [X]
/snippets
errors occur in
error.log
AEM- Syndication Mar 21, Mar 22, 2018 Unassigned Prem Moka CLOSED Done
7773 page error - 2018
Page not
found
AEM- ANALYTICS: Sep 18, May 18, Unassigned Jodi Fraser TO Unresolved
2512 Add Adobe 2015 2016 [X] REFINE
DTM tag to
error pages
AEM- Error on Nov 03, May 19, Unassigned Krzysztof CLOSED Done
3168 submit 2015 2016 Gorzynski [X]
comparision
page
AEM- Generic Error Jul 02, 2015 Jul 03, 2015 Patrycja Patrycja CLOSED Done
1427 Page Kurkowiak [X] Kurkowiak
template: [X]
there is no
message if
Image Alt is
not set
AEM- /error on Oct 19, Oct 19, 2016 Unassigned Andrzej TO Unresolved
6948 production 2016 Dolinski [X] REFINE
returns 403
page
AEM- Politics page Mar 23, Mar 23, 2018 Nayeem Prem Moka CLOSED Done
7778 returning 404 2018 Mohammed
error
AEM- Error while Jun 26, Jun 28, 2017 Anna Dezor Anna Dezor CLOSED Done
7588 trying to 2017 [X] [X]
activate a
page
AEM- JS errors after Mar 19, May 20, Unassigned Patrycja CLOSED Done
1235 twitter-config 2015 2016 Kurkowiak
page has [X]
been opened
AEM- Display page Jun 17, Jul 12, 2016 Unassigned Gavin Kirk TO Unresolved
6054 title in heading 2016 [X] REFINE
for Portal error
pages
AEM- Minified Dec 12, Dec 12, Unassigned Anna Dezor TO Unresolved
7152 exception 2016 2016 [X] REFINE
error on play
pages
AEM- Internal server Apr 12, Apr 14, 2016 Krzysztof Anna Dezor CLOSED Done
5285 error on 2016 Gorzynski [X] [X]
opening a
new page on
dispatcher
AEM- Stacktrace in Jul 08, 2015 May 20, Unassigned None CLOSED Done
1718 publish error. 2016
log after page
activation
AEM- Error when Jun 20, Jun 27, 2017 Anna Dezor Anna Dezor CLOSED Done
7576 trying to open 2017 [X] [X]
a page in
authoring
AEM- Lack of May 04, Jun 18, 2018 Unassigned Anna Dezor CLOSED Done
5579 generic error 2016 [X]
pages for
some
channels
AEM- No generic Apr 04, May 12, Unassigned Anna Dezor CLOSED Done

256
5183 error pages 2016 2016 [X]
for news,
lifstyle and
culture

Showing 20 out of 363 issues

Other

Component Properties
Name Type Description

257
Folder Template
Component

Folder Template
Nickname
(s)

Non AEM template, which is not accessible to the user, ie when a user tries to access the folder or a resource in the folder a 404 page is returned.
Description FolderRedirectionFilter captures the path using the Servlet Api Filter causing the 404 page error.

Interactions

Restrictions

Screenshot
(s)

/apps/telegraph/core/commons/templates/folderTemplate (code in telegraph component)


Location FolderRedirectionFilter.java (code in telegraph component)

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Folder Jul 06, 2015 Oct 01, 2015 Unassigned Gavin Kirk CLOSED Done
1482 template [X]
AEM- Folder Jul 09, 2015 Oct 01, 2015 Unassigned Gavin Kirk CLOSED Done
1521 template icon [X]
AEM- Backend - Jun 01, Oct 02, 2015 Michael Michael RELEASED Unresolved
891 DEV: create 2015 Goszczynski Goszczynski
per-channel
configuration
of non-IAB
ads
AEM- Non IAB Ads May 05, Aug 24, Patrycja None RELEASED Unresolved
474 Enabled 2015 2015 Kurkowiak [X]
AEM- Finder don't May 27, Jun 22, 2015 Unassigned None RELEASED Unresolved
829 display stories 2015
when content
is wrong.
AEM- Topic Jun 23, Dec 02, Unassigned Gavin Kirk RELEASED Unresolved
1295 template 2015 2015 [X]
AEM- 62AMS - Apr 24, Jun 27, 2017 Johnny Ooi Lucian CLOSED Done
7476 Spike on now 2017 Craciun
to build the
new prod env
AEM- Authoring Sep 22, Dec 10, Unassigned None RELEASED Unresolved
2555 supports 2015 2015
channels that
use date
folders for
content
AEM- Sponsored Dec 17, Feb 02, 2016 Unassigned Gavin Kirk CLOSED Done
3836 Topics 2015 [X]
AEM- Revised Nov 12, Dec 03, Tomasz Gavin Kirk RELEASED Unresolved
3257 template rules 2015 2015 Niedzwiedz [X]
to support [X]
manual
creation of
dated article
AEM- Video Finder Feb 24, Aug 08, Andrzej Robert READY Unresolved
4539 Alternative - 2016 2016 Dolinski [X] Toshman FOR DEV
Use the
Segment
Container
/Snippet for
the Video Hub
Template and
Video Play
Pages
AEM- Branding of Sep 28, Nov 05, Unassigned Gavin Kirk CLOSED Done
2682 Topic pages 2015 2015 [X]
AEM- Changes to Dec 03, Mar 16, 2016 Unassigned Jo Harris [X] CLOSED Done
3619 structure tags 2015

258
on Channel
pages are
reflected on
child pages
AEM- Enable Dec 17, Mar 04, 2016 Unassigned Gavin Kirk RELEASED Unresolved
3834 configuring of 2015 [X]
Sponsor Slots
in AEM
AEM- Spark embed Dec 17, May 06, Andrzej Gavin Kirk RELEASED Unresolved
3838 slots 2015 2016 Dolinski [X] [X]
AEM- NonIAB is Jun 12, Oct 02, 2015 Unassigned Patrycja RELEASED Unresolved
1123 visible also on 2015 Kurkowiak
another [X]
templates
than Hub and
Article2
template
AEM- nonIAB: Jun 12, Oct 02, 2015 Patrycja Patrycja RELEASED Unresolved
1132 Investigate. 2015 Kurkowiak [X] Kurkowiak
Carousel [X]
component
doesn't work
on publish
AEM- Errors While Jul 21, 2015 Oct 02, 2015 Unassigned Tomasz CLOSED Done
1659 Using the Niedzwiedz
Dialog of a [X]
Folder Page
AEM- Anchor links Oct 19, Oct 19, 2016 Unassigned Pedro TO Unresolved
6949 on Navigation 2016 Hernandez REFINE
bar
AEM- Spark Slots Apr 12, May 06, Blazej Blazej RELEASED Unresolved
5286 configuration 2016 2016 Kacikowski Kacikowski
not available [X] [X]
on Destination
and Bare
Templates

Showing 20 out of 68 issues

Other

Component Properties
Name Type Description

259
Gallery Teaser
Component

Gallery Teaser
Nickname
(s)

The Gallery Teaser makes image galleries discoverable by providing a preview of a Gallery that also serves as a link.
Description
The configuration dialog allows for the user to link to an Image gallery. Based on this link, the component picks up the image from the first slide of the Gallery as well as the headline of the Gallery page
and renders them in the teaser.

The icon next to the link makes it clear that the page the teaser links to is a Gallery.

The pathfield in the dialog only displays Gallery pages.

Interactions

Restrictions

Screenshot
(s)

/apps/telegraph/core/commons/components/galleryTeaser (sources in telegraph-component)


Location
uk.co.telegraph.core.commons.gallery.GalleryTemplatePredicate defines the predicate used in the dialog to only display Gallery pages in the pathfield.

JIRA Originally implemented under AEM-64 - Gallery Teaser CLOSED

T Key Summary Assignee Reporter P Status Resolution Created Updated Due

AEM- Hover state Unassigned Anna Dezor CLOSED Done Jun 03, Jun 15, 2015
975 for gallery [X] 2015
teaser
AEM- Gallery Blazej Gavin Kirk RELEASED Unresolved May 08, Jun 22, 2015
531 Teaser is too Kacikowski [X] 2015
large [X]
AEM-64 Gallery Unassigned Gavin Kirk CLOSED Done Apr 09, Nov 28,
Teaser [X] 2015 2016
AEM-15 Basic Gallery Unassigned None RELEASED Unresolved Mar 31, Jun 22, 2015
Teaser going 2015
to a Gallery in
standalone
mode
AEM-17 Author a Unassigned None RELEASED Unresolved Mar 31, Jun 22, 2015
Gallery 2015
Teaser in an
article
AEM- Blue line in Unassigned Gavin Kirk CLOSED Done Jun 25, Jan 14, 2016
1359 Gallery [X] 2015
Teaser
AEM- Gallery Unassigned Gavin Kirk CLOSED Done Jul 10, 2015 May 18,
1549 Teaser v2 [X] 2016
AEM- Make text Unassigned Gavin Kirk CLOSED Done May 08, Aug 18,
532 selectable in [X] 2015 2015
the Gallery
Teaser
AEM-62 Display Unassigned Gavin Kirk CLOSED Done Apr 09, May 18,
Headline or [X] 2015 2016
Caption in an
Gallery
Teaser
AEM- Gallery Unassigned Gavin Kirk CLOSED Done May 08, Aug 18,
530 Teaser has no [X] 2015 2015
hover state
AEM-60 Display slide Unassigned Gavin Kirk Unresolved Apr 09, Jun 22, 2015

260
count in [X] RELEASED 2015
Gallery
Teaser
AEM-78 Display Credit Blazej Gavin Kirk CLOSED Done Apr 10, May 18,
& Source in Kacikowski [X] 2015 2016
an Gallery [X]
Teaser
AEM-63 Gallery Unassigned Gavin Kirk CLOSED Done Apr 09, May 18,
Teaser linking [X] 2015 2016
to pseudo-
overlay
Gallery
AEM- Gallery Michal None RELEASED Unresolved Sep 23, Feb 11, 2016
2612 teasers bug Boruczkowski 2015
[X]
AEM-61 Enable author Unassigned Gavin Kirk CLOSED Done Apr 09, May 18,
to select a [X] 2015 2016
slide in a
Gallery
Teaser
AEM- Gallery teaser Blazej Anna Dezor CLOSED Done May 12, Jun 08, 2015
587 incorrectly Kacikowski [X] 2015
alligned inside [X]
Inline Content
component
AEM- Gallery teaser Unassigned None CLOSED Done Sep 28, Jan 14, 2016
2661 component - 2015
select path
menu loading
time.
AEM- Gallery teaser Unassigned Anna Dezor RELEASED Unresolved May 19, Aug 25,
660 should not [X] 2015 2015
affect content
type of artice
2
AEM- W3C CSS Unassigned Patrycja RELEASED Unresolved Aug 14, Dec 02,
1973 error on Kurkowiak 2015 2015
gallery-teaser [X]
button -
Unknown
dimension
AEM- Un-quarantine Marek Tero Pikala CLOSED Done Jul 28, 2015 Aug 05,
1738 or refactor Krokosinski [X] 2015
tests in [X]
features
/lifestyle
/gallery_teaser
.feature

Showing 20 out of 45 issues

Other

Component Properties
Name Type Description

Gallery Pathfield Path of the Gallery to link to

261
Gallery Template
Component

Nickname Gallery Template, Gallery, Image Gallery


(s)

Description The Gallery Template is used on Gallery Page creation and Gallery Renderer is used to render the Gallery Page.
A Gallery page requires at least one Gallery Item Slide.

Every slide is created as a child page of the main Gallery page.

Configuring a Gallery
The items common to all Gallery slides are configured on the Gallery page itself. This includes:

the headline (Headline component embedded in the Renderer),


the social sharing buttons (Social Share component embedded in the Renderer),
the social follow component (Social Follow component embedded in the Renderer).

All components present on a page based on the Gallery Template are baked into the template. It is not possible to drag-and-drop
additional components onto the page from the Sidekick. There are no paragraph systems available on the page.

In order to configure the slide-specific settings one must visit a slide page itself on the Author instance in Edit mode. Other WCM
Modes will not enable the user to display the slide configuration and will instead display the slide in context of the Gallery page.

Gallery navigation
A user can navigate between Gallery slides using navigation buttons or by sliding the image horizontally (especially on touch-
enabled devices).

The Gallery also supports a Thumbnail View where miniatures of all slides are displayed. This view can be used to navigate to an
arbitrary slide.

Every time the user navigates to another slide, the URL in the browser bar will change. When this happens, the page is not
actually reloaded. In reality, it's the JavaScript that switches the window.location value. The data necessary to display every
slide is rendered on the Gallery page as well as on every slide as a script tag containing a JSON document describing the
entire Gallery (including links to images for every slide, titles, descriptions, etc.). When JavaScript is disabled in the browser, the
Gallery falls back to a mode where the navigation buttons are links to separate slide pages. The Thumbnail view is not accessible
in this mode.

Deep linking
Every slide is fully addressable (has its own, unique URL based on the name of the Gallery Item page). Reordering the slides
does not change their URLs.

The first slide will also be visible when the user visits the gallery page itself. Upon loading whichever slide is currently the first one
in the gallery, the user will be redirected to the main Gallery page.

The Social Share component reads the shared URL from the browser bar so it follows the same convention. Reordering slides will
not break previously shared links. Re-naming them (effectively moving the page in AEM, not just adjusting the title), however, will.

262
The Thumbnail view has no URL of its own so it cannot be linked to.

Script resolution
Depending on the WCM mode, AEM will display slides in two possible modes.

1. In WCM Mode Edit, the slide will appear as a basic configuration page where the user can set the image, title and other
properties pertaining to the specific slide.

2. In other WCM modes, the slide will be rendered as it appears to a visitor of the site, in context of the Gallery page itself.

This is implemented in the GalleryRedirectionFilter class. Depending on the WCM Mode, it will cause the request to be
processed by the Gallery Item or the Gallery Renderer.

Gallery Replication
The Gallery page as well as every single slide contains a JSON document describing the entire gallery in its source. This
document is cached together with the whole HTML representation of the Gallery as well as every Slide by the Dispatcher, as well
as Varnish and Akamai. Technically, this data comes from multiple pages (every slide was implemented as a page of its own to
implement deep linking and meet the non-JS fallback requirement.).

263
Because of this, it's possible for incomplete pages to be cached by the Dispatcher if the Gallery page is replicated without the
slides or if a slide is replicated prior to the activation of a gallery page.

In order to work around this limitation, it has been made impossible to activate pages based on the Gallery Slide template.
Activating the Gallery page itself will cause them to be replicated.

Additionally, the way the Gallery and its Slides are replicated is customised. See the GalleryReplicationListener Java
class to see how this was implemented.

Gallery Advert
Rendering of Gallery Adverts is dependent on the viewport size.

Desktop
The Mid-Page Unit (MPU) advertisement is displayed next to the Gallery in a sidebar. The Gallery JavaScript controls the
MPU to some extent. The advert is switched to another one once the user goes to another slide provided that enough time
has passed since the current ad has been loaded. This time period is configurable as the Minimum Ad Viewability time on
configuration pages placed in the Tools section. The global config can be found in /miscadmin#/etc/telegraph/core
/adverts-config and can be overriden on a per-channel basis by creating a channel specific configuration page. For
example, to override the settings for the Fashion channel, one would go to /miscadmin#/etc/telegraph/core
/fashion/adverts-config
The default value of the Minimum Ad Viewability setting is 5000 milliseconds.
Mobile devices
The advertisements are interstitial (they are displayed as slides gallery slide). An advertisement slide is displayed after every
sequence of five slides unless otherwise configured in /miscadmin#/etc/telegraph/core/adverts-config or its
channel-specific counterpart.

The behaviour of Ads in galleries is a subject of ongoing discussion. The Minimum Ad Viewability settings is going to
be removed or re-interpreted in the aftermath of AEM-6465 - SMoG - Sticky MPU on Gallery pages RELEASED

There is a number of components baked into this template. These are:

Headline
Social Follow
Social Share
Advert

Interactions Uses Headline, Social Share, Social Follow and Advert components.

Restrictions Gallery pages can be created in Channels, Sections and Clusters. Slides can only be created as children of Gallery pages. Slides
can have no child pages.

Screenshot
(s)

264
Location /apps/telegraph/core/commons/renderers/galleryRenderer (code in telegraph component)
/apps/telegraph/core/commons/templates/galleryTemplate (code in telegraph component)
/apps/telegraph/core/commons/renderers/galleryItemRenderer (code in telegraph component)
/apps/telegraph/core/commons/templates/galleryItemTemplate (code in telegraph component)
/apps/telegraph/core/commons/components/gallery (code in telegraph component)
/apps/telegraph/core/commons/components/galleryItem (code in telegraph component)
For Gallery/GalleryItem Java Class go to (code in telegraph component)

The rendering of slides is delegated to the Gallery component or the Gallery Item renderer (configuration page) using the Galler
yRedirectionFilter

JIRA ML-2 - Gallery Template RELEASED ML-5 - View an Image in a Gallery RELEASED

ML-32 - SASS & HTML READY FOR RELEASE

Other Gallery Item configuration:

265
Component Properties
Name Type Description

266
267
Google AMP
Google AMP, Google Accelerated Mobile Pages, GAMP
Nickname
(s)

AMP stands for Accelerated Mobile Pages, a Google-backed project designed as an open standard for any publisher to have pages load quickly on mobile devices. On Feb. 24, 2016, Google officially
Synopsis
integrated AMP listings into its mobile search results.

In January 2016 it was decided there was a need to serve Google AMP pages from AEM in order to fit in with Googles new policies for page rankings and SEO. The initial decision was to create a basic
Description article page containing the main components used to serve the content. This functionality was then parked when

it was realised that as News was at this time still on eScenic it would not be available via this method and so placeholder functionality was instead developed using the content-api.

However the Web teams had by this point already created a viable Google AMP article from AEM which had been implemented for the following components:

articleBodyImage
articleBodyText
byline
headline
leadAsset
primaryLogoBar

And also a new components/template.html had been created for responsive and thumbnail image functionality.

There is a separate tmgAmp channel for styling the simpler presentation of various components.

Interactions

Restrictions

Usage
instructions

Screenshot
(s)

268
269
Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Premium AMP Oct 18, Oct 19, 2016 Unassigned Rima Amin CANCELLED Unresolved
6922 (Google AMP) 2016
AEM- Google AMP Jan 15, Jun 26, 2017 Unassigned Gavin Kirk TO Unresolved
4012 Pay Wall 2016 [X] REFINE

AEM- Google AMP Oct 13, Nov 07, Unassigned Mark Cyrson TO Unresolved
6893 improvements 2016 2016 REFINE

AEM- Add Google Feb 10, Mar 17, 2016 Unassigned None CLOSED Done
4354 AMP switch in 2016
OSGi service
AEM- Google AMP - Jan 14, Feb 02, 2016 Unassigned Gavin Kirk CLOSED Done
3989 Spark 2016 [X]
sponsored
articles
AEM- Google AMP - Dec 24, Dec 12, Unassigned Gavin Kirk RELEASED Unresolved
3852 Stripped down 2015 2016 [X]
article
AEM- Google AMP - Dec 24, Mar 08, 2016 Unassigned Gavin Kirk CLOSED Done
3854 Gallery in 2015 [X]
Google AMP
format
AEM- Google AMP - Jan 26, Mar 08, 2016 Unassigned Gavin Kirk CLOSED Done
4120 Particles in 2016 [X]
articles
AEM- Google AMP - Dec 24, Mar 08, 2016 Unassigned Gavin Kirk CLOSED Done
3853 Embeds in 2015 [X]
articles
AEM- Google AMP - Jan 14, Mar 08, 2016 Unassigned Gavin Kirk CLOSED Done
3986 IAB Ads 2016 [X]
AEM- Help Byron Feb 01, Mar 15, 2016 Unassigned None CLOSED Done
4230 with Google 2016
AMP styling
AEM- Google AMP - Jan 14, Mar 08, 2016 Unassigned Gavin Kirk CLOSED Done
3988 Spark 2016 [X]
sponsorship
on articles
AEM- Google AMP - Jan 12, Mar 08, 2016 Unassigned Gavin Kirk CLOSED Done
3966 Page view 2016 [X]
tracking on
GAMP pages
AEM- Google AMP - Jan 15, Jun 10, 2016 Unassigned Gavin Kirk CLOSED Done
4018 Update 2016 [X]
copyright year
in footer
dynamically
AEM- Google AMP - Jan 13, Mar 08, 2016 Unassigned Gavin Kirk CLOSED Done
3975 Basic article 2016 [X]
without
embeds, Ads
or Spark
AEM- Google AMP: Oct 21, Jan 29, 2016 Piotr Rzasa Melinda RELEASED Unresolved
2994 Add rel=" 2015 [X] Rogers [X]
amphtml" to
every AEM
article and
gallery page
AEM- Dispatcher Jan 13, Mar 04, 2016 Unassigned Gavin Kirk RELEASED Unresolved
3970 config for 2016 [X]

270
Google AMP
AEM- Investigate a Sep 11, Nov 23, Richard Dave CLOSED Done
2378 solution for 2015 2015 Spence Sanders
supplying
AMP-HTML to
Google (??-
XL-$)
AEM- Google AMP Jan 12, May 18, Unassigned Gavin Kirk CLOSED Done
3952 analytics - 2016 2016 [X]
tracking page
views
AEM- For Apple Oct 30, May 17, Unassigned Melinda TO Unresolved
3141 News, Google 2015 2017 Rogers [X] REFINE
AMP or
Facebook IA

Showing 20 out of 32 issues

Related Google AMP


links Google AMP
Google AMP POC
SOP - Google AMP
Google AMP - Releases

Other

271
Google AMP POC
Component

Nickname Google AMP, AMP, GAMP, Accelerated Mobile Pages


(s)

Synopsis A Proof of Concept supporting Acceletated Mobile Pages in AEM https://www.ampproject.org/

Description Requesting a page with the amp selector allows components to render in an AMP-compliant format. This means an article will
show as a lightweight, stripped down view.

This feature is not currently used. AMP pages are served based on the Content API and not requested from AEM
directly.

In order to make a page render an AMP view, request it with the ampselector. Then an alternative script will be chosen for its
renderer. That script will modify the clientlibs included so that only the AMP-specific scripts and CSS are loaded. The selector will
also be passed to all components included on that page. Each component with a supported AMP version will render using its own
amp HTL script. Components that are not supported will also have such scripts, except those will only contain a Sightly comment
documenting the level of support.

Image crops don't seem to work as expected on AMP pages served directly from AEM due to regression. The decision
not to request AMP renditions from AEM directly was made before significant changes to crop support. The new
features were never retrofitted to work with the AMP view.

Interactions

Restrictions

Screenshot
(s)

Location amp.html scripts for multiple components (including renderers)

A meta tag processor was implemented to make the AMP URL publicly accessible, see uk.co.telegraph.core.commons.
metatag.processors.GoogleAmpProcessor, it can be enabled by providing an Externalizer config for an "amp" domain.

JIRA WEB-135 - Google AMP TO DO

272
AEM-3852 - Google AMP - Stripped down article RELEASED

AEM-4097 - Link Article to GAMP Article RELEASED

Other

Component Properties
Name Type Description

Component

Nickname(s) Google AMP, AMP, GAMP, Accelerated Mobile Pages

Synopsis A Proof of Concept supporting Acceletated Mobile Pages in AEM https://www.ampproject.org/

Description Requesting a page with the amp selector allows components to render in an AMP-compliant format.

This feature is not currently used. AMP pages are served based on the Content API and not requested from AEM
directly.

Interactions

Restrictions

Screenshot
(s)

Location amp.html scripts for multiple components

A meta tag processor was implemented to make the AMP URL publicly accessible, see {{

uk.co.telegraph.core.commons.metatag.processors

JIRA WEB-135 - Google AMP TO DO

AEM-3852 - Google AMP - Stripped down article RELEASED

AEM-4097 - Link Article to GAMP Article RELEASED

Other

Component Properties
Name Type Description

273
274
Hard Regwall (ESI)
Component

Nickname Registration wall, hard regwall, regwall


(s)

Description The Paywall is built using AEM components:

registrationTemplate

registrationWallList

The Regwall is displayed via Akamai:

1. anonymous user (based on the configuration located in /content/telegraph/application/paywall


/registrationwall/anonymous )

The regwall is shown depending on the response from Evolok, the available setting on the AEM side are...

AEM Sent to Evolok as example

hscomscore.businessSegment channel "business"

tmg.channelPageName sectionId "rugby-union"

tag keyword "new-year-new-you"

Usage example;

Interactions The whole interaction in defined in the ESI* language and evaluated only on Akamai layer.
Interacted services:

global switch - external place where during ESI evaluating code on akamai, code is checking if there is whole feature enabled or
disabled (example http://meter-globalswitch.awspreprod.telegraph.co.uk/meter-dev2.html)
evelok (meter) - external service (example path: http://evolok-uat.telegraph.co.uk/evolok-ad-web/api/3.0/authorize/esi) where
AEM is sending couple of information about user and current page, like if article is NOT premium, and expect in response if user
should see full page content or the hard regwall

Current possible responses from evelok (meter):

1. ALLOW_ACCESS -> no regwall


2. REQUIRE_LOGIN -> anonymous regwall

Restrictions The Regwall/Meter script is adding only on article2.

Screenshot AEM Regwall component; set button text and login URL etc... (note there is a link to the config page at the top of this page)
(s)

275
Regwall setting page; set page specific content (it can be useful to switch to classic editor view for text formatting)
To create a new row, click on the table you want to administer, you get a context menu, choose full screen icon.
Put your cursor into a table data and click "Duplicate row" amend the new row as necessary. When your done, exit full screen mode
and save. (remember to publish both the setting page the above page too)

Example Meter OSGI configuration (uses the same as Paywall)

Geo Not supported


location

Code In AEM content:


Location /content/telegraph/application/paywall/*

/content/telegraph/products/registration-wall*

In OSGI (/system/console/configMgr):
TMG - METER Integration

In CRX repository:

/apps/telegraph/core/commons/snippets/meterCheck
/apps/telegraph/core/commons/components/paywall/registrationWallList
/apps/telegraph/core/config/renderers/regwallRenderer
/apps/telegraph/themes/commercial/templates/registrationWallTemplate

(see this Pull Request for full list of assets added to AEM https://bitbucket.aws.telegraph.co.uk/projects/CHEET/repos/telegraph-
component/pull-requests/4262/overview)

In Java:

MeterConfigurationService.java
MeterStatusProvider.java
MeterStatus.java

JIRA

276
First original ticket is here:
https://jira.aws.telegraph.co.uk/browse/SUB-8057

Other Editing the settings page. Classic UI and Touch UI offer different functionallities, I recommend using Touch UI for adding and
removeing regwalls and makeing minor changes to content. open the settings page in Touch UI (editor.html), wait for the page to load
(can take a while), click on the table > click on edit > click on full screen.

277
Header
Component

Nickname(s) Header

Synopsis The page "Header" contains navigation elements, please see Navigation for more information.

Interactions

Restrictions

Screenshot(s)

Location
telegraph/core/clientlibs/tmgchannels/_base/sass/snippets/snippet.header.scss

telegraph/core/commons/snippets/defaultHeader

JIRA

Other

Component Properties
Name Type Description

278
Headline
Component

Headline
Nickname
(s)

Main component used to add a headline. It is included by default in many page templates including the Hub template, the Video Hub Template and the Article Template 2.
Description
The Headline configuration allows for the head line text to be added and Styles tab if the styling to be set.

Interactions

This component is a mandatory field, which is pre-populated. The choice of adding it is not given for adding it to a page.
Restrictions

Screenshot
(s)

Headline displays - Her Story, review

/apps/telegraph/core/commons/components/headline
Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Headline Sep 16, Nov 25, Unassigned Jo Harris [X] TO Unresolved
6703 character 2016 2016 REFINE
count
AEM- Get data for May 19, Jul 19, 2016 Michal Gavin Kirk CLOSED Done
5738 Headline 2016 Boruczkowski [X]
length [X]
analysis
AEM- Not possible Sep 11, Sep 28, Unassigned Kornelia CLOSED Done
2408 to change 2015 2015 Miklas [X]
headline for
only special
characters
contain.
AEM- Title is not Mar 30, Mar 30, 2016 Unassigned Andrzej CLOSED Done
5104 overwriting 2016 Dolinski [X]
default
headline in
hero block tile
AEM- Sponsorship Jan 12, Mar 15, 2016 Unassigned Gavin Kirk RELEASED Unresolved
3943 logo adjacent 2016 [X]
to Headline
AEM- Button Jul 15, 2015 Jul 29, 2015 Unassigned None RELEASED Unresolved
1585 affordance -
Headline
AEM- Search for Feb 13, Sep 28, Jo Harris [X] None RELEASED Unresolved
189 stories using 2015 2015
Headline
AEM- Item type | Mar 16, Apr 21, 2016 Patrick Mathias RELEASED Unresolved
4911 Headline font 2016 Clancey [X] Douchet
should be
Austin News
Deck Medium

279
AEM- Adjust Oct 08, Feb 04, 2016 Anna Anna Dezor CLOSED Done
2809 headline 2015 Karkkainen [X]
padding on [X]
section pages
AEM- Padding Mar 18, Mar 24, 2016 Unassigned Gavin Kirk RELEASED Unresolved
4956 between 2016 [X]
Sponsor Slot
and Headline
AEM- Page Title is May 21, Aug 19, Jo Harris [X] None CLOSED Done
733 always the 2015 2015
same as the
Headline
AEM- Create new Jun 02, Jul 22, 2015 Lukasz None RELEASED Unresolved
923 styles for 2015 Graziowski
headline [X]
component
AEM- Adjust Sep 10, Oct 07, 2015 Anna Dezor Mathias CLOSED Done
2345 Headline 2015 [X] Douchet
component on
section pages
AEM- Remove Oct 23, Dec 03, Tomasz Gavin Kirk RELEASED Unresolved
3026 Headline from 2015 2015 Niedzwiedz [X]
Topics [X]
template
AEM- Headline with Sep 01, Oct 27, 2017 sdu aemdev Dan Silver CLOSED Done
7672 full stop 2017
merges words
AEM- Canceling a Mar 16, Apr 05, 2016 Unassigned Jo Harris [X] RELEASED Unresolved
4919 schedule and 2016
changing the
headline does
not update the
URL
AEM- Save button Nov 04, Feb 05, 2016 Unassigned Kornelia RELEASED Unresolved
3180 enabled 2015 Miklas [X]
despite no
headline is
displayed.
AEM- Full width Aug 20, Nov 17, Patrick None RELEASED Unresolved
2074 headline for 2015 2015 Clancey [X]
Live blog
page
AEM- Finder not Sep 16, Oct 05, 2015 Unassigned Jo Harris [X] RELEASED Unresolved
2485 handling 2015
stories with
long headlines
correctly.
AEM- Too big gap May 06, May 25, Unassigned Anna Dezor RELEASED Unresolved
5618 between 2016 2016 [X]
headline and
hero image

Showing 20 out of 496 issues

Other

280
Styling selections:

None

Version 1

Version 2

Author/Topic Page Headline

Component Properties
Name Type Description

281
HTML Embed
Component

Html Embed (writing document in progress)


Nickname
(s)

HTML Embed is used to add html content or javascript includes in a page. For instance, adding a youtube video to a page.
Description

Interactions

Restrictions

Screenshot
(s)

html/cheetah/html/components/htmlEmbed.html
Location
Source:

cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/htmlEmbed

Adding content, javascript or CSS to a page using the HTML Embed


JIRA
How to use Authoring tools

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Headings in Dec 18, Feb 05, 2016 Unassigned Kornelia RELEASED Unresolved
3840 html embeds 2015 Miklas [X]
are not styled
properly.
AEM- Additional Feb 02, Apr 20, 2017 Tomasz Mark Cyrson RELEASED Unresolved
7291 HTML 2017 Lipowicz [X]
validation for
Embed
(remove Tab
character)
AEM- Generic Mar 27, Jul 16, 2015 Lukasz None RELEASED Unresolved
194 HTML embed 2015 Blaszynski [X]
AEM- Lazy load Apr 29, Jul 22, 2016 Andrzej None RELEASED Unresolved
5565 HTML 2016 Dolinski [X]
embeds
AEM- HTML Embed Apr 16, Aug 13, Unassigned None RELEASED Unresolved
171 Component 2015 2015
AEM- HTML embed May 05, Aug 04, Unassigned None CLOSED Done
475 component - 2015 2015
list of HTML
snippets
AEM- Copy and Jul 06, 2015 Jul 09, 2015 Unassigned None READY Done
1478 Paste an html FOR
RELEASE
embed
truncates the
html in the
copy
AEM- HTML embed May 31, Jul 15, 2016 Andrzej Andrzej RELEASED Unresolved
5861 is not 2016 Dolinski [X] Dolinski [X]
rendered on
the page
when lazy
load is
enabled
AEM- Instructions Feb 25, Mar 16, 2016 Unassigned Gavin Kirk CLOSED Done
4555 for how to use 2016 [X]

282
HTML Embed
to inject CSS
& javascript
AEM- Validate html Dec 09, Feb 05, 2016 Unassigned None RELEASED Unresolved
3719 embed to 2015
wrap text
AEM- Add html Oct 21, Dec 14, Unassigned None RELEASED Unresolved
2983 embed to live 2015 2015
article post
AEM- HTML Feb 19, Jun 10, 2016 Unassigned Lucian TO Unresolved
4487 Embeds can 2016 Craciun REFINE
redirect users
to a different
page
AEM- HTML embed Jan 12, Feb 15, 2017 Anna Dezor None RELEASED Unresolved
7242 can't be edited 2017 [X]
AEM- Lazy load Jan 09, Feb 17, 2017 Unassigned Gareth Clubb TO Unresolved
7225 HTML 2017 [X] REFINE
embeds
AEM- HTML Embed Jun 16, May 17, Unassigned Gavin Kirk CLOSED Done
1210 style 2015 2016 [X]
functionality
AEM- Undenting of Apr 13, Apr 21, 2016 Unassigned Gavin Kirk RELEASED Unresolved
5308 HTML Embed 2016 [X]
AEM- Tighten the Jul 04, 2016 Jun 18, 2018 Unassigned Gavin Kirk CLOSED Done
6159 padding [X]
around the
HTML Embed
when floated
left
AEM- Transfer the Apr 23, Aug 25, Unassigned None TO Unresolved
361 HTML embed 2015 2015 REFINE
capability
(currently on
eScenic) over
to AEM
AEM- Text from html Dec 01, Feb 05, 2016 Unassigned Kornelia RELEASED Unresolved
3566 embed is 2015 Miklas [X]
going out
embed.
AEM- Cannot Jul 06, 2015 Jul 09, 2015 Unassigned None READY Done
1477 include FOR
RELEASE
duplicate html
in the embeds

Showing 20 out of 190 issues

Other

Component Properties
Name Type Description

283
Hub Template
Component

Hub Template
Nickname
(s)

Template for a Channel or Section Page at page creation using Hub Renderer (inherits from PageRenderer) to render pages.
Description

Interactions

Restrictions

Screenshot
(s)

/apps/telegraph/core/commons/renderers/hubRenderer (code in telegraph-component)


Location /apps/telegraph/core/commons/templates/hubTemplate (code in telegraph component)

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Hub template May 19, Jul 17, 2015 Tomasz Tomasz CLOSED Done
659 not available 2015 Niedzwiedz Niedzwiedz
at the root [X] [X]
level
AEM- NonIAB is Jun 12, Oct 02, 2015 Unassigned Patrycja RELEASED Unresolved
1123 visible also on 2015 Kurkowiak
another [X]
templates
than Hub and
Article2
template
AEM- Create new Apr 30, Jun 22, 2015 Unassigned Gavin Kirk RELEASED Unresolved
452 Hub template 2015 [X]
in core
AEM- Div needed Oct 09, Oct 20, 2015 Unassigned Anna RELEASED Unresolved
2838 around hub 2015 Karkkainen
template [X]
advert area
AEM- Video hub Apr 11, Apr 21, 2016 Unassigned Mathias RELEASED Unresolved
5264 template | 2016 Douchet
Make slot 4
optional
AEM- Video - Add Mar 07, Apr 12, 2016 Michael Mathias RELEASED Unresolved
4716 V6 Sponsored 2016 Goszczynski Douchet
List to the
Video Hub
Template
AEM- Wrong name May 12, Jun 22, 2015 Unassigned Patrycja RELEASED Unresolved
584 for Hub 2015 Kurkowiak
template [X]
AEM- Display ads Apr 23, May 13, Unassigned None CLOSED Done
364 on Hub 2015 2016
template
AEM- New articles Sep 06, Sep 19, Unassigned Marek CLOSED Done
6596 can be 2016 2016 Krokosinski
created under [X]
channels
which are not
Hub
Templates
AEM- Add Snippet Nov 25, Jan 29, 2016 Unassigned Gavin Kirk RELEASED Unresolved
3443 Reference to 2015 [X]
Hub & Topics
templates
below local
navigation
AEM- Create Video Jan 13, Feb 10, 2016 Anna Robert RELEASED Unresolved
3981 Hub Page 2016 Karkkainen Toshman
Template [X]
AEM- Video Finder Feb 24, Aug 08, Andrzej Robert READY Unresolved
4539 Alternative - 2016 2016 Dolinski [X] Toshman FOR DEV

284
Use the
Segment
Container
/Snippet for
the Video Hub
Template and
Video Play
Pages
AEM- Video Hub Mar 09, Apr 12, 2016 Anna Anna RELEASED Unresolved
4769 template not 2016 Karkkainen Karkkainen
available [X] [X]
under /content
/telegraph
AEM- Should the Jul 15, 2015 Oct 02, 2015 Unassigned Anna Dezor RELEASED Unresolved
1597 Business [X]
Segments be
available for
the HUB
template?
AEM- Ability to Jun 29, Aug 25, Unassigned None CLOSED Done
1376 move fixed 2015 2015
components
in channel
hub template
AEM- Front end: Jun 03, Apr 25, 2016 Patrycja None RELEASED Unresolved
954 Sticky MPU's 2015 Kurkowiak [X]
on hub
template
AEM- Video hub Apr 13, Apr 21, 2016 Anna Mathias RELEASED Unresolved
5305 template 2016 Karkkainen Douchet
should get [X]
pagetype=inde
x
AEM- Video hub Mar 17, May 05, Anna Dezor Mathias RELEASED Unresolved
4935 template | List 2016 2016 [X] Douchet
horizontal line
is wrong
AEM- Cluster page Sep 03, Nov 04, Unassigned None CLOSED Done
2250 template - 2015 2015
switch Culture
and Lifestyle
home pages
from Hub
template to
Cluster
template
AEM- Any page Jul 07, 2015 Jul 16, 2015 Unassigned None CLOSED Done
1487 (template)
under hub,
when on hub
ads are
disabled, are
also disabled

Showing 20 out of 290 issues

Other

Component Properties
Name Type Description

285
Image Report
Component

Nickname Image Report


(s)

Synopsis The Picture Desk team needs to get an auto-generated usage report compiled from the image credit fields in AEM.

The Picture Desk use this report to assist with working out how much money to pay image contributors.

Description What is extracted:

Extract to contain data of images on published pages (Lead Asset, Article Body Image & Gallery Slide only)
Extract should not contain any records for images that are not used on a published pages
Go back to to pages published on 1 March 2016 00:00 to 30 June 2016 23:59
Do not include video data

Data extract spec:

Item Description Data from Data definition

Publication Publication date of the page that the image is used on Page publication date (not image publication date) YYYY-MM-DD HH:MM
date (24H)

Description As entered by the journalist in Authoring or Image Alt in Text


component Lead Asset - Image Alt
Article Body Image - Image Alt
Gallery Slide - Alt-Text

Agency Name of agency Source (in AEM


Agency (in Authoring) component)
Source (in AEM)

Artist Photographer name Text


Artist (in Authoring)
Credit (in AEM component)

Name (DAM) File name of image Name of image from DAM Text

Title (DAM) Original title of image from provider (often contains Reference Title from DAM Text
ID of provider)

Description Original description of image from provider Description of image from DAM Text
(DAM)

Image Alt Original alt text of image from provider Image Alt of image from DAM Text
(DAM)

Caption Original caption of image from provider Caption of image from DAM Text
(DAM)

Creator (DAM) Original creator of image from provider Creator of image from DAM Text

Contributor Original contributor of image from provider Contributor of image from DAM Text
(DAM)

Copyright Original copyright of image from provider Copyright of image from DAM Text
(DAM)

Web link URL of the page the the image was is used on Full URL
Galleries - slide URL (including the first slide
full slide path)
All other pages - page URL

Export format:

CSV
Separated out into one file per month - from 1st to last of the month

This feature should ONLY BE USED IN PRE-PROD ENVIRONMENTS. The implementation is an MVP not optimised with
performance in mind, implemented very quickly to avoid extra charges for delayed payments to external agencies.

Usage
Call the ImageReportServlet (path: /bin/telegraph/reports/images) with query parameters startDate and endDate specifying the
date range (the date format used is yyyyMMdd).

Example: /bin/telegraph/reports/images?startDate=20160101&endDate=20160515

286
The servlet will not generate more than one report at a time. This is achieved by a very naive implementation of the ImageReportSe
rvlet, namely, the processRequest method is synchronized

Interactions

Restrictions DO NOT USE IN PRODUCTION

Screenshot
(s)

Location Classes in the uk.co.telegraph.core.commons.reports.image package

The entry point is the ImageReportServlet

uk.co.telegraph.core.foundation.utils.DateFormatter#IMAGE_REPORT - query parameter date format

JIRA AEM-5847 - Generate a report to assist contributor payments for images RELEASED

Other

Component Properties
N/A

287
Lead Asset
Component

Lead Asset, Lead Image


Nickname
(s)

Displays a prominent image serving as the main illustration of an article.


Synopsis

Displays a prominent image serving as the main illustration of an article and a piece of copyright information. Each article needs to have a lead asset.
Description
Lead images are also displayed in List Items by the List component. They are also used to generate some of meta tags (the link to the image is used in the og:image tag that's consumed by social
media cards for example).

For every image, the Lead Asset component will render a data attribute containing information on all available renditions of the image in the source of the page.

<img class="responsive-image lead-asset__image" width="316" height="197" alt="David Attenborough in


Planet Earth II" data-frz-ratio="1.60"
src="/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
small_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg"
data-frz-src-array="[
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
xsmall_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':158,
'height':98,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.03'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
xlarge_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':1265,
'height':790,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.45'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
medium_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':474,
'height':296,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.45'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
thumbnail_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':138,
'height':86,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.32'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
xxlarge_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':1483,
'height':926,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.44'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
small_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':316,

288
'height':197,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.34'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
large_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':711,
'height':444,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.45'
}
]"
/>

The data attribute will be ingested by the JavaScript responsible for lazily loading images ( etc/designs/telegraph/core/clientlibs/core/js/libs/lazyload-0.8.5-modified.js )

Renditions and Cropping


Every src property in the document will point at a rendition of the image of a specific size. The file names will also have an encrypted crop parameter string appended to the file name, similar to this
one: trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI

The parameters will be decrypted and interpreted by the uk.co.telegraph.core.foundation.image.ImageRedirectServlet (also see NamedTransformImageServlet ) in telegraph-
component. The Servlet will translate the parameters to a different format and redirect the call to hit another servlet that will actually reads the images from the repository - NamedTransformImageSer
vlet in the forked acs-aem-commons

The generation of renditions in different sizes is achieved by a slightly customised OOTB workflow. See src/main/cq/jcr_root/etc/workflow/models/dam/update_asset/_jcr_content
/model.xml for the exact definition of the workflow (you can also view it at /etc/workflow/models/dam/update_asset.html on your Author instance once telegraph-component has been
deployed.).

It's possible for a video to be placed in the Lead Asset's position. The Video component allows the user to select an image to be displayed when the video is not playing. The same image
is used in list items.

The ACS AEM Commons fork, specifically https://bitbucket.aws.telegraph.co.uk/projects/CHEET/repos/acs-aem-commons/browse/bundle/src/main/java/com/adobe/acs/commons/images/impl


Interactions /NamedTransformImageServlet.java

Restrictions

Screenshot
(s)

289
telegraph/core/commons/components/leadAsset
Location

uk.co.telegraph.core.foundation.leadasset.LeadAsset - a widely used model representing images in most of the components we have, including List, Gallery, Article Body
Image and others.

JIRA

T Key Summary Assignee Reporter P Status Resolution Created Updated Due

PRB- Live Adrian Vit [X] Nicola DONE Done Jun 06, Jun 07, 2019
1550 Streaming - Ayonoadu 2019
Lead Asset
added to
microservice
TT-849 Lead asset - Unassigned None RELEASED Unresolved Nov 23, Dec 09,
top margin 2015 2015
AEM- Format Lead Yaseed None CLOSED Done Feb 17, Dec 02,
242 Asset Caption Chaumoo [X] 2015 2015
TRAN- Lead Asset Simon Ward Gavin Kirk BACKLOG Unresolved Nov 21, Dec 16,
84 [X] [X] 2016 2016
PRB- Images not Adam Gaudry Adam DONE Done Nov 08, Aug 30,
643 appearing on Gaudry 2016 2018
the homepage
due to lazy
loading java
code
AEM- View Unassigned None CLOSED Done Feb 24, May 14,
161 metadata for 2015 2015
Lead Asset
image
AEM- Q4 Authoring Unassigned None TO Unresolved Sep 22, Sep 28,
2595 Lead Asset in REFINE 2015 2015
Lists
NOS- AEM Content Unassigned None DONE Cannot Jan 29, Mar 18, 2016
2808 issues - Live Reproduce 2016
Article - lead
asset
TRAN- BE - Lead Tomasz Omar Baig IN Unresolved Nov 21, Dec 14,
57 Asset Niedzwiedz [X] REVIEW 2016 2016
Renditions [X]
CCORE- [UI] - Styling Simon Ward Simon Ward DONE Fixed Feb 26, Mar 20, 2014
327 and structural [X] [X] 2014
changes for
Lead asset
ratings
AEM- Display Unassigned None TO Unresolved Sep 21, Nov 08,
2535 Ooyala video REFINE 2015 2016
information in
Lead Asset
AEM- Increase the Unassigned Gavin Kirk CLOSED Done Sep 28, Nov 02,
2679 size of caption [X] 2015 2015
in Lead Asset
[DUPE - SEE
RELATED
TICKETS]

290
PLTX- NAM - V2 Cornel Adrian Vit [X] Done Dec 19, Feb 28, 2019
DONE
602 /article Isbiceanu 2018
endpoint for
youtube lead
asset
NF-1383 Contract for Rasheed Richard DONE Unresolved Nov 06, Nov 28,
Lead Asset Ilesanmi Spence 2019 2019
variations
AEM- Remove Lead Unassigned None CLOSED Unresolved Feb 16, May 14,
158 Asset Image 2015 2015
AEM- Video as Lead Unassigned Gavin Kirk RELEASED Unresolved May 13, Jul 15, 2015
608 Asset [X] 2015
TT-856 Lead asset - Samantha None RELEASED Unresolved Nov 23, Dec 09,
additional Edwards [X] 2015 2015
bottommargin
SD- AEM Lead Ray Karim [X] Oliver CLOSED Done Apr 25, May 04,
118024 Asset Edgington 2018 2018
Problem
TT-925 To big space Unassigned None CLOSED Done Dec 03, Feb 11, 2016
after lead 2015
image asset
on mobile
screens
RFC- Import lead Ritesh Ritesh CLOSED Done Dec 15, Jan 06, 2016 Dec 16,
4769 assets for Bhavsar [X] Bhavsar [X] 2015 2015
AEM Travel

Showing 20 out of 1147 issues

Other

Component Properties
Tab Name Type Description

Lead Image Image The image to be displayed as the lead. Drag and drop from the Content Finder.

Lead Image Image Alt Text The text to be displayed in the image's alt attribute.
Configuration

Caption Text A caption to be displayed underneath the image. This value will be pulled from the DAM if this field is
left blank.

Disable Image Caption Checkb Check this to hide the caption without removing its value from the repository (useful for temporarily
ox hiding the text)

Override DAM Checkb Check this to override the Credit and Source information from the DAM with explicit values.
information ox

Credit Text Credit text to be displayed (visible if the Override DAM information checkbox is ticked)

Source Text Image Source to be displayed (visible if the Override DAM information checkbox is ticked)

Component

Lead Asset, Lead Image


Nickname
(s)

Displays a prominent image serving as the main illustration of an article.


Synopsis

Displays a prominent image serving as the main illustration of an article and a piece of copyright information. Each article needs to have a lead asset.
Description
Lead images are also displayed in List Items by the List component. They are also used to generate some of meta tags (the link to the image is used in the og:image tag that's consumed by social
media cards for example).

For every image, the Lead Asset component will render a data attribute containing information on all available renditions of the image in the source of the page.

<img class="responsive-image lead-asset__image" width="316" height="197" alt="David Attenborough in


Planet Earth II" data-frz-ratio="1.60"
src="/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
small_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg"
data-frz-src-array="[
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-

291
xsmall_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':158,
'height':98,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.03'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
xlarge_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':1265,
'height':790,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.45'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
medium_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':474,
'height':296,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.45'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
thumbnail_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':138,
'height':86,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.32'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
xxlarge_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':1483,
'height':926,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.44'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
small_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':316,
'height':197,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.34'
},
{
'src':'/content/dam/tv/2016/11/04/112157217-Planet-Earth-CULTURE-
large_trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI.jpg',
'width':711,
'height':444,

'imageCropTransformSuffix':'trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI',
'percentageImageRatio':'62.45'
}
]"
/>

The data attribute will be ingested by the JavaScript responsible for lazily loading images ( etc/designs/telegraph/core/clientlibs/core/js/libs/lazyload-0.8.5-modified.js )

Every src property in the document will point at a rendition of the image of a specific size. The file names will also have an encrypted crop parameter string appended to the file name, similar to this
one: {{

trans_NvBQzQNjv4BqVrUpGShtiMSOrgRE1UXhxwvm66VPBZpv7lQVy_JwGVI

292
It's possible for a video to be placed in the Lead Asset's position. The Video component allows the user to select an image to be displayed when the video is not playing. The same image
is used in list items.

Interactions

Restrictions

Screenshot
(s)

telegraph/core/commons/components/leadAsset
Location

uk.co.telegraph.core.foundation.leadasset.LeadAsset - a widely used model representing images in most of the components we have, including List, Gallery, Article Body
Image and others.

JIRA

T Key Summary Assignee Reporter P Status Resolution Created Updated Due

PRB- Live Adrian Vit [X] Nicola DONE Done Jun 06, Jun 07, 2019
1550 Streaming - Ayonoadu 2019
Lead Asset
added to
microservice
TT-849 Lead asset - Unassigned None RELEASED Unresolved Nov 23, Dec 09,
top margin 2015 2015
AEM- Format Lead Yaseed None CLOSED Done Feb 17, Dec 02,
242 Asset Caption Chaumoo [X] 2015 2015
TRAN- Lead Asset Simon Ward Gavin Kirk BACKLOG Unresolved Nov 21, Dec 16,
84 [X] [X] 2016 2016

293
PRB- Images not Adam Gaudry Adam Done Nov 08, Aug 30,
DONE
643 appearing on Gaudry 2016 2018
the homepage
due to lazy
loading java
code
AEM- View Unassigned None CLOSED Done Feb 24, May 14,
161 metadata for 2015 2015
Lead Asset
image
AEM- Q4 Authoring Unassigned None TO Unresolved Sep 22, Sep 28,
2595 Lead Asset in REFINE 2015 2015
Lists
NOS- AEM Content Unassigned None DONE Cannot Jan 29, Mar 18, 2016
2808 issues - Live Reproduce 2016
Article - lead
asset
TRAN- BE - Lead Tomasz Omar Baig IN Unresolved Nov 21, Dec 14,
57 Asset Niedzwiedz [X] REVIEW 2016 2016
Renditions [X]
CCORE- [UI] - Styling Simon Ward Simon Ward DONE Fixed Feb 26, Mar 20, 2014
327 and structural [X] [X] 2014
changes for
Lead asset
ratings
AEM- Display Unassigned None TO Unresolved Sep 21, Nov 08,
2535 Ooyala video REFINE 2015 2016
information in
Lead Asset
AEM- Increase the Unassigned Gavin Kirk CLOSED Done Sep 28, Nov 02,
2679 size of caption [X] 2015 2015
in Lead Asset
[DUPE - SEE
RELATED
TICKETS]
PLTX- NAM - V2 Cornel Adrian Vit [X] DONE Done Dec 19, Feb 28, 2019
602 /article Isbiceanu 2018
endpoint for
youtube lead
asset
NF-1383 Contract for Rasheed Richard DONE Unresolved Nov 06, Nov 28,
Lead Asset Ilesanmi Spence 2019 2019
variations
AEM- Remove Lead Unassigned None CLOSED Unresolved Feb 16, May 14,
158 Asset Image 2015 2015
AEM- Video as Lead Unassigned Gavin Kirk RELEASED Unresolved May 13, Jul 15, 2015
608 Asset [X] 2015
TT-856 Lead asset - Samantha None RELEASED Unresolved Nov 23, Dec 09,
additional Edwards [X] 2015 2015
bottommargin
SD- AEM Lead Ray Karim [X] Oliver CLOSED Done Apr 25, May 04,
118024 Asset Edgington 2018 2018
Problem
TT-925 To big space Unassigned None CLOSED Done Dec 03, Feb 11, 2016
after lead 2015
image asset
on mobile
screens
RFC- Import lead Ritesh Ritesh CLOSED Done Dec 15, Jan 06, 2016 Dec 16,
4769 assets for Bhavsar [X] Bhavsar [X] 2015 2015
AEM Travel

Showing 20 out of 1147 issues

Other

Component Properties
Tab Name Type Description

Lead Image Image The image to be displayed as the lead. Drag and drop from the Content Finder.

Lead Image Image Alt Text

294
Configuration The text to be displayed in the image's alt attribute.

Caption Text A caption to be displayed underneath the image. This value will be pulled from the DAM if this field is
left blank.

Disable Image Caption Checkb Check this to hide the caption without removing its value from the repository (useful for temporarily
ox hiding the text)

Override DAM Checkb Check this to override the Credit and Source information from the DAM with explicit values.
information ox

Credit Text Credit text to be displayed (visible if the Override DAM information checkbox is ticked)

Source Text Image Source to be displayed (visible if the Override DAM information checkbox is ticked)

295
List (The)
Component

List, List of Entities (referred to as such by designers), Dynamic List (phrase encountered in the Java code distinguishing the List component from the Curated List components)
Nickname
(s)

The main component used to link between pages on the Telegraph website. It uses Cq Search to find articles based on a set of configurable criteria: Supports searches based on page type, tags. Supports pagination of re
Description
The List component appears on the majority of pages with the exception of the Gallery and Bare templates. It's the key component of Hub pages.

It comes in over 20 style variants. See the List Versions page (mind that it's slightly out of date), also refer to the Style Guide but check with UX to make sure it's actually up to date.

Every List displays a number of List Items. The List component is only responsible for finding the pages to display. The way every List Item is rendered as well as the data it contains is driven by the renderer of the page b

For example, when the List component displays links to pages based on the Article 2 template, it's the articleRenderer2 and not the List component itself that's responsible for generating the List Item view.

For that to happen, the pages supported by the List component must respond to the listItem selector. This is usually achieved by Sling URL to script resolution.

Interactions The search of list items to display is based on Cq Search, see uk.co.telegraph.core.search.api.SearchEngine and friends for an entry point in code analysis,
Server Side Includes are used when the Dispatcher is involved in processing the request (see SsiResolver and how it's used in the HTL scripts behind the List)

Restrictions

Screenshot
(s)

The component itself: /apps/telegraph/core/commons/components/list (code in telegraph-component)


Location
The core Java classes for this component can be found in the uk.co.telegraph.core.list package in telegraph-component. Mind that it contains code used by the Curated List and Curated List 2 as well. Code
component is in uk.co.telegraph.core.list.dynamic

Examples of List Item scripts for different renderers:

/apps/telegraph/core/commons/renderers/articleRenderer2/listItem.html
/apps/telegraph/core/commons/renderers/galleryRenderer/listItem.html
/apps/telegraph/core/commons/renderers/authorRenderer2/listItem.html

In order for the List component to use SSI, a number of selectors need to be whitelisted on the Dispatcher, the configuration for this can be found tmg-aem in:

publish-filter.inc.erb
travel-filter.inc.erb (for the Travel publishers)

Whatever mentions lists in the AEM Jira, with the status Released. Some of these will not be related (like List of Tags or Curated List) but this is a good starting point to get an overview.
JIRA

T Key Summary Assignee Reporter P Status Resolution Created

AEM- Implement new List architecture for Unassigned Gavin Kirk [X] RELEASED Unresolved Sep 28,
2666 existing Lists 2015
AEM- White space inside list structure Unassigned Jedrzej RELEASED Unresolved May 18,
648 Osinski [X] 2015
AEM- Provide Default List Renderers for All Patrycja Tomasz RELEASED Unresolved Apr 15,
125 Pages Kurkowiak [X] Niedzwiedz [X] 2015
AEM- Curated List Tiles do not display on Unassigned Tomasz RELEASED Unresolved Apr 24,
385 Publish Niedzwiedz [X] 2015
AEM- Standardise Publication Date treatment in Anna Dezor [X] Melinda RELEASED Unresolved Mar 19,
465 Articles & Lists Rogers [X] 2015
AEM- Article2 within a Channel onward journey Unassigned Gavin Kirk [X] RELEASED Unresolved Aug 12,
1950 list 2015
AEM- Wrong colour of Gallery icons in List Unassigned Tomasz RELEASED Unresolved Jun 04,
985 version-15 Niedzwiedz [X] 2015
AEM- New articles not immediately appearing Unassigned None RELEASED Unresolved Oct 16,
2922 in lists 2015
AEM- "Grouping" content - for manually curated Unassigned None RELEASED Unresolved Sep 22,
2582 list 2015
AEM- Enable Most Viewed List component to Unassigned Gavin Kirk [X] RELEASED Unresolved Sep 02,

296
6588 gather data from all channels & by page 2016
type
AEM- Image in heading of Desk List version Unassigned Gavin Kirk [X] RELEASED Unresolved Nov 24,
3436 2015
AEM- Video Portal - List version 21 (New List) - Eoin Tunstead Luis RELEASED Unresolved Dec 16,
3796 aka Hero: Must Watch (Curated List) Khamashta 2015
AEM- Sponsored List Items Unassigned None RELEASED Unresolved Nov 27,
3498 2015
AEM- Styling for List of Galleries Lukasz None RELEASED Unresolved May 08,
525 Graziowski [X] 2015
AEM- List heading - overlapping letters Unassigned None RELEASED Unresolved Jun 15,
1180 2015
AEM-10 Spike to research existing list creation Tomasz Gavin Kirk [X] RELEASED Unresolved Mar 31,
Niedzwiedz [X] 2015
AEM- Automatically Populate a List of Galleries Unassigned Tomasz RELEASED Unresolved Apr 21,
322 - Functionality Niedzwiedz [X] 2015
AEM- List of Tags Unassigned Gavin Kirk [X] RELEASED Unresolved May 12,
586 2015
AEM- List Logic Unassigned None RELEASED Unresolved Jun 12,
1151 2015
AEM- Video - List component - Video Search Piotr Rzasa [X] Luis RELEASED Unresolved Dec 16,
3787 Criteria Khamashta 2015

Showing 20 out of 748 issues

Other
Passing any information from the List component configuration to any of the List Items can only be done by means of a Sling selector. It's very easy to further complicate the code very quickly by adding suppo
selectors. It should only be done if absolutely necessary and impossible to avoid.

the selectors need to be passed to the data-sly-resource as well as Server Side Includes, adding more selectors makes this code more complex
for every combination of selectors, there is a file in the Dispatcher cache, introducing new selectors will result in the need to cache many more files, which, given how commonly used the List compoent
disk space on the server to fill up more quickly

For example, the Headline position is passed this way.

Most of the front-end code for List, Curated List and Curated List 2 is shared. They're all styled as the List of Entities, see the Sass and JS code in telegraph-component

Be careful about requirements to change one of these components and not the others.

The List component uses some custom reference providers to ensure that changes to articles are seen in lists across the site.

Basically, when an article changes in a way that may affect how it looks in lists or which lists can display it, the pages containing those lists are flushed from the cache. This mechanism only works for Lists
empty set of tags to filter the results. Lists with no tags will not be updated automatically.

The code can be found in uk.co.telegraph.core.commons.listreferences in telegraph-component

The following diagram depicts the List replication flow:

297
Component Properties
Name Type Description

Display Radio Drives the interpretation of the Tags field as a union or an intersection of the tags entered.
pages
tagged with

Tags Tag Select one or more tags based on which to search for articles. Depending on the value of the Display pages tagged with
field, the search will be for articles tagged with all tags mentioned here or with at least one of them.

Exclude Radio Similar to Display pages tagged with, determines how pages tagged with the tags specified in Excluded tags should be
pages excluded from the search (based on the presence of a specific set of tags or the presence of any tags from the set).
tagged with

Excluded Tag Pages tagged with these tags will be excluded from the search.
Tags

This is used by Editorial for hiding content of channels that are not yet live. All of the live content usually
excludes the Blacklist tag, which is applied to pages that are not supposed to go live yet. This allows those
pages to be built in production.

See Blacklisting for more information.

Type Dropdo The type setting maps to sets of Templates to include in the search. See uk.co.telegraph.core.search.impl.
wn CqSearchEngine to learn what templates exactly are represented by these values (look for *QueryBuilder classes)

The set of available valuse is:

298
Article
Entity
Author
Comparison
Gallery
Video Play Page
Bare
Premium
Offer
Any

Not all entries in this list are supposed to be used any more. The ones highlighted in Red should be removed. They were
used on the old Telegraph Cars, Film and Best pages.

Layout Dropdo Default or Simple


wn
This is probably unused at this point. To be verified. //TODO: check this

Headline Dropdo Body or First


position wn
The list headline can appear above the image as the first element in a list rendition or below the image, within the body of
the list item. This was implemented in the pre-flexbox era when it was impossible to achieve styling like this with CSS
only. The setting affects the markup.

The information on the position of the headline is passed from the List component to the listItem script in a renderer by
means of a Sling selector. Regardless of whether the item is included internally, via a data-sly-resource or by means
of a Server Side Include.

Display Check Check this to maek an ad slot appear inside the list.
advert box

Rules Dropdo Ordering of the searched list elements. Most recent or Reverse chronological order, self-explanatory
wn

Start Number The offset of first element (for pagination)


element
offset

Max number Number How many of the search results should be displayed. Up to 20 elements will be rendered if this is left blank. If the list is
of items paginated, this setting is ignored and all items will be retrieved (they can be displayed using the Load more button that
displayed appears below the list)

Paginate Check Check this if the list is supposed to paginate.


box

If this is set, the number of items returned by the queries is not limited. This causes performance problems.

Slider mode Radio Lists can have additional styling applied to enable a slider. This is used on some pages to obtain scrollable content in lists.
(Style version specific!)

No slide - do not display a slider


Slider on - display a slider regardless of the viewport
Mobile only - display only on mobile devices (based on screen width)

No arrows Check Hides the arrows visible on the sides of the slider
box

Time labels Check Turns on time labels (Style version specific! Version 17 - Latest News)
on box

Time breaks Check Enables time breaks (Style version specific! Version 17 - Latest News)
box

299
List of Tags
Component

Nickname List of Tags


(s)

Description The List of Tags component enables the discovery of Topic pages and other pages potentially associated with a given tag (such
as some of the sections in the Fashion channel)

It can display page-level tags. Addutional tags can also be added manually. A condition for a tag to be rendered as a link to a
page is the existence of a mapping between the tag and a page in the Tag Mapping admin interface.

Interactions Tag Mapping

Restrictions

Screenshot
(s)

Location /apps/telegraph/core/commons/components/listOfTags (code in telegraph component)

JIRA AEM-1263 - List of Tags enhancements RELEASED AEM-586 - List of Tags RELEASED

Other

300
301
Component Properties
Tab Name Type Description

Configuration Display page-level tag checkbox Enables the display of tags at the bottom of a page

Additional Tags dropdown Enables selection of further tags

Number of tags displayed Number of tags to be displayed initially without expanding the list. Page-level tags will appear first.

Heading Component text Title for tags

Styles Styling dropdown Styling - none

302
Metatags
Component

Metatags
Nickname
(s)

Different types of meta tags rendered in each page's head section can be set up in the CMS. Most of them can be set up on the Metatag configuration pages in the Tools section.
Synopsis

The metaTags page in /etc/telegraph/core/ as well as its channel-specific counterparts (such as /etc/telegraph/core/fashion/metaTags, /etc/telegraph/core/books/metaTags,
Description
etc.) can be used to define the set of metatags to display in the head section of pages belonging to a given channel.

If present, a channel specific configuration will completely override the global one ( /etc/telegraph/core/metaTags). That is, tags defined in the global configuration that are not
defined in the channel-specific one will not be present.

When a new metatag is added, the business user will have to manually add the new metatag configuration on the channels (see screenshot below), where it is required.

When a new channel is added, the business user will have to add all the required metatags if they are different to those in the core (root) node or they would be automatically cascaded down from the
root if no configurations are made in the new channel.

Each of the configuration pages is a flat paragraph system in which MetaData components can be placed.

Each MetaData component represents a single metatag.

Metatags will not be displayed in Sticky Preview. The reason behind this is that the meta tags are expensive to generate due to a very non-performant implementation.

The Metatags should be refactored at some point to generate in a reasonable amount of time. They can then be enabled in Sticky Preview. See metaTags.html (in pageRenderer)
and the Java backend, MetaTagChannelSpecificConfig and ChannelSpecificConfigView.

Interactions

Restrictions

Screenshot
(s)

303
304
305
/apps/telegraph/core/commons/templates/metaDataTemplate - the template for a metat tag configuration page, to be used in the Tools section to set up global or channel specific meta tag
Location
configuration pages

/apps/telegraph/core/commons/renderers/metaDataRenderer - the template's underlying renderer

/apps/telegraph/core/commons/components/metaTag - the component used on the configuration page to set up a single meta tag

/apps/telegraph/core/commons/components/metaTag/headerTag.html - the script responsible for rendering meta tags as seen in the head section of a page. This is called by the metaTag
List by including each meta tag with a selector.

/apps/telegraph/core/commons/components/metaTagsList - a component included on every page that is responsible for rendering the meta tags

uk.co.telegraph.core.commons.metatag.processors.MetaTagProcessorFactory - a Java class that maps different values of the Content type field in the dialog to type-specific processors
(a naming convention arbitrarily selected for a family of classes implementing meta tag value lookup strategies)

/apps/telegraph/core/commons/components/metaTag/templates.html - HTL templates for all kinds of meta tags. Display context and the format of different tag types can be changed
here... assuming this is properly re-used and not copied and pasted everywhere.

JIRA Implemented in ancient history. The first mention of the tags I could find is this: CADS-59 - Webtrends metatags DONE

This list is bound to have some noise in it but I can't narrow it down further - Tomek

T Key Summary Assignee Reporter P Status Resolution Created Updated Due

AEM- 'premiumConte Anand Anand CLOSED Done Nov 17, Nov 17,
7057 ntOnFirstPubli Shirkande Shirkande 2016 2016
sh' meta tag
not displayed.
AEM- Robots meta Unassigned Gavin Kirk TO Unresolved May 18, Jul 04, 2016
5724 tag [X] REFINE 2016
TT-1732 BE - Add Unassigned Austin Harris RELEASED Unresolved Apr 25, Nov 24,
offers meta [X] 2016 2016
tag to pages
that have offer
on
CCORE- Complete Unassigned None DONE Done Dec 10, Jul 14, 2014
72 meta-tags for 2013
the ad-
integration
AEM- Dynamic meta Unassigned Gavin Kirk TO Unresolved Sep 06, Sep 06,
2278 tags [X] REFINE 2015 2015
WEB- Meta tags Wendy Michelle RELEASED Done Sep 14, Aug 22,
1820 access Cocksedge Wilding [X] 2018 2019
ML-170 Meta tag tool Unassigned Gavin Kirk OPEN Unresolved Mar 13, Mar 31, 2015
updates [X] 2015
AEM- Zone meta tag Unassigned Gavin Kirk RELEASED Unresolved Sep 22, Mar 08, 2016
2593 to expose [X] 2015
more layers
WEB- OG Meta Javier Furio Chris Boakes RELEASED Done Oct 01, Nov 28,
3161 Tags 2019 2019
AEM- Button Unassigned None RELEASED Unresolved Jul 15, 2015 Feb 11, 2016
1584 affordance -
Meta Tags
SD- Meta tags Jevonney Michelle CLOSED Done Sep 05, Sep 29,
130097 access Irwin [X] Wilding [X] 2018 2018

306
AEM- Beauty meta Blazej Gavin Kirk CLOSED Done May 27, Jun 08, 2015
854 tags not Kacikowski [X] 2015
rendering on [X]
page
WS-557 Add Google Unassigned Tero Pikala CLOSED Done Sep 15, Apr 09, 2015
site [X] 2014
verification
meta tag to
AEM
TT-2309 Partner Tours: Unassigned Samantha RELEASED Unresolved Sep 15, Nov 24,
Update Meta Edwards [X] 2016 2016
Tag
Processor
EWP- Reinstate Richard Richard RELEASED Done Jun 19, Jun 11, 2015
484 missing meta Spence Spence 2014
tags (for GSA
and generic
tags)
TTT-67 AEM - Update James Bodkin Samantha CLOSED Done Nov 24, Apr 04, 2017
Content_Type [X] Edwards [X] 2016
Meta Tag
WS- Meta tag sdu Gavin Kirk CLOSED Done Nov 13, Nov 18,
3602 corrections websupport [X] 2015 2015
[X]
AEM- New Unassigned Gavin Kirk RELEASED Unresolved Sep 23, Dec 03,
2597 sponsored [X] 2015 2015
content meta
tag indicating
if campaign is
live
AEM- Change the Unassigned Gavin Kirk CLOSED Done Jul 24, 2015 May 18,
1699 Twitter Handle [X] 2016
meta tag to
take the
channel
setting
AEM- Remove time Unassigned Gavin Kirk CLOSED Done Sep 06, May 18,
2279 for [X] 2015 2016
ArticleFirstPubl
ished meta
tag

Showing 20 out of 513 issues

Other

Component Properties
Tab Name Type Description

Configu Tag type Dropdo Type of the metatag. One of the following values:
ration wn
Name tag
Link tag
Akamai tag
OpenGraph tag
URI meta tag

Each of these tag types is associated with a different format of the tag in the head section of the page. See /apps/telegraph
/core/commons/components/metaTag/templates.html

Meta tag Text Name of the metatag to be displayed


name

Content Dropdo
type wn

307
This field completely changes the semantics of a specific meta tag and the way its value is determined. See uk.co.telegraph.
core.commons.metatag.processors.MetaTagProcessorFactory

Static Text The interpretation of this field is different based on the value of the Content type field above. If the Static value content type is
/Default selected as the Content type, the value of this field represents the value of the meta tag. Otherwise, the value MAY be used as
Value the default value for a dynamic meta tag.

Where to Dropdo One of:


display the wn
metatag All pages
Homepage only (just the Portal page)
Exclude homepage (all pages but the Portal)
Travel product pages
Partner tour pages
Holiday pages

Omit if Checkb Check this if the tag should be displayed without a value or if it should be removed from the markup if its value is empty. It is
blank ox necessary for some of the meta tags to be rendered without a value.

Homepage Dropdo Only a single value - Type -is vailable.


property wn
name If the Content type is set to Homepage property, the underlying back-end code will:

1. check if the current page is the Portal page (if it isn't, the tag does not display),
2. check the value of this ( Homepage property name ) field for this specific meta tag field,
3. read a page property with the name matching the value of the field ( Homepage property name ) from the Portal page
4. Display the value of the property as the value of this meta tag

Tags Text This is only used when the Content type of Page tags is selected. It can cause such a meta tag to only display tags from a given
namespace namespace.

Entity This entire Tab should no longer be used. It had to do with the Entity model used by the old Cars, Film and Best sites. It should
Configu be removed (together with the underlying back-end code).
ration

308
Most Viewed List
Component

Most Viewed List, MVL


Nickname
(s)

Description
At the time of writing of this page, the Most Viewed List component is disabled in production. See

AEM-7017 - Delete Most Viewed List OSGi configuration from the code RELEASED for more context.

The most viewed list AEM component is actually just an extension of the Curated List component that is automatically populated with tiles, as opposed to being manually curated.

The following documentation describes all the collaborating components that make up the most viewed list solution:

1. Data Access - how the analytics data is accessed


2. Refresh Scheduler and creating the Most viewed lists
3. Most Viewed list component used within CQ UI

1. Data access - how the analytics data is accessed


Most viewed data is retrieved from the [RETIRED] Most Viewed List API Service Description via an AEM service:

uk.co.telegraph.core.foundation.mvl.MvlConfigurationService

See the following configurations for pre-prod and prod configurations:

PRE PROD: core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author/uk.co.telegraph.


core.foundation.mvl.MvlConfigurationService.xml
PRODUCTION: core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author.prod/uk.co.
telegraph.core.foundation.mvl.MvlConfigurationService.xml

2. Refresh Scheduler and creating the Most viewed lists


The following classes are the main AEM components and services that make up the MVL solution, their collaboration is discussed later:

uk.co.telegraph.core.foundation.analytics.dynamic.list.RefreshScheduler
uk.co.telegraph.core.foundation.analytics.dynamic.list.RefreshConfiguration
uk.co.telegraph.core.foundation.analytics.dynamic.list.RefreshJob
uk.co.telegraph.core.foundation.analytics.dynamic.list.RefreshScheduler

uk.co.telegraph.core.foundation.mvl.MvlDataHandler
uk.co.telegraph.core.foundation.mvl.MvlConfigurationService

The following flow details the basic mechanism behind the most viewed list solution:

An instance of the RefreshScheduler is created and activated on the CMS instance


Currently 3 RefreshConfigurations are then loaded - daily, weekly and monthly (at the time of writing, the only the daily configuration is enabled).

core-root/cq/core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author/uk.co.
telegraph.core.foundation.analytics.dynamic.list.RefreshConfiguration-daily.xml
core-root/cq/core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author/uk.co.
telegraph.core.foundation.analytics.dynamic.list.RefreshConfiguration-weekly.xml
core-root/cq/core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author/uk.co.
telegraph.core.foundation.analytics.dynamic.list.RefreshConfiguration-monthly.xml

When new channels are launched or new sections need to have most viewed lists, just add the channel to the enabled.channels section of each of the configurations above.

If a new content type needs to be supported - such as "gallery" then this would be added into the page.types section of each of the above configurations - note: this would have to go
through the development process and be QA'ed before releasing.

309
For each config, if the config is enabled, a sling scheduled job - an instance of RefreshJob - is created and scheduled according to the scheduler expression specified in the config - for example
the daily job is (currently) scheduled to be run every 1/2 hr. The job contains both a list of channels and a list of AEM content types (currently just "story") that need to be created.
When a RefreshJob executes, it iterates through all channels and types creating an instance of uk.co.telegraph.core.foundation.analytics.dynamic.list.EndpointJob for each channel/type
combination. These jobs are then queued for execution by the configured sling ThreadPool - "TMG-ADFS-ThreadPool"

TMG-ADFS-ThreadPool is used to constrain the impact that the Most Viewed list refreshing has on the CMS. See the configuration file for the min and max pool size:

core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author/org.apache.sling.commons.threads.impl.DefaultThreadPool.factory-TMGADFS.config

Note: this constraint (limiting the number of parallel jobs that can be run) is important. As the process runs on the CMS the impact of the scheduled jobs needs to be
minimised to avoid impacting editorial workflows.

The EndpointJob uses the uk.co.telegraph.core.foundation.mvl.MvlDataHandler to do the following:

3. Most Viewed List component used within CQ UI


Once the above schedule has been run for a particular channel, the MostViewedList component can then be used within the content of that channel:

If the scheduler has not run for the channel, then the most viewed list will show the following warning when used in a page:

310
Most Viewed List API Service
Interactions
Some of the Curated List back-end code is used by this component.

Restrictions

Screenshot
(s)

/apps/telegraph/core/commons/components/mostViewedList
Location
/apps/telegraph/core/commons/renderers/dynamicListDataRenderer - included dynamically by the Most Viewed List, responsible for delegating the presentation logic to the Curated List .

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Most Viewed Apr 23, Oct 25, 2016 Unassigned None TO Unresolved
368 List 2015 REFINE

SD- 'Most Viewed' Feb 13, Feb 16, 2017 John Molloy Chris CLOSED Done
81982 list not 2017 Breckon
working
AEM- Auto populate Apr 16, Jul 16, 2015 Unassigned None CLOSED Done
173 the most 2015
viewed list
WEB-65 APE: Update Jan 18, Mar 20, 2017 Prem Moka Rima Amin CANCELLED Done
Most Viewed 2017
List
EWP- Most Viewed Aug 26, Jun 11, 2015 Unassigned Adriana NEW Unresolved
1799 and Most 2014 Neicu
Shared meta
tags are found
in the source
page of an
article found
in most view
and most
shared list
EWP- Most Viewed, Aug 28, Jun 11, 2015 Unassigned Adriana NEW Unresolved
1819 Most Shared 2014 Neicu
and Most
Commented
meta tags are
found in the
source page
of an article
found in most
view, most
shared and
most
commented
list
AEM- Most Viewed Apr 11, Jun 18, 2018 Unassigned Andrzej CLOSED Done
5272 List - not 2016 Dolinski [X]
visible on

311
author in
preview mode
AEM- Research Jun 02, Jul 16, 2015 Unassigned None CLOSED Done
912 Analytics API 2015
in terms of
Most Viewed
List
AEM- Most viewed Sep 04, Feb 04, 2016 Unassigned None CLOSED Done
2264 list allways 2015
display 5
elements
SD- Add Most Oct 13, Oct 13, 2016 John Molloy Matthew CLOSED Done
70960 Viewed List 2016 Richards
(MVL) to the
TMG
Component
picker list
AEM- Most Viewed Oct 25, Oct 28, 2016 Daniel Gavin Kirk IN Unresolved
6977 List to use 2016 Madejek [X] [X] DEV
Curated List 2
as its core
AEM- Enable the Sep 16, Oct 25, 2016 Daniel Gavin Kirk READY FOR Unresolved
6701 "Most Viewed 2016 Madejek [X] [X] DEV
List" to return
articles of any
type in a
single list
AEM- SPIKE: Figure Sep 02, Sep 14, Daniel Gavin Kirk CLOSED Done
6589 out how Most 2016 2016 Madejek [X] [X]
Viewed List
filters
channels
AEM- Amend Most Mar 15, Mar 24, 2016 Unassigned Mark Cyrson RELEASED Unresolved
4893 Viewed list so 2016
that it returns
results for
whole site
AEM- Ability to May 19, Jun 18, 2018 Unassigned None CLOSED Done
656 manually 2015
exclude
specific
articles from
'Most Viewed'
list
INT-94 Define API Feb 10, Apr 22, 2014 Unassigned Frederic DONE Fixed
call to return 2014 Dran
list of most
viewed
sections
AEM- Delete Most Nov 07, Dec 05, James Bodkin Lucian RELEASED Unresolved
7017 Viewed List 2016 2016 [X] Craciun
OSGi
configuration
from the code
AEM- Error during Mar 11, Mar 24, 2016 Unassigned Andrzej RELEASED Unresolved
4805 putting Most 2016 Dolinski [X]
Viewed List
component on
the Bare page
WEB- Most viewed Jun 19, Jun 27, 2017 Flavio Russell Deep CLOSED Done
557 list shows only 2017 [X] Liyanage [X]
2 items on the
published
page, ignoring
the max no of
items
displayed
configuration
AEM- When deleting Sep 07, Feb 04, 2016 Unassigned None CLOSED Done
2280 an existing 2015
article it still
occur in most
viewed list vs
AC

Showing 20 out of 196 issues

312
Other

Component Properties
Name Type Description

313
Navigation
Component

Navigation, global nav, primary nav, overlay nav, rich nav, feature rich navigation
Nickname
(s)

Allows users to navigate the website


Synopsis

The navigation elements are SSIs so can be updated and published independently of the content
Description

Global navigation displays different links depending on the user status (i.e. logged in? Subscribed?) this is dependent on the tmg_p13n cookie. The global nav also adds a value to links containing
Interactions redirectTo param
(see OPI-420) and the overlay nav can be displayed via the "All Sections" toggle

Navigation behaviour differs on Desktop and Mobile, for example on mobile only the first three global nav elements are displayed and the primary nav is hidden completely
Restrictions

To configure the navigation elements follow the instructions on the Feature Rich Navigation page
Usage
instructions

Screenshot
(s)

Location telegraph/core/commons/components/navigation/*

telegraph/core/commons/snippets/richNavHeader/richNavHeader.html

telegraph/core/clientlibs/core/js/components/component.global-nav.js

telegraph/core/clientlibs/core/js/components/component.overlay-nav-button.js

telegraph/core/clientlibs/core/js/components/component.overlay-nav-secondary.js

telegraph/core/clientlibs/core/js/tmg.js (see window.tmg.setLoginStatusAttributes)

telegraph/core/clientlibs/tmgchannels/_base/sass/snippets/snippet.header.scss

telegraph/core/clientlibs/tmgchannels/_base/sass/snippets/snippet.header/*

314
telegraph/core/clientlibs/tmgchannels/_base/sass/snippets/snippet.overlay-nav/*

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

OPI-249 Global Aug 23, Oct 04, 2016 Patrick Eric Cheng RELEASED Done
Navigation - 2016 Clancey [X] [X]
Improvement
to the user
experience
OPI-49 Global Jun 17, Aug 31, Unassigned Robert TO Unresolved
Navigation - 2016 2016 Toshman REFINE
Update and
included
connecting to
Loyalty site
OPI-355 A new Sep 29, Oct 20, 2016 Patrycja Anna Dezor RELEASED Done
navigation 2016 Platek [X] [X]
item cannot
be added to
navigation
config
template
OPI-297 Add Premium Sep 09, Oct 20, 2016 Patrycja Eric Cheng RELEASED Done
link to the 2016 Platek [X] [X]
primary
navigation in
the TCUK
homepage
OPI-391 Cannot login Oct 17, Oct 27, 2016 Unassigned Anna Dezor CLOSED Done
from global 2016 [X]
navigation on
test8
OPI-185 8.5) Easy of Aug 11, Sep 14, Unassigned Syreeta Sims CANCELLED Unresolved
Navigation 2016 2016 [X]
OPI-539 Server Side Nov 03, Nov 03, Unassigned Tomasz TO Unresolved
Include (SSI) 2016 2016 Niedzwiedz REFINE
the whole [X]
Navigation
OPI-390 Logout clear Oct 17, Nov 03, Grzegorz None RELEASED Done
cookie to fix 2016 2016 Bednarski [X]
global
navigation
OPI-380 Server Side Oct 13, Oct 20, 2016 Grzegorz Tomasz RELEASED Done
Include 2016 Bednarski [X] Niedzwiedz
navigation [X]
links to login
and
registration
OPI-532 LoginRegistrati Nov 02, Nov 07, Mathias Anand CLOSED Done
on/Subscribe 2016 2016 Douchet Shirkande
top navigation
links not
displayed on
home page on
mobile
devices.
OPI-520 'Contact Us' Nov 01, Nov 01, Tomasz Anand CLOSED Done
page not 2016 2016 Niedzwiedz Shirkande
displayed if [X]
navigated
from Register
page.
OPI-516 User Nov 01, Nov 02, Luis Anand CLOSED Done
navigated to 2016 2016 Khamashta Shirkande
akamai8 if
tried to
subscribe
through
rewards on
Opium.
OPI-506 Registered Oct 31, Nov 01, Unassigned Anand CANCELLED Unresolved
User is able to 2016 2016 Shirkande
view any
premium

315
article if
navigated
through My
Account.
OPI-504 Incorrect Oct 31, Jan 31, 2017 Tomasz Patrycja RELEASED Done
icons on login 2016 Niedzwiedz Kurkowiak
page when [X] [X]
user tries to
log from
global
navigation
level
OPI-184 Device access Aug 11, Aug 11, Unassigned Syreeta Sims TO Unresolved
and ease of 2016 2016 [X] REFINE
navigation
OPI-454 Styling issues Oct 27, Nov 02, Grzegorz Grzegorz RELEASED Done
on login and 2016 2016 Bednarski [X] Bednarski [X]
registration
pages
OPI-397 Ring fence My Oct 18, Nov 02, Patrycja Patrick RELEASED Done
Account look 2016 2016 Platek [X] Clancey [X]
and feel
OPI-180 [aem] 8.1) Aug 11, Jan 31, 2017 Patrycja Syreeta Sims RELEASED Done
Ability to view, 2016 Platek [X] [X]
list of current
Newsletters I
am signed up
to
OPI-443 Unable to Oct 26, Oct 27, 2016 Arnaud Gary Brown CLOSED Done
login and 2016 Lamotte [X] [X]
access my
account
OPI-451 Premium Oct 26, Oct 27, 2016 Unassigned Gunay Tacel TO Unresolved
articles can be 2016 [X] REFINE
seen after
logging out
(registered
user)

Showing 20 out of 530 issues

Related Local navigation


links Feature Rich Navigation

Other

Component Properties
Name Type Description

316
Footer
Nickname(s) Footer

Synopsis This is is the global footer used on all pages across the site. It is part of he Navigation solution.

Description This Navigation item has been separated out here as it uses a different template, called Footer Config, which has the addition of the
copyright text, symbol and year.

The main item of note hear is that the year is not content editable but added to the Copyright text automatically by AEM.

Interactions

Restrictions

Usage
instructions

Screenshot(s)

Location See Navigation

JIRA See Navigation

Related links

Other

317
Local Navigation
Nickname(s) Local Navigation, Section Navigation

Synopsis Enable each channel to configure and manage their own sub-navigation for their channel.

Description This is part of the Navigation and has been separated out here to highlight that each channel has its own Local Navigation.

Interactions

Restrictions

Usage instructions To configure the navigation elements follow the instructions on the Feature Rich Navigation page

Screenshot(s)

Location

JIRA

Related links

Other

318
Ooyala overlay
Component

Ooyala
Nickname
(s)

Service for embedding videos


Synopsis

All Ooyala vendor scripts are compiled into ooyala-min.js and loaded outside of the main app.js file because they are syntax errors when trying to minify and concatenate with our version of YUI
Description compressor.
File comprises of-

Core
Skin
HTML5 plugin
Google IMA plugin
bitwrapper plugin (this also calls in other bitwrapper plugins from the same folder depending on the video format)

The Skin also has a settings and language file which are JSON format.
The Skin also has a CSS file which is minified and stored in the video component scss file with some overrides.
All videos have an overlay where authors can override the title and preview(background) image if not the the title is the video title and the preview image is taken from the first frame of the video using
the Ooyala API (all backend work).
Once the user clicks play then the Ooyala-min.js file is initialised using the yepno js plugin inside the page head. Once initialised, the overlay screen is hidden (display none) and the video is set to
auto play to prevent the user having to click the Ooyala video play button.
Ooyala requires a unique ID on each player element so that is set during the init function.
At the end of each video there we grab a list of related videos (trending which comes from the Ooyala discovery api, series path which is set in page properties or search path which is set at
component level) and then watch for the 'played' event from the video and then update the player embed code to the next one in the list.
Ads are pulled in the videos via the Google IMA plugin and the adUrl is set dynamically in js built by the ads team (not in the telegraph-component repo).
The video series page has a sticky video which has a separate js file, sticky-video.
There is a User Guide on Confluence that explains the Author process in adding a video to an article, Eric wrote this and Rima and Mark have been through it with me to clear up any unknowns.

Interactions

Restrictions

Screenshot
(s)

Video Player component - telegraph-component/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/videoPlayer/videoPlayer.html


Location
Ooyala Core CSS - telegraph-component/cq/core-design/src/main/cq/jcr_root/etc/designs/telegraph/core/clientlibs/tmgchannels/_base/sass/plugins/ooyala.scss

Ooyala Core JS - telegraph-component/cq/core-design/src/main/cq/jcr_root/etc/designs/telegraph/core/clientlibs/core/js/ooyala/ooyala-player.min.js


Video Player component CSS - telegraph-component/cq/core-design/src/main/cq/jcr_root/etc/designs/telegraph/core/clientlibs/tmgchannels/_base/sass/components/component.video-player.scss

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

EWP- Ooyala videos Oct 02, Oct 02, 2015 Cristian Paun None NEW Unresolved
4033 and ads are 2015
displayed
under the
footer on
mobile pages
EWP- Verify that May 15, Jun 11, 2015 Unassigned None NEW Unresolved
3301 size of 2015
preform
ooyala videos
is 620x349 for
wide articles
AEM- IE 11 - Video Dec 13, Dec 16, Unassigned Anna Dezor TO Unresolved
7170 cannot be 2016 2016 [X] REFINE
played on
video play
page
AEM- Tidy up Nov 07, Dec 16, Dan Mitchell Eric Cheng READY Unresolved
7116 Ooyala CSS 2016 2016 [X] [X] FOR
DEV

AEM- Update Nov 21, Dec 16, Dan Mitchell Luis TO Unresolved
7115 Ooyala V4.8.5 2016 2016 [X] Khamashta REFINE
to Version
4.10.4

5 issues

Other

Component Properties

319
Name Type Description

320
Paywall, meter (ESI)
Component

Paywall and Meter


Nickname(s)

The Paywall is built from 3 a AEM components:


Description
premiumPaywallHeader
paywallPackage
premiumPaywallFooter

The Paywall is showing only on Akamai layer for:

1. anonymous user (based on the configuration located in /content/telegraph/application/paywall/anonymous )


2. users registered but without an active subscription (displays the content from /content/telegraph/application/paywall/subscribe )

The page knows when to add the paywall html from the Evelok (meter) response (check possible responses below).

The whole interaction in definied in the ESI* language and evaluated only on Akamai layer.
Interactions Interacted services:

global switch - external place where during ESI evaluating code on akamai, code is checking if there is whole feature enabled or disabled (example http://meter-globalswitch.awspreprod.
telegraph.co.uk/meter-dev2.html)
evelok (meter) - external service (example path: http://evolok-uat.telegraph.co.uk/evolok-ad-web/api/3.0/authorize/esi) where AEM is sending couple of information about user and current page,
like if article is premium, and expect in response if user should see full page content or the paywall

Current possible responses from evelok (meter):

1. ALLOW_ACCESS -> no paywall


2. REQUIRE_LOGIN -> anonymous paywall
3. REQUIRE_ENTITLEMENT -> subscribe paywall

The Paywall/Meter script is adding only on article2, offer and gallery. In AEM exists page property where you can decide to add or not the Paywall/Meter script.
Restrictions Possible values of page property:

inherit (default) - takes configuration from parent


disabled - no paywall/meter script on the page
enabled - paywall/meter script added
silent - paywall/meter script added but in silent mode, this mean that user will see full page content always (no paywall displaying). but user will by counted by evelok (lost 1 credit)

AEM paywall components


Screenshot
(s)

Paywall example on akamai

321
Example Meter OSGI configuration

The Paywall can display different paywall versions for different countries (defined by Akamai GEO{'country_code'})
Geo
To create a country specific paywall
location
(AEM 1. Find the ISO 2 digit country code for the country you want to add
2. Login to the AEM CMS and navigate to the paywall folder /content/telegraph/application/paywall
4.7) 3. Create a new "paywall container" child page ensuring that the "name" field is your country code in lower case (see example)

4. Copy the existing Anonymous and Subscribed paywall pages and paste under your new paywall container page you created at step #3
5. Amend the new paywall pages and publish them (remembering to also publish your paywall container page)
6. At this point, check your new paywall page is visible on the dispatcher for example...
a. http://aem-docker-qa5.aws-preprod.telegraph.co.uk/application/paywall/subscribe/_jcr_content/paywallContainer/ (default subscriber paywall on QA5)
b. http://aem-docker-qa5.aws-preprod.telegraph.co.uk/application/paywall/us/subscribe/_jcr_content/paywallContainer/ (USA version, note the country_code "/us/" in the URL)
c. http://aem-docker-qa5.aws-preprod.telegraph.co.uk/application/paywall/na-continent/subscribe/_jcr_content/paywallContainer/ (North America version, note the continent code "/na-
continent/" in the URL)
7. When you have verified your paywall page is visible on the dispatcher, edit the page properties on the Telegraph Portal page, adding US (in upper case) to the GeoLocations section (see
example). Save and publish

8. Allow some time for the page properties to propagate, you can check the new country has been added by viewing dispatcher source on a freshly published article and searching for "has $(GEO
{'country_code'})" when your country code appears in the preceding string you know it's propagated ok, you can then clear the dispatcher cache for older articles to allow the new country setting
to be picked up.

(There is a basic USA paywall package attached paywall-USA-2.0.zip, install package and then jump to step #7 above)

NB; the paywall also supports the Akamai GEO{'continent}' param. The process is the same as for country but with '-continent' appended to the page name. i.e. creating a paywall container with the
name 'sa' at step #3 would be used for the country South Africa and 'sa-continent' would be used for the continent South America.

(this superseeds the preivous section)


Geo location
(Single page)
Using a sigle page configuration pawall. Quick start; Install the paywall-geo-2.zip on the target environment then select the correct config page, and skip to step 8 below.

322
To create a sigle pawall page that supports muliple countries and continents

1. Open the AEM Author instance on the revelvant environment


2. locate the products folder in the content finder (content/telegraph/products) create a new page type "Products for geo paywall" (sugest naming this as per the target environment e.g. paywall-
uat, paywall-prod etc...)

3. Open this page to edit (I reccomend touch UI for table editing. Presuming your in Classic UI open the page to edit and then change the /cf#/content... in the current URL to /editor.html/content... )
4. There are three tables, Country, Continent and Default paywalls. Click on the one you want to edit; select edit, select full screen.

323
5. Once you are on the full screen editor, you can amend the table as necessary.

6. To use the setting page create a page in telegraph/application/paywall of the "Geo Paywall" type, e.g. paywall-multinational

7. Open in normal editor and edit the configuration chooseing the path of the multnational table we just created (step #2) On the settings dialog you will find the; domain setting, header footer, and
register setting which are common to all paywalls (these can't be edited on a paywall by paywall basis).

8. Putting it live (one off task)


To change from the current seporate pages to the combined page, you need to open the page properties for the Telegraph portal page and select "Use single page" checkbox and add the name
of the page you want to use (the name of the page from step #6 "paywall-multinational" in our example above, save and activate.

In AEM content:
Code /content/telegraph/application/paywall/*
Location
- In open-premium mode are using:
/content/telegraph/application/paywall/subscribe
/content/telegraph/application/paywall/anonymous

In OSGI (/system/console/configMgr):
TMG - METER Integration

In CRX repository:

324
/apps/telegraph/core/commons/snippets/meterCheck
/apps/telegraph/core/commons/snippets/paywall
/apps/telegraph/core/config/renderers/paywallRenderer
/apps/telegraph/core/config/templates/paywallTemplate

/apps/telegraph/core/commons/components/paywall/premiumPaywallHeader

/apps/telegraph/core/commons/components/paywall/premiumPaywallFooter

/apps/telegraph/core/commons/components/paywall/premiumPaywallContainer

/apps/telegraph/core/commons/components/paywall/paywallPackage

/apps/telegraph/core/commons/snippets/meterCheckOpenPremium
/apps/telegraph/core/commons/snippets/paywallOpenPremium
/apps/telegraph/core/config/renderers/premiumPaywallRenderer
/apps/telegraph/core/config/templates/premiumPaywallTemplate

/apps/telegraph/core/config/templates/paywallContainerTemplate

In Java:

MeterConfigurationService.java
MeterStatusProvider.java
OpenPremiumModeProvider.java
MeterStatus.java

uk.co.telegraph.core.commons.paywall.components.*
(sling models for paywall components)

First original ticket is here:


JIRA https://jira.aws.telegraph.co.uk/browse/AEM-1025
First paywall design here:
https://jira.aws.telegraph.co.uk/browse/AEM-1621
Second paywall design:
https://jira.aws.telegraph.co.uk/browse/AEM-1622
First open premium ticket:
https://jira.aws.telegraph.co.uk/browse/OPI-1
First open premium design
https://jira.aws.telegraph.co.uk/browse/OPI-117

Whatever mentions paywall or meter in the AEM Jira, with the status Released.

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Incorrect Feb 05, Feb 16, 2016 Piotr Rzasa Piotr Rzasa RELEASED Unresolved
4298 <head/> 2016 [X] [X]
element in
paywall body
AEM- On tabbing Nov 13, Feb 05, 2016 Unassigned Anna Dezor RELEASED Unresolved
3273 through the 2015 [X]
paywall the
focus goes on
the article
bellow
AEM- Meter - Jul 17, 2015 Jan 12, 2016 Unassigned None RELEASED Unresolved
1622 Paywall
version 2
Design
Implementatio
n
AEM- Question Jan 15, Feb 03, 2016 Unassigned Anna Dezor RELEASED Unresolved
4008 mark added 2016 [X]
automatically
to the
subscribtion
link on
paywall
AEM- Not hidden Nov 16, Feb 05, 2016 Krzysztof Anna Dezor RELEASED Unresolved
3289 article body 2015 Gorzynski [X] [X]
under the
paywall in
specific case
AEM- The paywall Nov 13, Feb 05, 2016 Unassigned Anna Dezor RELEASED Unresolved
3275 disappears 2015 [X]
after some
time when
refreshing the
page
AEM- Video - Visting Apr 27, May 06, Krzysztof Tarun RELEASED Unresolved
5534 video playlist 2016 2016 Gorzynski [X] Sharma
page
increment the

325
meter count
for paywall
AEM- esi tag Jan 27, Feb 10, 2016 Piotr Rzasa Tarun RELEASED Unresolved
4160 implementatio 2016 [X] Sharma
n for paywall
in article2
body breaking
html and
affecting
downstream
applications
AEM- International Oct 17, Oct 26, 2017 Unassigned Patrick RELEASED Unresolved
7696 paywall 2017 Clancey [X]
management
improvment
AEM- Paywall v2 Oct 29, Feb 05, 2016 Unassigned None RELEASED Unresolved
3104 CSS 2015
AEM- Paywall v2 Oct 29, Feb 05, 2016 Krzysztof Krzysztof RELEASED Unresolved
3101 backend 2015 Gorzynski [X] Gorzynski [X]
implementatio
n
AEM- SUB-7378 Aug 24, Sep 13, Patrick Patrick RELEASED Unresolved
7670 Make 2017 2017 Clancey [X] Clancey [X]
GeoLocation
options in
paywall
AEM- Paywall v2 Nov 03, Feb 05, 2016 Piotr Rzasa Krzysztof RELEASED Unresolved
3163 update 2015 [X] Gorzynski [X]
automated
tests
AEM- Paywall v2 Oct 29, Feb 05, 2016 Unassigned None RELEASED Unresolved
3103 Establish 2015
markup and
prepare
mocks
AEM- Gift subs AEM Nov 16, Nov 23, Unassigned Patrick RELEASED Unresolved
7711 2017 2017 Clancey [X]
AEM- Fix all Mar 10, Apr 05, 2016 Michael None RELEASED Unresolved
4793 deprecated 2016 Goszczynski
$(document).
on("ready")
calls in JS
files
AEM- Unable to Jan 06, Jan 27, 2016 Michael Michael RELEASED Unresolved
3896 create meter 2016 Goszczynski Goszczynski
configuration
pages
AEM- Video Sep 26, Nov 23, Patrycja Eric Cheng RELEASED Unresolved
6777 Playback 2016 2016 Platek [X] [X]
Errors and
Error
Messages
AEM- Js Error: tmg. Jan 28, Feb 10, 2016 Piotr Rzasa Anna Dezor RELEASED Unresolved
4192 onresize is not 2016 [X] [X]
a function
AEM- Incorrect Nov 12, Feb 05, 2016 Unassigned Anna Dezor RELEASED Unresolved
3256 width of top 2015 [X]
header on
tablet version

Showing 20 out of 26 issues

Example meter script: HERE


Other Example paywall script: HERE

When the editor change something in paywall content and activate it, on java side exist listener on it which on force to clear paywall cache on dispatcher automatically. Thanks to that this change is
Flushing going to akamai quickly.
dispatcher
cache for Java classes:
paywall
PaywallReplicationListener.java

PaywallReplicationEventConsumer.java

Premium Paywall Container

326
This is container node to get only paywall html when akamai call for it:
http://www.akamai2.awspreprod.telegraph.co.uk/application/paywall/subscribe/_jcr_content/paywallContainer/
http://www.akamai2.awspreprod.telegraph.co.uk/application/paywall/anonymous/_jcr_content/paywallContainer/

Premium Paywall Header Component Properties


Name Type Description

Article Heading text Text what will be displaying on article2 (managed by css)

Gallery Heading text Text what will be displaying on gallery (managed by css)

Leading Text richtext Text which possibility to add bullet lists, links and more.

Premium Paywall Footer Component Properties


Name Type Description

Footer Text text

Link Text text

Link Path path Path to login page for example: https://auth-uat.telegraph.co.uk/sam-ui/login.htm?logintype=tmg&redirectTo=

Trailing Text richtext Text which possibility to add bullet lists, links and more.

Paywall Package Component Properties


Name Type Description

Heading text

Subheading text

Link style selection css style for call to action link

Call to action text text

Call to action path path Path for example to sign up page like https://auth-uat.telegraph.co.uk/sam-ui/register.htm?logintype=tmg&redirectTo=

Benefits richtext Text which possibility to add bullet lists, links and more.

Extra benefits richtext Text which possibility to add bullet lists, links and more.

*Note

redirectTo= - this is a placeholder where javascript is adding current page path. Thanks to that after log in, user will be redirect to last page after submit.

327
Publication Date Override
Publication Date Override
Nickname
(s)

The Publication Date Override (PDO) is a page properties of every page. Visitors will see if displayed via the Article Date on the Article 2 Template.
Description
The purpose of the property is to stabilise and give control of the date that is displayed to visitors as the publication date of an article.

PDO Update Rules:

On page creation the PDO remains blank.


If an editor has added a value to the PDO before the first activation andthen activates the page then the manually set PDO remain unchanged
Upon first activation, if the PDO value has not been set manually, then it is automatically populated with the AEM publish date.
Once the PDO has been set,whether manually or automatically) then it is never updated automatically again (so if an article is updated and republished the PDO stays the same unless the eifitor
changed it manually as part of the update)
Notes:
On previewing an article that has never been published the Article Date component displays the page creation date.
If the editor adds or edits the date in the Article Date component it will not update the PDO. So although the preview may show the revised date on the published page the Article
Date component will always show the PDO value.

This component loads data from pages the Publication Date Override (see Overrides tab in Page Properties).
Interactions

Restrictions

Screenshot Item Screenshot


(s)

Publication Date Override


property

Article Date uses PDO but


does not update it

Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Standardise Mar 19, Sep 04, Anna Dezor Melinda RELEASED Unresolved
465 Publication 2015 2015 [X] Rogers [X]
Date
treatment in
Articles &
Lists

328
1 issue

Other

329
Segment Container
Segment Container
Nickname
(s)

The Segment Container is a shell component that other components are placed in. The component can had a heading, navigation and sub-menus of likes. It also has a Show/Hide feature that opens
Synopsis and closes the content area of the Segment Container. When closed only the heading and navigation are visible.

The Segment Container is used heavily in the Sport channels to help group content together on index pages. It allows editor to create a section of related content within a page.
Description It is a shell that can have a heading, its own navigation and sub-menus. It has typically been used to contain list that relate to a particular category such as "Premier League" on the Football page.

In some cases in production the Segment Container has been configured to display the Show/Hide link and appears not to hide the content when used. This is due to editors placing their
content underneath the Segment Container rather than inside its shell. So this is not a bug but poor configuration.

Interactions

Restrictions

Screenshot Item Screenshot


(s)

Segment Container with sub-


menu closed

Segment Container with sub-


menu open

Show/Hide (open and closed)

Component config

(heading and navigation links)

330
Component config

(navigation links & sub-menu


reference)

Sub-menu config page location

331
Sub-menu config page

Sub–menu navigation link item

/apps/telegraph/core/commons/components/segmentContainer
Location
/etc/designs/telegraph/core/clientlibs/core/js/components/component.segment-container.js

JIRA AEM-2171 - Segment Container for Sport RELEASED

Related:

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Allow Mar 17, Mar 24, 2016 Blazej Jo Mitchell RELEASED Unresolved
4940 segment 2016 Kacikowski [X]
containers to [X]
be placed in
splitter
AEM- Allow Show Mar 10, Mar 24, 2016 Blazej Jo Mitchell RELEASED Unresolved
4800 /Hide to be 2016 Kacikowski [X]
hidden on [X]

332
segment
containers
AEM- Make the start Mar 07, May 17, Unassigned Gavin Kirk TO Unresolved
4712 and end of a 2016 2016 [X] REFINE
Segment
Container
obvious to
authors in
AEM interface
AEM- Enable the Feb 24, Mar 02, 2016 Blazej Jo Mitchell RELEASED Unresolved
4547 segment 2016 Kacikowski [X]
container [X]
component to
be used in
snippets
AEM- Video Finder Feb 24, Aug 08, Andrzej Robert READY Unresolved
4539 Alternative - 2016 2016 Dolinski [X] Toshman FOR DEV
Use the
Segment
Container
/Snippet for
the Video Hub
Template and
Video Play
Pages
AEM- Remember Jan 18, Jun 15, 2016 Unassigned None TO Unresolved
4032 segment 2016 REFINE
container
Show/Hide
status
AEM- Apply channel Dec 08, Feb 22, 2016 Unassigned Mark Cyrson RELEASED Unresolved
3702 colour to each 2015
Segment
Container
AEM- Segment Dec 01, Feb 18, 2016 Unassigned Gavin Kirk RELEASED Unresolved
3569 Container 2015 [X]
should check
all dependent
pages when
activated
AEM- Spike: Test to Oct 08, Nov 05, Unassigned Gavin Kirk CLOSED Done
2820 see how 2015 2015 [X]
Segment
Container
works on
Article 2
AEM- Segment Aug 27, Dec 08, Unassigned Gavin Kirk RELEASED Unresolved
2171 Container for 2015 2016 [X]
Sport
AEM- Segment Aug 27, Jan 20, 2016 Unassigned Gavin Kirk TO Unresolved
2155 container 2015 [X] REFINE

11 issues

Other This ticket should be dealt with so a Splitter can be used inside Segment Container AEM-4703 - Cannot add a Splitter into a Segment Container TO REFINE

333
Snippet & Snippet Reference
Component

Nickname Snippet Reference, Snippet


(s)

Synopsis Snippets enable the users to define reusable bits of content. Every snippet is a page, based on the Snippet template, with a single
paragraph system inside which an author can place arbitrary components. The partial HTML document rendered by the resulting
page can then be included on other pages by the Snippet Reference component.

Description Snippets enable the users to define reusable bits of content. Every snippet is a page, based on the Snippet template, with a single
paragraph system inside which an author can place arbitrary components. The partial HTML document rendered by the resulting
page can then be included on other pages by the Snippet Reference component.

Snippet pages are edited in the same way as any other page. Authors can drag and drop components from the sidekick and
configure them to enter the desired content.

The Snippet Reference component can be used to point at a specific snippet page and display its contents.

The contents of a page included by a Snippet Reference are not editable in place. One has to visit the snippet page itself to be
able to edit the components placed there.

Snippet definitions are usually found in the application folders across Channels, as well as in the Portal's application
folder. For example:

/content/telegraph/application/snippets
/content/telegraph/fashion/application/snippets
content/telegraph/art/application/snippets

Portal Page Snippets


Snippet pages are key to the operation of the Portal Page. The basic unit of replication in AEM is a Page. At the same time,
concurrent editing of pages can result in lost updates. It's possible to lock a page but that would make it impossible for the Portal
page to be configured efficiently. Because of this, the Portal page is heavily based on Snippets. Every section of the Portal page
contains a separate Snippet Reference component pulling in content from a different Snippet page. The separate Snippet pages
can be updated concurrently.

Interactions This component uses Server Side Includes.

Restrictions

Screenshot
(s)

Location The code for Snippet pages and the Snippet Reference component resides in the telegraph-component repository.

/apps/telegraph/core/commons/templates/snippetTemplate

334
/apps/telegraph/core/commons/renderers/snippetRenderer

/apps/telegraph/core/commons/components/snippetReference

The pathfield in the Snippet Reference dialog only allows snippet pages. This is made possible by the OSGi service uk.co.
telegraph.core.commons.snippet.SnippetTemplatePredicate

JIRA AEM-3165 - Enable reusing content on multiple pages (snippets for Opta Widgets) RELEASED

Other

Component Properties
Name Type Description

Snippet Pathfield The snippet page to render in place of this component. Only displays pages based on the Snippet template.

335
Social Follow
Component

Social Follow
Nickname
(s)

Social Follow is a means of sharing content and displaying popularity through social media counts.
Description

Interactions

Restrictions

Some examples of the Social Follow component from across different channels
Screenshot
(s)
Item Business example Fashion example

Component

Channel
config

336
337
Social follow works by using the FB api which is initialised on certain pages when FB related functionality is detected.

FB requires an app to exist on a specified developer account on FB itself and for the code initialising the FB api object to call using the specific FB appId.

The FB appID is set on the portal (Telegraph) page of the website and can be configured from within page properties.

This appID is used by all FB sharing functionality not just Social Follow.

DO NOT CHANGE THE APPID UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING AND HAVE CREATED AN APP WITH ALL REQUIRED PERMISSIONS + OTHERWISE YOU WILL BREAK ALL

FACEBOOK RELATED FUNCTIONALITY ON THE SITE.

Location

JIRA

Key Summary T Created Updated

AEM-112 Social following component Apr 14, 2015 Aug 13,


2015
AEM-1535 Social sharing & following v1 Jul 10, 2015 Mar 14, 2016

AEM-1599 Social Sharing & Following Telegraph (UX) Jul 16, 2015 Aug 17,
2015
AEM-5574 Social - Following - Extend Networks and enable users to control presentation etc May 03, Dec 06,
2016 2016
AEM-6039 Groovy script for inserting Social Follow component on Hub Pages Jun 17, 2016 Jul 05, 2016

AEM-5976 Social - Following - SSI Jun 09, 2016 Jun 09, 2016

AEM-7599 PostConstruct errors when adapting to uk.co.telegraph.core.commons.social.follow.SocialFollowModel Jul 04, 2017 Jul 10, 2017

AEM-7059 Social Follow - Facebook initialisation issue Nov 18, Feb 03, 2017
2016
AEM-853 Social Sharing & Following Telegraph (Design) May 27, Aug 13,
2015 2015
AEM-5663 Social - Following - Non JS versions May 11, Jun 29, 2016
2016
AEM-5973 Crossbrowser: Follow - B: iPads: all socials are not in line Jun 09, 2016 Jul 05, 2016

AEM-6181 Mark up CTA in social follow component with <span> rather than h1 Jul 07, 2016 Aug 01,
2016
AEM-5972 Crossbrowser: Follow - A: on mobiles and tablets all social buttons except primary should be hidden Jun 09, 2016 Jul 05, 2016

AEM-5606 Social - Add tagging for Social Follow Networks May 06, Jun 29, 2016
2016
AEM-1544 Social following spike Jul 10, 2015 Jul 22, 2015

AEM-6122 Styles for some following buttons are not displayed in Firefox Incognito mode Jun 28, 2016 Dec 21,
2016
AEM-578 Facebook like integration (UX) Jan 22, 2015 Jul 29, 2015

AEM-5422 Social - Share Tools - Add more Social Networks Apr 20, 2016 Sep 07,
2016
AEM-4853 Social Improvements Q2 2016 Mar 14, Oct 03, 2016
2016
AEM-652 Enhanced Social Functionality May 18, Aug 13,
2015 2015

Showing 20 out of 66 issues

The Social Follow component on the Articles and Galleries requires no configuration. It takes is configuration from the page properties Social tab of the channel page (see above).
Other

338
Component Properties
Name Type Description

339
Social Share
Component

Social Share
Nickname
(s)

Social Share is component enabling content to be shared using different social media providers such as Facebook, Twitter, Pinterest, LinkedIn and by email client.
Description
Typically this will be set at the channel level and inherited down to child pages. This is because each channel's selected the social sharing networks that their readers are most likely to use.

Interactions

Baked into the Article 2 and Gallery pages. Only available in the sidekick on Bare pages.
Restrictions

Screenshot Item Business example Fashion example


(s)

Social
Share on
desktop

Social
Share on
mobile

(adds
WhatsApp
if
configured)

Channel
page
config

The Social Share component has its own config. This is given default setting when placed on new articles and galleries.

340
Social share works by using api's for the particular sharing device being used. In the case of FB this means that it uses the FB api which is initialise on certain pages when FB related functionality is

detected. FB requires an app to exist on a specified developer account on FB itself and for the code initialising the FB api object to call using the specific FB appId.

The FB appID is set on the portal (Telegraph) page of the website and can be configured from within page properties.

This appID is used by all FB sharing functionality not just Social Share.

DO NOT CHANGE THE APPID UNLESS YOU KNOW EXACTLY WHAT YOU ARE DOING AND HAVE CREATED AN APP WITH ALL REQUIRED PERMISSIONS + OTHERWISE YOU WILL BREAK ALL

FACEBOOK RELATED FUNCTIONALITY ON THE SITE.

/apps/telegraph/core/commons/components/socialSharing
Location
/etc/designs/telegraph/core/clientlibs/core/js/components/component.socialShare.js (based on http://sharrre.com/)

JIRA

Key Summary T Created Updated Due

AEM- Social Sharing & Following Telegraph (UX) Jul 16, 2015 Aug 17,
1599 2015
AEM- Issue with social sharing and article image Jul 13, 2017 Aug 09,
7634 2017
AEM- Social - Share Tools - Add more Social Networks Apr 20, Sep 07,
5422 2016 2016
AEM- Configure Social Sharing for WhatsApp Nov 17, May 05,
3325 2015 2016
AEM- Social - Add analytics tracking for Social Sharing buttons Dec 17, Aug 24,
3808 2015 2016
AEM- Social - Share Tools - Enable Total Counts Apr 20, Jul 05, 2016
5421 2016
AEM- Social sharing buttons are not rendered on article pages Aug 24, Sep 16,
6554 2016 2016
AEM-175 Social - Add Email, Pinterest & Whatsapp options to sharing Mar 04, May 22,
2015 2015
AEM-413 Social - Share a gallery or slide Apr 28, Mar 08, 2016
2015
AEM-365 Implement and extend the social sharing component on AEM Apr 23, Jun 20, 2016
2015
AEM-512 Social Sharing component styling May 07, Aug 18,
2015 2015
AEM- Two social share components displayed. Dec 07, Dec 07,
7141 2016 2016
AEM-927 Social Share component js error Jun 02, May 20,
2015 2016

341
AEM- Social share icons are always sticky May 30, Jul 05, 2016
5844 2016
AEM- The first social share icon get the 'share' text May 27, Jul 05, 2016
5836 2016
AEM- Social sharing & following v1 Jul 10, 2015 Mar 14, 2016
1535
AEM- Social share count styling issue Apr 01, May 03,
5174 2016 2016
AEM-346 Social - Add Pinterest to social sharing component Apr 22, Aug 13,
2015 2015
AEM- Styling of social sharing total count May 17, Jul 05, 2016
5717 2016
AEM- Social share icons are not visible in correct way on Fast Preview mode Jun 27, Jun 28, 2016
6107 (WCMMODE=disabled) 2016

Showing 20 out of 103 issues

Other

Component Properties

It is highly uncommon for the Social Sharing component to be configured on a per-instance basis. Use the options in Page properties
described above rather than the component dialog.

Name Type Description

Show Social Media Counters Radio


Inherit (show or hide the counters based on the inherited page properties)
Yes (force the counters to show)
No (force the coutners to hide)

As of December 2016, there is no context in which the counters should ever be displayed.

Enable Twitter Share Radio Enable or disable the Twitter button

Enable Facebook Share Radio Enable or disable the Facebook button

Auto Clone of Component Radio ........................................ well... it MIGHT do something


Disabled

Stickiness of Component Radio The component can stick in the same position as the page is scrolled next to it. This should never be
Disabled enabled.

Order of Share Buttons Multifield Reorder the fields to reorder the Facebook and Twitter buttons.

342
Spark Slots
Spark Slots
Nickname
(s)

Purpose
Description
Spark want to be able to addd content to pages that comes from the CMS so it more difficult for ad blockers to identify and strip off the page.

Spark want to be able to add content to Sponsored Content in structured locations on the pages of a campaign using Snippets. These locations are known as Spark Slots and there are four of them on
the templates that they appear on.

Three of the slot are intended to display snippets in fixed location on the page (see screenshots below).

Spark Slot 4 was intended for Spark to be able to use to add a Sponsor'sReskin (essentially a background to the page delivered from the CMS rather than the Ad Server). It is phyically locally at the
very bottom of the page but it assumes that Spark will use CSS and javascript in there snippet to place its content wherever they like.

Inheritance

All of the Spark Slots inherit from parent to child across the main templates in the system. Typically Spark will set up a section page using a Hub template and set up the Spark Slots explicitly on this
page. Then all of the child pages that support Spark Slot will inherit from this source by default. From there they can cheery pick the pages they want to stop the inheritance on a page-by-page basis.

Also the parent page that has the explicit config can act the as source of inheritance but can be configured to not display the content on itself (see Hide on current checkbox).

Templates that support Spark Slots

Article 2
Bare
Cluster
Destination
Folder
Gallery
Hub
Topics
Travel Product - Hotel

Markup

Each new slot will have its own class name that will be rendered on the page even when empty. This is so Polar can also be used to inject content (the preference is to use the CMS so that ad blockers
cannot strip the content).

Interactions

Restrictions

Screenshot Template Spark Slot location image


(s)

Article 2

Gallery

343
Hub

Topics

Item Screenshot

Page properties

Spark Slot tab

344
Meta data for empty slots

Spark Slot location in


markup

345
Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Extend Spark Mar 11, May 18, Unassigned Gavin Kirk RELEASED Unresolved
4804 Embed Slots - 2016 2016 [X]
Apply to child
pages only
AEM- Extend Spark Mar 10, May 19, Unassigned Gavin Kirk TO Unresolved
4802 Embed Slots 2016 2016 [X] REFINE
to other
templates
AEM- Spark Embed Mar 09, Jun 15, 2016 Unassigned Gavin Kirk RELEASED Unresolved
4768 Slot 4 - slot at 2016 [X]
bottom of
page
AEM- Spark embed Dec 17, May 06, Andrzej Gavin Kirk RELEASED Unresolved
3838 slots 2015 2016 Dolinski [X] [X]
AEM- Spark Embed Dec 17, Mar 11, 2016 Unassigned Gavin Kirk TO Unresolved
3820 Slots 2015 [X] REFINE

5 issues

Other

346
Splitter
Splitter
Nickname
(s)

The Splitter is a component used to enable editors to place other components side by side when laying out a page.
Synopsis

The Splitter component is enables the editor to select the number of columns to split an area into and set the ratio of the relative sizes of the columns to each other.
Description
In the component config the columns as "slots" and the relative sizes of each are expressed as ratio to each other.

Interactions

Restrictions

Usage
instructions

Screenshot
(s)

347
Location

JIRA

Key Summary T Created Updated Due

OPI-249 Global Navigation - Improvement to the user experience Aug 23, Oct 04, 2016
2016
OPI-49 Global Navigation - Update and included connecting to Loyalty site Jun 17, Aug 31,
2016 2016
OPI-355 A new navigation item cannot be added to navigation config template Sep 29, Oct 20, 2016
2016
OPI-297 Add Premium link to the primary navigation in the TCUK homepage Sep 09, Oct 20, 2016
2016
OPI-391 Cannot login from global navigation on test8 Oct 17, Oct 27, 2016
2016
OPI-185 8.5) Easy of Navigation Aug 11, Sep 14,
2016 2016
OPI-539 Server Side Include (SSI) the whole Navigation Nov 03, Nov 03,
2016 2016
OPI-390 Logout clear cookie to fix global navigation Oct 17, Nov 03,
2016 2016
OPI-380 Server Side Include navigation links to login and registration Oct 13, Oct 20, 2016
2016
OPI-532 LoginRegistration/Subscribe top navigation links not displayed on home page on mobile Nov 02, Nov 07,
devices. 2016 2016
OPI-520 'Contact Us' page not displayed if navigated from Register page. Nov 01, Nov 01,
2016 2016
OPI-516 User navigated to akamai8 if tried to subscribe through rewards on Opium. Nov 01, Nov 02,
2016 2016
OPI-506 Registered User is able to view any premium article if navigated through My Account. Oct 31, Nov 01,
2016 2016
OPI-504 Incorrect icons on login page when user tries to log from global navigation level Oct 31, Jan 31, 2017
2016
OPI-184 Device access and ease of navigation Aug 11, Aug 11,
2016 2016
OPI-454 Styling issues on login and registration pages Oct 27, Nov 02,
2016 2016

348
OPI-397 Ring fence My Account look and feel Oct 18, Nov 02,
2016 2016
OPI-180 [aem] 8.1) Ability to view, list of current Newsletters I am signed up to Aug 11, Jan 31, 2017
2016
OPI-443 Unable to login and access my account Oct 26, Oct 27, 2016
2016
OPI-451 Premium articles can be seen after logging out (registered user) Oct 26, Oct 27, 2016
2016

Showing 20 out of 530 issues

Related
links

Other
FIX REQUIRED

At present the Sport pages use the Segment Container a lot and the original intention was that Splitters could be placed inside them to allow editors to layout the content in various ways desired by the editorial te
page then you are not able to add another into a Segment Container. As a work around in production when a Splitter is required in a Segment Container, DigiPub placed the Splitter underneath the Segment Con
functionality of the Segment Container can not be used because the content inside the Spillter is not actually inside Segment Container.

Refer AEM-4703 - Cannot add a Splitter into a Segment Container TO REFINE

349
Sponsor's Reskin
Sponsor's Reskin (also known as an Authored Reskin)
Nickname
(s)

Purpose
Description
Spark want to be able to add a reskin to a Sponsored Content (typically a sponsored section) that comes from the CMS so it more difficult for ad blockers to identify and strip off the page.

This kind of reskin allow Spark to add a single image that gets used as a background. The link can be configured with a link to the sponsor's site.

If Spark want to add a reskin that is not limited to being just an image then they can either do this be creating a snippet and adding it to Spark Slot 4 or liaising with Ad Ops and asking then to inject it via
Ad Server.

Inheritance

The Sponsor's Reskin is typically set up on a section page and then will inherit to all of its child pages.

Interactions

Restrictions

Screenshot
(s)

Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Reskin Mar 30, Apr 21, 2016 Blazej Tomasz RELEASED Unresolved
5118 configurable 2016 Kacikowski Niedzwiedz
when no [X] [X]
campaign ID
is set
AEM- Spark Embed Mar 09, Jun 15, 2016 Unassigned Gavin Kirk RELEASED Unresolved
4768 Slot 4 - slot at 2016 [X]
bottom of
page
AEM- Authored Dec 18, Jun 15, 2016 Andrzej Gavin Kirk RELEASED Unresolved
3846 reskin - 2015 Dolinski [X] [X]
structured
content
AEM- Authored Dec 17, Mar 31, 2016 Unassigned Gavin Kirk TO Unresolved
3822 Reskin 2015 [X] REFINE

4 issues

350
Other

351
Sponsored Content
Component

Sponsored Content
Nickname
(s)

Sponsored Content is content generated by Spark and third party advertisers for advertising campaigns. It is content rendered with sponsored labels (except in the case of sponsored pages) and
Description sponsored business component meta tags. Sponsored labels are required for legal reasons. In the context of AEM, this is a feature enabling the aforementioned to certain components that are also
customised in their look by way of logos, re-skinning and branding.

Please also see Sticky Branding for more detail about how to configure the sponsored logo to be 100% viewable (sticky).

The following components have the ability to be sponsored.

Sponsored sections
Spark will locate their client's commissioned content within a section that is usually placed within an Editorial channel. The section is usually created using the standard Hub template but
Spark will assign the Business Segment of "sponsored". Doing this will mean that this page and its children will all be sponsored content through inheritance.
Aviva for example is in the Cars channel at http://www.telegraph.co.uk/cars/road-safety/ (can be reached using the redirect URL http://www.telegraph.co.uk/aviva)

Old Mutual Wealth Series is in the Rugby Union http://www.telegraph.co.uk/rugby-union/old-mutual-wealth-series/

Articles - Spark will use AEM (rather than Authoring) to write the commissioned articles under the sponsored campaign section
Gallery - Spark will use AEM (rather than Authoring) to write the commissioned articles under the sponsored campaign section
Spark can set the campaign assets in the page properties (usually as the campaign section page) and these assets will inherit down through the child content making up the rest of the campaign
pages. The following templates have a "Sponsored" tab

Hub
Destination Template
Article 2
Gallery
Cluster
Topics
Folder (this is required so that Topics can inherit Sponsor assets from a Folder)

Code Overview

How to setup Sponsored Content? - the process of setting up a sponsored campaign is by populating the campaign id field

Configuration generation
Each component used the same configuration dialog which is accessible from edit and page properties in the site admin. This is enabled by component dialog.xml files using the following JSON in
cqinclude to create the configuration screen.
/apps/telegraph/core/commons/renderers/pageRenderer/tab_sponsored.infinity.json

The "infinity" selector above enables the the JSON tree to be accessed.

The Sponsored tab is defined by the tab_sponsored.xml, this uses tmgSponsoredTabPlugin.js, which is a custom made plugin catering for the enabling and disabling of fields in the
configuration screen. This is a self executable plugin that has the scope of the entire panel containing the Sponsored settings.

The complexity of the configuration panel is enabled by the listeners in the plugin, listening for events disabling or enabling field(s).

This functionality is related with certain Metatag implementations:


Interactions
Campaign id
Campaign start
Campaign end

Restrictions

Screenshot
(s)

352
353
Location /apps/telegraph/core/commons/renderers/pageRenderer/tab_sponsored.xml - the definition of the Sponsored tab shared by multiple dialogs

/etc/designs/telegraph/core/clientlibs/core-wcm/js/tmgSponsoredTabPlugin.js - the JavaScript responsible for the sponsored tab's dynamic behaviour

uk.co.telegraph.core.commons.sponsored.AbstractSponsoredPageData and sub-classes read the data regarding page sponsorship from the JCR and can be used in HTL files (search for
usage of sub-classes in HTML files, you can find examples of this in Article 2, Gallery and Hub renderers that are responsible for displaying the logo.), classes responsible for Metatags (ones related to
Campaigns)

The class responsible for displaying sponsored list items is uk.co.telegraph.core.foundation.list.sponsored.SponsoredStylingChecker, used by the various listItem.html scripts
(to understand how these map to list items, see the List documentation.

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Sponsored Sep 01, Nov 23, Unassigned Dave CLOSED Done
2208 Content 2015 2015 Sanders
Identification
AEM- Put sponsor Feb 01, Mar 22, 2016 Unassigned Melinda RELEASED Unresolved
4243 data in body 2016 Rogers [X]
of pages for
the Content
API
AEM- Confirm Oct 12, Nov 23, Richard Richard CLOSED Done
2860 Sponsored 2015 2015 Spence Spence
content
approach on
Film
AEM- Sponsored Sep 17, Jan 12, 2016 Unassigned None TO Unresolved
2495 content on 2015 REFINE
hub pages
AEM-68 Sponsored Apr 10, May 12, Melinda None TO Unresolved
Content 2015 2015 Rogers [X] REFINE
Compliance
(Cannes)
AEM- Display Jun 08, Jun 15, 2016 Unassigned Tomasz CLOSED Done
1013 sponsored 2015 Niedzwiedz
content in [X]
Galleries
AEM- Mark content Jun 08, Jul 23, 2015 Unassigned None CLOSED Done
1037 as Sponsored 2015
AEM- Remove May 12, Jan 14, 2016 Maciej None CLOSED Done
545 'Sponsored 2015 Panecki
by' content for
films auto
added to
curated lists
AEM- Design of Jul 30, 2015 Feb 04, 2016 Unassigned Patrycja RELEASED Unresolved
1779 sponsored Kurkowiak
content is [X]
broken when
page (for
Sponsor Logo
URL) is not
active
AEM- Sponsored Nov 11, Nov 23, Richard Richard TO Unresolved
3246 entity pages 2015 2015 Spence Spence REFINE
for content
API
AEM- Home Page Jun 03, Jan 14, 2016 Unassigned Patrycja CLOSED Done
969 (Film): the title 2015 Kurkowiak
is not [X]
rendering
proper
(sponsor
content) on
IE9, IE11
AEM- Sponsored Jul 30, 2015 Feb 04, 2016 Unassigned Patrycja RELEASED Unresolved
1780 content has Kurkowiak
incorrect label [X]
(text)
AEM- Add logo May 26, Feb 11, 2016 Lukasz None RELEASED Unresolved
812 /badge to all 2015 Graziowski
sponsored [X]
content article
pages
AEM- Add logo Jul 02, 2015 Aug 25, Unassigned None CLOSED Done
1431 /badge to all 2015
sponsored

354
content
channel hub
pages
AEM- New Sep 23, Dec 03, Unassigned Gavin Kirk RELEASED Unresolved
2597 sponsored 2015 2015 [X]
content meta
tag indicating
if campaign is
live
AEM- Sponsored Jun 10, Sep 24, Thomas None IN Unresolved
1088 content on 2015 2015 Hartwig REVIEW
hub pages
(UX)
AEM- Author can May 20, Jun 22, 2015 Unassigned Gavin Kirk RELEASED Unresolved
670 add content 2015 [X]
above the
main sidebar
content on an
article
AEM- Add logo Jul 07, 2015 Feb 04, 2016 Michal Marcin CLOSED Done
1488 /badge to all Boruczkowski Macioszczyk
sponsored [X]
content article
pages -
backend
AEM- Determine Sep 16, Nov 23, Richard Richard CLOSED Done
2483 how we 2015 2015 Spence Spence
present the
Sponsor of a
page to the
Content API -
In Escenic &
AEM - *-S-$$
AEM- Automatically Nov 09, May 16, Unassigned Richard TO Unresolved
3223 apply source: 2015 2016 Spence REFINE
sponsored
ticket to
sponsored
articles

Showing 20 out of 98 issues

Other

355
Component Properties
Name Type Description

356
357
Sponsored Lists
Nickname Sponsored Lists
(s)

Description List items need to comply with ASA standards so that the Telegraph do not get fined for non-compliance. Therefore list items that
appear on non-sponsored pages must advise the user that they link to a sponsored piece of content.

This is referred to as sponsored styling and includes replacing the datetime stamp with the word "sponsored" and adding a different
coloured background to the tile.

At time of writing this styling logic only works on the List and Curate List components. It needs to work on Curated List 2 before
Curated List can be deprecated (refer AEM-5276 - Curated List 2 not respecting sponsored list items logic CLOSED )

Interactions

Restrictions

Screenshot
(s)

Location

JIRA
Originally implemented under AEM-3498 - Sponsored List Items RELEASED

Fix Curated List 2 - AEM-5276 - Curated List 2 not respecting sponsored list items logic CLOSED

Future work for Promotions -


WEB-177 - Promotions business segment content to behave as per Sponsored business segment content RELEASED

Other The diagram below attempt to explain the logic of when a list item receives sponsored styling and when it doesn't. Basically if the list
item of a sponsored page appears on a non-sponsored page then is should receive sponsored styling, otherwise is does not.

358
WEB-177 - Promotions business segment content to behave as per Sponsored business segment content RELEASED will
extend this logic to pick up on the Business Segment of "promotions" to also have the sponsored styling. The diagram below explains
this updated logic to include both sponsored and promotions.

359
Sticky-Ad
Component

Sticky-Ad
Nickname
(s)

(currently updating...)
Synopsis

Description

Interactions

Restrictions

Screenshot
(s)

Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Sticky Ads Apr 27, Nov 17, Unassigned Gavin Kirk TO Unresolved
5540 2016 2016 [X] REFINE

AEM- Deprecate old May 19, Jun 03, 2016 Andrzej Gavin Kirk RELEASED Unresolved
5728 Sticky Ads 2016 Dolinski [X] [X]
AEM- Sticky Ads Jun 28, Aug 05, Unassigned Ian Curtis [X] CLOSED Done
6129 Styling Bugs 2016 2016
on iPad
AEM- Assist Ad Ops May 19, Aug 22, Unassigned Gavin Kirk CLOSED Done
5733 with CSS for 2016 2016 [X]
sticky Banner
transitions
AEM- Assist Ad Ops May 19, Jun 03, 2016 Simon Ward Gavin Kirk CLOSED Done
5732 with CSS for 2016 [X] [X]
sticky MPU
transitions
AEM- The ads are Aug 22, Aug 26, Unassigned Anna Dezor CLOSED Done
6529 not sticky 2016 2016 [X]
AEM- Add support Jun 28, Jun 29, 2016 Unassigned Sean Dillon TO Unresolved
6118 for including 2016 REFINE
geo-targeting
data for 'sticky
ads'.
AEM- Ads do not Jun 01, Jun 09, 2016 Andrzej Zeid Hadi [X] RELEASED Unresolved
5889 display on hub 2016 Dolinski [X]
pages
AEM- Sticky Ads not Jan 08, May 05, Unassigned Ian Curtis [X] CLOSED Done
3905 functioning 2016 2016
correctly
AEM- Spike[2days]: Jun 19, Jul 22, 2015 Unassigned None CLOSED Done
1229 Sticky MPU's 2015
on hub
template
AEM- Maxmizing - Jun 30, Jul 16, 2015 Unassigned None CLOSED Done
1393 tablets 2015
rotation from
vertical to
horizontal
AEM- User Jun 30, Jul 16, 2015 Unassigned None CLOSED Done
1398 experience on 2015
tablets
AEM- Minimizing - Jun 30, Jul 16, 2015 Unassigned None CLOSED Done
1396 tablets 2015
rotation from
horizontal to
vertical
AEM- Sticky MPU Apr 25, Jun 28, 2016 Andrzej Gavin Kirk RELEASED Unresolved
5504 on Article 2 2016 Dolinski [X] [X]

360
AEM- Front end: May 26, Apr 25, 2016 Unassigned None Unresolved
RELEASED
807 Sticky MPU's 2015
on article
template
AEM- Sticky MPU to Jun 30, Jul 27, 2015 Unassigned Patrick CLOSED Done
1413 support tablet 2015 Clancey [X]
browsers -
SPIKE
AEM- Stickiness on Jun 08, Aug 25, Unassigned None CLOSED Done
1039 logo / badge 2015 2015
AEM- SBoM - Sticky Apr 25, Sep 02, Simon Ward Gavin Kirk RELEASED Unresolved
5505 Banner on 2016 2016 [X] [X]
Mobile
AEM- Sticky MPUs Apr 17, May 26, Patrick None CLOSED Done
292 (Spike) 2015 2015 Clancey [X]
AEM- Management Apr 27, Dec 06, Unassigned Gavin Kirk RELEASED Unresolved
5539 of Ads models 2016 2016 [X]

Showing 20 out of 64 issues

Other

Component Properties
Name Type Description

361
Sticky Branding
Sponsored Content
Nickname
(s)

Sticky Branding is a way of making the sponsored logo stays viewable (becomes sticky) as the visitor scrolls down the page.
Description
The assets used (the label and logo) in a standard sticky branding implementation are the same ones configured for the Sponsored Content. The Spark editor just needs to check the Enable sticky
branding checkbox and the logo will become sticky as the user scrolls. This stickiness is usually configured on the section page and inherited down to articles.

The Spark editor can also add a Message Unit which bespoke HTML. This HTML is intended to appear the logo. Spark also have he ability to makethe Messaging Unit takover the sticky area. This has
the effect of making the label and log disappear leaving only the Messaging Unit. This takeover can be configured to take effect only after a specified number of pixel in scroll depth.

Examples:

http://www.telegraph.co.uk/cars/road-safety - Sticky on mobile only

http://www.telegraph.co.uk/property/online-estate-agent/ - Sticky on all breakpoints with a Messaging Unit

Interactions

Restrictions

Screenshot
(s)

362
363
Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

WEB-5 S2N - Jun 17, Apr 07, 2017 Unassigned Gavin Kirk CANCELLED Done
Updating 2016 [X]
sticky
branding
AEM- Up the Z Apr 13, May 06, Simon Ward Gavin Kirk RELEASED Unresolved
5322 index on 2016 2016 [X] [X]
Sticky
Branding to
9999
AEM- Sticky Dec 17, Apr 22, 2016 Unassigned Gavin Kirk RELEASED Unresolved
3824 branding & 2015 [X]
3rd party
script
AEM- Sticky Dec 17, Nov 24, Gavin Kirk [X] Gavin Kirk CLOSED Done
3815 Branding 2015 2016 [X]

4 issues

Example Message Unit button:


Other
Styles do not match those in Production (http://www.telegraph.co.uk/property/online-estate-agent) as classes are not present in Confluence. This is here to help understand what kind of content is placed
into a Messaging Unit not to copy is exactly.

Book a free property valuation

Example Message Unit HTML:

<a href="https://www.yopa.co.uk/property-valuation?utm_medium=partnership&utm_source=telegraph"
target="_blank" rel="nofollow" class="stickyButton">Book a free property valuation</a>
<style>
.stickyButton{
background: #cc6666;
padding: 10px 10px;
color: #fff;
top: 10px;

364
position: relative;
text-align: center;
}
@media (max-width: 440px){
.stickyButton{
line-height: 1;
font-size: 90%;
display: block;
top: 0;
}
}
</style>

365
Sticky Preview
Component

Nickname Sticky Preview, Fast Preview


(s)

Synopsis A button in the Sidekick that allows the user to quickly preview a page in WCM Mode Disabled and without loading the ads. Meant
as a quick preview.

Description A special preview mode that allows the user to quickly preview a page in WCM Mode Disabled and without loading the ads. Meant
as a quick preview. It's activated by adding two parameters, wcmmode=disabled and stickyPreview=enabled, to the query
string.

These two parameters cause three things to happen:

No authoring tools are displayed on the page. This is enforced by WCM Mode Disabled, an OOTB AEM feature that causes
the page to render on the Author instance in a way as similar to the Publish instance as possible.
No ads are displayed. This is caused by the stickyPreview parameter which, if detected, interrupts the lookup of
configuration required by the Advert component.
Every link on the page will be rendered with the additional wcmmode and stickyPreview query parameters. This allows the
user to navigate between pages without leaving this mode.

The mode can be entered by clicking the custom Fast Preview button in the Sidekick, on the Page tab.

One of the features disabled by Sticky Preview are the Metatags. The reason they are hidden in this mode is that they
take a very long time to render (up to 50% of the total page rendering time at the time of Sticky Preview's
implementation. As soon as Metatags are refactored to be more performant, they can be shown in Sticky Preview.

The MetaTagChannelSpecificConfig class extends ChannelSpecificConfigView which contains the toggle


based on the stickyPreview parameter.

Interactions

Restrictions

Screenshot
(s)

366
Location /etc/designs/telegraph/core/clientlibs/core-wcm/js/tmgStickyPreviewPlugin.js - adds the button to the
Sidekick

The code responsible for the custom rendering of the links is located in the uk.co.telegraph.core.foundation.
stickypreview package.

The code disabling the Ads when the sticky preview mode is enabled can be found in the class uk.co.telegraph.core.
commons.configuration.channelspecific.ChannelSpecificConfigView

JIRA AEM-4364 - Improvements to AEM Preview RELEASED

Other

Component Properties
Not applicable

367
Tag Mapping
Component

Tag Mapping Admin Interface


Nickname
(s)

The Tag Mapping admin interface in the Tools section ( /miscadmin ) enables the addition of tags manually or automatically. This is rendered in the form of a table of tag names and pages mapped to
Description
those tags.

The admin page is found at: http://<host>:<port>/etc/telegraph/admin/tag-mapping.html

The mapping can be applied in two ways:

Manually, by a person with access to the admin interface


By the OSGi service responsible for the creation of topic pages. When the OSGi service detects multiple instances of tags that have been replicated, it does a lookup on the tag mapping table, if
an entry does not exist, a new topic page is generated and a mapping between the tag and the newly created Topic Page is added to the table. If an entry already exists a new topic page is not
created and no new mapping is applied.

When manually editing existing mappings, it's only possible to change the page path. The tag determines the actual location of the coniguration entry in the content repository so to change the tag, one
must delete an existing entry and create a new one.

The table is actually represented as a tree with a structure mirroring that of the Topics tag namespace. Thanks to this, the lookup of a mapping for a given tag is as simple as looking up a specific
resource. No search is required. The structure is maintained in /etc/telegraph/admin/tag-mapping/jcr:content/topics in the repository.

Blacklisting Topics

A specific topic or tag is blacklisted by manually adding an entry with a tag without a path. This ensures a topic page is not generated. See screenshot in other section.

The page uses DataTables to display the mapping.


Interactions

This is a configuration page. It's deployed together with the CRX package and not created manually based on a template.
Restrictions

Screenshot
(s)

All code related to this feature is in the telegraph-component repository.


Location
/apps/telegraph/wcm/admin/tagMapping

/etc/designs/telegraph/core/clientlibs/tagmapping/js/tagMapping.js

/etc/designs/telegraph/core/clientlibs/tagmapping/js/jquery.dataTables.min.js

JIRA The mechanism was originally implemented in scope of AEM-777 - Tag Mapping configuration page RELEASED

The current interface using an updated content structure (flat list replaced with a tree) was implemented in scope of AEM-5339 - Refactor the tags mapping configuration RELEASED

For an overview of tickets related to the feature, see:

T Key Summary Assignee Reporter P Status Resolution Created Updated Due

PRB- Tag mapping Adam Gaudry Adam DONE Done Aug 03, Aug 30,
483 caused AEM Gaudry 2016 2018
to become
unresponsive
AEM- Refactor the Andrzej Tomasz RELEASED Unresolved Apr 14, Dec 07,
5339 tags mapping Dolinski [X] Niedzwiedz 2016 2016
configuration [X]
AEM- Duplicated tag Unassigned Jedrzej CLOSED Done Sep 01, Oct 02, 2015
2217 mapping Osinski [X] 2015

368
items
AEM- Improve Patrick Tomasz RELEASED Unresolved Nov 23, Apr 12, 2017
7087 content Clancey [X] Niedzwiedz 2016
loading UX on [X]
the Tag
Mapping page
AEM- Moved tags Unassigned Gavin Kirk CLOSED Done Nov 24, Jun 18, 2018
3421 are not [X] 2015
updated in the
Tag Mapping
AEM- Tag Mapping Unassigned Gavin Kirk RELEASED Unresolved May 22, Dec 07,
777 configuration [X] 2015 2016
page
AEM- Only allow Gavin Kirk [X] None CLOSED Done Feb 03, Jun 18, 2018
4275 topic pages in 2016
the Tag
Mapping Item
component
TRAN- Tag mapping Eleanor Hunt Tomasz DONE Done Nov 22, Nov 29,
106 page - [X] Niedzwiedz 2016 2016
business [X]
overview
AEM- Tag mapping Blazej Andrzej RELEASED Unresolved Jul 27, 2016 Aug 10,
6357 content is not Kacikowski Dolinski [X] 2016
refreshed [X]
after deleting
mapping
AEM- Tag mapping Unassigned Gavin Kirk CLOSED Done Nov 23, Jun 18, 2018
3406 path should [X] 2015
be optional
SD- Tags Mapping Unassigned Joe Jenkins CLOSED Done Apr 25, Apr 25, 2016
56709 page will not 2016
load
AEM- Enable quick Blazej Tomasz RELEASED Unresolved Jul 14, 2016 Aug 10,
6230 activation of Kacikowski Niedzwiedz 2016
Tag Mapping [X] [X]
configuration
WEB- tag mapping Nancy Gupta PJ Brett [X] RELEASED Done Apr 12, May 09,
2526 created when 2019 2019
topic creation
fails
AEM- Tag mapping Tomasz Andrzej CLOSED Done Aug 09, Aug 09,
6423 page is not Niedzwiedz Dolinski [X] 2016 2016
visible on [X]
AEM author
SD- AEM Tags Owen Tuz [X] Joe Jenkins CLOSED Done Apr 13, Apr 14, 2016
55542 Mappings 2016
page will not
load
AEM- User is able to Unassigned Andrzej READY Unresolved Jul 25, 2016 Jul 28, 2016
6315 provide more Dolinski [X] FOR DEV
than one tag
during
creating new
tag mapping
AEM- After Andrzej Andrzej RELEASED Unresolved Jul 28, 2016 Aug 10,
6361 removing tag Dolinski [X] Dolinski [X] 2016
mapping user
is navigated to
the first page
TRAN- BE - Tag Tomasz Omar Baig DONE Done Nov 21, Dec 12,
17 Mapping Niedzwiedz [X] 2016 2016
[X]
SD- AEM not John Molloy Ella Turner CLOSED Done Aug 03, Aug 08,
65160 allowing [X] 2016 2016
logins,
unresponsive
and slow to
publish
AEM- Tags order Unassigned Jedrzej RELEASED Unresolved Jun 08, Oct 02, 2015
1021 not clear Osinski [X] 2015

Showing 20 out of 247 issues

369
Other

The page has its own clientlib located in /etc/designs/telegraph/core/clientlibs/tagmapping (this should be refactored and aligned with other configuration pages such as
the Advert Management page)

Component Properties
Name Type Description

370
Topic Pages
Component

Nickname Topic pages


(s)

Description Business Overview

Topic pages are special pages that are used to aggregate and surface related content to visitors and search engines. Each topic
page related to a single topic tag. The lists on a topic page are configured to pull in any content tagged with the same topic tag.

For example the Chocolate topic page http://www.telegraph.co.uk/chocolate lists only articles and galleries that have been tagged
with the chocolate topic tag.

As far as visitors and search engines are concerned topic page are always directly beneath the Telegraph portal page. So from a
public standpoint they are never deeper in the Telegraph content structure than the first level (www.telegraph.co.uk/topic-name).

Creation of Topic pages

Topic pages can be created either automatically or manually.

Automatic topic pages are created when the topic tag has been used on three published articles (this threshold is actually
configurable in AEM but requires an AEM admin to change). The a page is published then the following check logic is run
to determine whether to create a new topic page;

The page is either an Article or a Gallery.


Cycle through the topic tags on the page.
If the topic tag does not have a Tag Mapping then proceed with the next check.
If publishing this page means the total number of published page containing the topic tag meets the threshold then
create and publish a topic page
Use the tag's name and title to determine the name and title of the topic page
Use the tag's location (namespace) to create the new topic page's location in AEM
e.g.: Tag = topics:things/chocolate >>> Topic page path = /content/telegraph/topics/things/c/chocolate
(note the "c" in this path is the first character of the tag name)
If this path will not be unique when shortened to appearing directly under www.telegraph.co.uk then the
category (namespace) is added to the title in brackets and after a hyphen in the name.
e.g.: Santander is both a bank and a place so the tags topics:organsations/santander and topics:places
/santander might exist for each. If the topic page for Santander the bank already exists then when the
topic page for the place is automatically created it will have the title "Santander (Places)" and the name
"santander-places" (leading to the URL www.telegraph.co.uk/santander-places).
If the path is still not going to be unique then the the disambiguation code with simply add the next available
numeral to the end of the title and name. When Digital Publishing become aware of this happening they
should manually update the title and name to something more suitable. If they do this they should ensure that
the tag mapping is also updated.
A Tag Mapping is created between the topic tag and the topic page.
A notification is sent to Digital Publishing alerting them that the new topic page has be created which details the
public facing URL, the content path and the tag that is responsible for creating it.

Manual topic pages

Digital Publishing may also want to create articles topics pages manually. This can be done in the AEM interface
but there are certain steps that need to be following for the page to behave correctly.
Create a topic tag (you will need to decide whether the topic belongs to Events, People, Places, Organisations,
Things or In The News and create it in the desired category).
Activate the tag.
The page must use the Topics template (either create new or copy and existing topic page).
The page must be located in a node that has been set up with URL rewriting. This is so that the content path is
hidden from the URL.
So if you want to set up a topic page for Widgets, then you might place this in /content/telegraph/topics/things
/w as this node is already configured to rewrite the URL of any page within it.
Activate the topic page.
Set up a new entry in the Tag Mapping (/etc/telegraph/admin/tag-mapping.html) which maps the new topic tag to
the new topic page.
If you neglect to set a mapping then a duplicate topic will be created when the tag usage threshold is hit.
Activate the Tag Mapping page.

Branded topic pages (also called Channelised topic pages)

Thus far we have been talking about Generic topic pages but some channels want to own certain topic pages. For
example Football want to own the Arsenal and other team pages. To meet SEO goals these pages should still

371
have a top-level URL (e.g.: www.telegraph.co.uk/arsenal-fc) but the Sport desk was to benefit from the advertising
revenue gained on them and also to have consistent Sport branding so that visitors feel like they belong to the
Telegraph Football channel.
For ease of management then the branded topic pages were set up within the channel so that they inherit the
channel styles, section navigation and Business Segment to drive advertising and revenue attribution.
For all branded topic pages in Sport channels a new structure was set up within each channel that has then
(only a few of the bigger channel do). Essentially two new folders were created and each was added to the
URL rewriting configuration. For example:
/content/telegraph/football/topics/teams
/content/telegraph/football/topics/competitions
Any page then created in these folders will have it URL shortened to www.telegraph.co.uk/page-name but
unlike generic topic pages it will inherit the channel styles, section navigation and business segment.
Once the page has been created you must ensure that you have created a matching topic tag. This should be
located in the usual topic tag structure.
You must also create a Tag Mapping between the topic tag and the topic page otherwise the duplicate topic will be
created in the generic topics area when the tag usage threshold is hit.
Examples of Branded Topic pages are:
Arsenal - www.telegraph.co.uk/arsenal-fc/ (content path = /content/telegraph/football/topics/teams/arsenal-fc)
Premiership - http://www.telegraph.co.uk/premiership/ (content path = /content/telegraph/rugby-union/topics
/competitions/premiership)

URL rewriting

Topic pages are special pages that have been automatically generated by the use of tags. Tags enable the categorisation of
content in pages. The setting of tags is created in tagging mapping page - which is a separate interface.

Editors can also create Topic pages manually using the Topics template. In order to ensure the URL is rendered as a top level
(rather than the full path) the editor must put the page in a folder that is set up with URL rewriting.

Use of say the same tag on multiple pages causes Topic pages to be automatically spun up. There is an OSGI services that
listens to the frequency use of tags that have been replicated.

Topics are accessed via

Clicking on the links at the bottom of a pages in the Read More About section
For known tags, via a URL: http://www.telegraph.co.uk/chocolate

Pages that have been tagged only have their tags rendered if the respective Topic pages exist.

In the repository, topic pages are found in the path for example for chocolate:

/content/telegraph/topics/things/c/chocolate

This path shows that topics are categorised alphabetically.

To learn more about how this has been implemented, read Topic Page URL resolution

Topic pages use their own template.

Code Overview
Sling job mechanism is used to enable asynchronous jobs to automatically create Topic pages in the Telegraph/topic root folder.
The job is initiated by Replication events - the OSGI Event handler interface is known as AutomaticTopicsHandler class.

OSGI job input properties are:

1. Minimal tag count value - this is threshold - currently set at three, if there or more instances are found, topic page is created
and activated
2. Enables automatic creation of topics pages
3. Enables notifications for newly created topic pages
4. Enables activation of created topic page
5. Enables activation of tagsMappingPage
6. Queue listened to for Topic Event Action, which has changed previously

4 and 5 are linked.


The AutomaticTopicsHandler uses the ResourceResolverFactory, which allows for authentication using different setting to gain
access the OSGI Service (not using the credentials in the HTTP Request)
The job is consumed by AutomaticallyJobsConsumer. This creates the Topic Page if required, the Tag Mapping location and
activates them.

OSGi user access config found at:


/apps/telegraph/configuration/config.author/org.apache.sling.serviceusermapping.impl.
ServiceUserMapperImpl.xml
XML file represents OSGi config with user settings.

Interactions The Dispatcher dynamically whitelists topic pages, as described here.

372
Restrictions

Screenshot
(s)

Location For automatic Topic Java code go to code in telegraph component

Topic pages are based on the Topic Template

JIRA

Other The List of Tags component used on articles displayed topic tags (only if the tag is mapped to a published topic page). Tags can
be used by visitors to navigate to the topic page where more articles and galleries are lists about the same topic (tagged wit the
same topic tag).

Component Properties
Name Type Description

373
Topic Page URL resolution
The current implementation opens the error page to an DDoS attack. When an non-existing page is requested, the resource resolution will
iterate over each of the entries in the sling mapping. This traversal is slow and hits the repository frequently. The following ticket will improve this
situation and resolve a different bug (AEM-6884)

The URLs of Topic pages look the same as if they were Channel or Cluster pages (direct children of the /content/telegraph resource in the content
structure). The pages themselves are actually placed deeper in the content tree, with most of the Topic pages residing under /content/telegraph
/topics in alphabetical buckets belonging to specific topic categories.

For example:

http://www.telegraph.co.uk/bacon/ is actually the page from /content/telegraph/topics/things/b/bacon


http://www.telegraph.co.uk/chocolate/ is /content/telegraph/topics/things/c/chocolate
http://www.telegraph.co.uk/stephen-hawking/ is /content/telegraph/topics/people/s/stephen-hawking

It's also possible for some channels to have in-channel topic pages. This is particularly common among Sport channels which conventionally have up to
two topic categories, Teams and Competitions. For example:

http://www.telegraph.co.uk/arsenal-fc/ is actually located in /content/telegraph/football/topics/teams/arsenal-fc


http://www.telegraph.co.uk/fa-cup/ is /content/telegraph/football/competitions/fa-cup

The URL mapping is achieved by the Sling Mapping mechanism, controlled by the JcrResourceResolverFactory OSGi configuration (see src/main
/cq/jcr_root/apps/telegraph/configuration/config.publish/org.apache.sling.jcr.resource.internal.
JcrResourceResolverFactoryImpl.xml in telegraph-component). A comprehensive overview of the feature can be found on this blog.

The configuration can be viewed in the OSGi console, in the Configuration section (/system/console/configMgr)

The mappings provided in the existing XML configuration file are two-way. They affect both resource resolution and resource mapping. That is, a request
to /arsenal-fc will get resolved to /content/telegraph/football/teams/arsenal-fc and a the resource resolver will also be able to map any
link to /content/telegraph/football/teams/arsenal-fc to /arsenal-fc. This affects the Externalizer so there's no need to manually map
links that are rendered in elements/attributes already covered by it.

Additionally, the topic paths need to be whitelisted in the Dispatcher Filter configuration. While topics are fairly static and a list of them can be maintained
manually (see the channel list in dispatcher.rb in the tmg-aem repo containing Chef recipies for AEM environments and publish-filter.inc.erb)
, topic pages can be created automatically so they need to be allowed in a more dynamic manner.

To work around this, the Dispatcher config uses a feature originally intended for Vanity URLs, as seen in publish-vanity.inc.erb in tmg-aem. The
path indicated by the /url parameter points at the DispatcherFilterServlet implemented in telegraph-component. The servlet returns a list of
all topic pages currently in existence and allows the dispatcher to white-list them. The /delay parameter specifies how often (in seconds) the servlet
should be polled for an up to date list. The list gets cached on the Dispatcher at the path specified by the /file parameter. See the AEM Dispatcher docs
for more information.

374
Topic tag
From a business perspective a topic tag is defined as a tag that describes the aboutness of a page. Authors will add these tags to article and galleries. If
the topic tag has a Tag Mapping configured then it will appear in the List of Tags component which will provide visitors with an onward journey to the
relevant topic page.

From a technical stand point a topic tag is defined any tag in AEM that is within one of the sub-categories of the Topics namespace (Events, In the news,
Organisations, People, Places, Things).

Note that although "Topics" and all of its sub-categories above are in fact AEM tags and can technically be used to tag pages, these are not regarded as
topic tags. The Topics namespace and the sub-categories have been set up to categorise the tags and assist authors with disabiguation.

When setting up a new topic tag Digital Publishing should consider carefully which sub-category (location) to place the tag in and choose its Name and
Title with care also. This is because these are all used in the automatic creation of Topic Pages.

375
Topic Template
Component

Nickname Topic Template


(s)

Description Topic Template is used in the automatic and manual generation of Topic Pages. The Topic Renderer renders the page using the
Page Renderer.

Interactions

Restrictions

Screenshot
(s)

Location

JIRA /apps/telegraph/core/commons/templates/topicsTemplate (code in telegraph-component)


/apps/telegraph/core/commons/renderers/topicsRenderer (code in telegraph-component)

Other

Component Properties
Name Type Description

376
Video Player - Ooyala Updates
Following the Video Improved Player project, we have upgraded the Ooyala video player from V3 to V4. As a result, we are now hosting the video player
ourselves and are responsible for the maintenance of the player. Ooyala will regularly release updates to the video player and we will be responsible for
applying these updates to our video player. Ooyala will issue releases notes with every release and based on what is included in the release, it will be
determined by the business whether to update the video player or not.

Step-by-step guide
1. Ensure you are subscribed to the Release notes to be notified when a release is available and what is included. Follow the instructions at: http://he
lp.ooyala.com/video-platform/concepts/release_notes_subscribe.html

Background info on the project here

Related articles
AEM Core - Current release process
Creating a new Channel
How to configure Reg Walls in AEM
How to add HTML Embed in Global Navigation
How to configure Mid-Article Unit for content via LiftIgniter

377
Video Player - Relevant Recommendations &
Autoforwarding
The relevant recommendations and auto-forwarding feature was implemented on to the TCUK website to surface relevant content to entice readers to view
more videos. When a reader reaches the end of a video, the video player will auto-forward to the next video that has been surfaced as a relevant
recommendation. Three sets of rules have been implemented to determine what would be the relevant content; Series, Sponsored, Standard.

Step-by-step guide - Series


This rule set would be applied to videos which belong as part of a series (e.g. http://www.telegraph.co.uk/food-and-drink/video/john-whaites-5-ingredient-
recipes/). Applying this rule would surface the other videos in the Series as the relevant recommendations

1. Create the article page


2. Place the video component on to the page
3. Via the AEM instance, open the Page Properties dialogue box
4. Go to the "Video" tab
5. Set the Series Home Page path to the Series home page.

For Series and Sponsored videos, if the path has been set incorrectly, the JSON which retrieves the relevant recommendations will return empty and no
auto-forwarding will occur. Instead the end screen will be displayed with the replay button.

When the reader reaches the end of watching the list of relevant recommended videos, they will be presented with the end screen with the replay button.

Step-by-step guide - Sponsored


This rule set would be applied to videos which belong as part of a Sponsored campaign (e.g. http://www.telegraph.co.uk/money/transferwise/).

Applying this rule would surface the other videos in the specified campaign as the relevant recommendations

To apply this rule set to a video:

1. Create a new article page


2. Complete the page as you would for a series article
3. Configure the video player component by right-clicking and selecting “Edit” (this can only be done via the AEM instance and not the Authoring
Tool)
4. Go to the "End Screen" tab
5. Set the Search Path to the campaign home page.

378
Note: if both paths have been set for Series and Sponsored videos, the Series path would take priority and the videos from the Series would be surfaced
as the relevant recommendations.

For Series and Sponsored videos, if the path has been set incorrectly, the JSON which retrieves the relevant recommendations will return empty and no
auto-forwarding will occur. Instead the end screen will be displayed with the replay button

When the reader reaches the end of watching the list of relevant recommended videos, they will be presented with the end screen with the replay button.

Step-by-step guide - Standard


This rule set would be applied to all other videos that are not part of a Series or a Sponsored campaign.

Applying this rule would surface current trending videos on the TCUK website as the relevant recommendations. This is achieved using the Ooyala
Discovery platform.

To apply this rule set to a video:

1. Create a new article page


2. Complete the page as you would for an article, including a video player
3. Ensure the Series Home Page and the Search Path have not been set

To manage the Ooyala Discovery API:

This is located at /system/console/configMgr

Limit: the maximum limit on the number of videos to surface as relevant recommendations
Window: the window of time to identify what is trending
Discovery URL: Ooyala Discovery has 5 different APIs to determine what video to play next. We are using the Trending API

The API call will use the API key and signature to call TMG’s Discovery. This ensures that only TMG videos would be returned. A checkbox has also been
added to OSGI configuration for the video player component to enable/disable the auto-forwarding functionality should it be required.

When the reader reaches the end of watching the list of relevant recommended videos, they will be presented with the end screen with the replay button.

Click here for more background information about the project.

379
Related articles
AEM Core - Current release process
Creating a new Channel
How to configure Reg Walls in AEM
How to add HTML Embed in Global Navigation
How to configure Mid-Article Unit for content via LiftIgniter

380
Components tracking
Note - Copied from Cheetah 'Components Tracking' and updated (Cheetah - Spreadsheet here)

Page Components
Overall Spec status = 9/13 = 69%

Overall Build status = 6/13 = 46%

ID Name Description Status Specified Link to Epic Product MVP Built Due
Component Owner
Overview

T1 Article Main article DELIVERED YES YES Deliver


Page view created ed
based on a
template, and
using 1 one or
more
components e.
g. Image,
Headline, Body
Copy etc

T2 Navigatio Menu of DELIVERED YES YES Deliver


n menu telegraph.co.uk ed
sections that
reader can
navigate
through to
select the
section they
wish to view

T3 Header Strip that DELIVERED YES NO


appears along
the top of the
web page
frame to
display data
that is common
to all pages on
the site, such
as date, logo &
search function
box

T4 Footer Strip that NOT STARTED NO NO


appears along
the bottom of
the web page
frame to
display data
that is common
to all pages on
the site, such
as copyright
data, contact
information,
and links to the
privacy
statement and
the terms of
use.

T5 Breadcru Assist readers IN PROGRESS NO NO


mbs navigate the
telegraph.co.uk
site - by
displaying the
sections
selected by a
reader to arrive
at a site
location.

For example: H
ome>Culture>
Comedy>Com
edy News

T6 Review DELIVERED YES YES Deliver


CCORE-177 - Create
Page ed
a structured review
TO DO

T7 Section Home page NOT STARTED NO NO


Page view of a
section of

381
telegraph.co.uk
(e.g. Luxury,
Fashion etc)
displaying a list
of articles,
adverts etc

T8 Author Author DELIVERED YES YES Deliver


Page biography - ed
page
containing
details of an
author - name,
photo, job title,
email address
and a list of
articles created
by the
specified
author. The
reader can
select to view
the author bio
page by
selecting the
URL link
displayed as
the author
name (author
ID component)
within any
article on
telegraph.co,
uk.

T9 Login / IN PROGRESS IN PROGRESS NO Q3


CCORE-745 - Respon
user 2014
status sive login component - MVP
box TO DO

T10 Gallery A collection of DELIVERED YES YES Deliver


images that a ed
reader can
scroll through e.
g. Pictures of
the Day.

T11 Shanghai A home page DELIVERED YES Ed Keohane YES July


CCORE-757 - Everythi
homepage template that 2014
lists ng required for Shanghai
comparison home page v1 DONE
page templates

T12 Shanghai A page that DELIVERED YES Ed Keohane YES July


CCORE-752 - Everythi
comparis compares 2014
on page products ng required for Shanghai
comparison page v1
DONE

T13 Shanghai A page that DELIVERED YES Ed Keohane YES July


CCORE-750 - Everythi
Product presents a 2014
Page product review ng required for the
Shanghai product page v1
DONE

T14 In line The ability for IN PROGESS Liane Katz In progress Sept
content authors to add 2014
various content
types in line
with text

T15 Data A topic page NOT STARTED Jon Attard


driven that is created
topic from a
page FactMint
ontology and
related entities

Content Components
Overall Spec status = 17/20 = 85%

Overall Build status = 14/20 = 70%

ID Name Description Status Specified Link to Component Product MVP Built Due Owner Comments
Overview Owner

CC1 Headline Primary DONE YES YES


headline on a

382
full article page
displays a very
high level
descriptive
summary of the
article so the
reader can see
at a glance
what the article
is about

CC2 Standfirst Standfirst DONE YES YES


component is
an introductory
paragraph in
an article page
which
summarises at
a lower level
than the
primary
headline the
detail of the
article it is
contained within

CC3 Abstract Abstract DONE YES YES


component
displays a
summary about
the article
when viewing
the article list
on a section
page. There
are two types
of abstract
components
that can be
displayed
against each
article within an
article list on a
section page:

Long
abstract
summary
Short
abstract
summary

CC4 Label ?? A URL link DONE YES YES


within an article
written as a
short keyword
that redirects a
reader to
another article
or area of the
telegraph.co.uk
site

CC5 Date Capability to DONE YES YES


/Time apply a date
and time stamp
to an article
confirming the
publish date
and time of a
static article

CC6 Author ID Author ID DONE YES Author Content (ID) YES


component Component Requirement
contains the Overview
author's details
(name,
location, photo,
e-mail address
job title
etc). This
component can
then be used to
add the author
details to an
article
providing a link
to the author's
page (see
author page
component
page for details
of the page
component)

CC7 Image Image related DONE YES YES


to an article
displayed

383
within the
article (at top of
article and not
within body
copy text - see
Inline Image)

CC8 Body Allows text to DONE YES Body Copy Component YES
copy be added and Requirement Overview
edited in the
main body of
an article
component

CC9 Related DONE YES YES


assets

CC10 Table DELIVERED YES NO

CC11 Inline Image related DONE YES YES


image to an article
displayed
within the body
copy text of an
article

CC12 Gallery A collection of DONE YES YES


images related
to a theme e.g.
Rugby world
cup, that a
reader can
scroll through e.
g. telegraph.co.
uk has a
"Pictures of the
Day" gallery

CC13 Sharing Capability for DONE YES YES


readers to
share an article
on social
media sites e.
g. Facebook,
LinkedIn,
Twitter etc. via
an icon
displayed
within the article

CC14 Comments Capability for NOT STARTED NO NO


readers of an
article to leave
comments on
an article and
share with
other readers

CC15 Related List of articles DONE YES YES


content related to
another article
displayed
within the
article being
viewed

CC16 List Article List - DONE YES NO


article
summaries
displayed on a
section page -
article
summary
headline and
summary
(abstract)
displayed

Wide variety of
article lists
utilised across
the TCUK site
e.g. "Most
Viewed", "Top
5", "Most
Commented",
"Editors
Choice" etc

CC17 Compare Capability to DELIVERED YES Ed Keohane YES Q3


CCORE-738 - Product
compare 2014
products within Comparison component
a product DONE
family defined
in an entity
definition

CC18 Structure Capability to IN PROGRESS YES Ed Keohane IN PROGRESS Q3


d Data read and write 2014

384
structured data
CCORE-506 - Structur
from and to the
Data Hub via ed data that is useful to the
Nitro API reader or experience
CANCEL

CC19 Video Video player IN PROGRESS NO Ed Keohane IN PROGESS Q3


2014

CC20 Call to Capability to DELIVERED YES Ed Keohane YES Q3


CCORE-698 - Shangh
action click a button 2014
that takes the ai - Create action block
reader to an DONE
external link
without CCORE-839 - Function
demoting the ality required for call to
site SEO DONE
action

CC21 Search Reader facing NOT STARTED NO


component to
enable
searching via
topic, article,
entity within
AEM and
Factmint.

Commercial Components
Overall Spec status = 2/2 = 100%

Overall Build status = 2/2 = 100%

ID Name Description Status Specified Link Product MVP Built Due Owner Comments
to Owner
spec

AD1 Lower Inserts a single ad DONE YES Lower YES


instream container into the and
page content (second Upper
in page flow) instream

AD2 Upper Inserts a single ad DONE YES Lower YES


instream container into the and
page content (first in Upper
page flow) instream

385
How-to articles
Add how-to article

Title Creator Modified

AEM Core - Current release process Unknown User (hegartyi) Oct 21, 2019

Creating a new Channel Yadvinder Chauhan Apr 13, 2018

How to configure Reg Walls in AEM Mark Cyrson Apr 10, 2018

How to add HTML Embed in Global Navigation Unknown User (baigo) Jan 17, 2018

How to configure Mid-Article Unit for content via LiftIgniter Mark Cyrson Dec 18, 2017

New Developer Application Setup 2 Unknown User (baigo) Oct 26, 2017

Configure clientlibs Unknown User (paneckim) Aug 24, 2017

Optimizely and ESI Switches Unknown User (weedonv) Jul 18, 2017

New Developer Setup Jan Kuzniak Jun 15, 2017

How to Analyse Performance Test Results Zubair Hasan May 10, 2017

Running tests in Bamboo Unknown User (taylorju) Mar 23, 2017

Rebuild AEM CI environment Unknown User (pikalat) Mar 21, 2017

Investigate test failures Unknown User (pikalat) Mar 17, 2017

Check browser console log Unknown User (pikalat) Mar 17, 2017

Running tests in command line Unknown User (goszczynskim) Mar 17, 2017

Setting up Livefyre Comment feature on Localhost Unknown User (ajojeo) Feb 07, 2017

Understanding application configuration pages Unknown User (niedzwiedzt) Dec 14, 2016

Ad Blocker Message Unknown User (kirkg) Dec 12, 2016

How to Flush Content on Secure 8 Unknown User (niedzwiedzt) Nov 28, 2016

Component Validation Unknown User (niedzwiedzt) Nov 28, 2016

Find more results

386
Ad Blocker Message
When visitors to the site are using an ad-blocker then we display an overlay message that attempts to persuade them to switch it off as adverts are a major
source of funding for TMG. The ad blocker message can be closed and the visitor can continue to browse for and read content unimpeded.

Only certain ad blockers were targeted to show the message if they are in use. These are:

AdBlock
AdBlock Plus
Adguard AdBlocker
uBlock Origin

Ghostery was also requested by the business in the initial scope but was rejected as it is not really an ad blocker.

The ad blocker message appears shortly after the page loads as an overlay. The user can then either go to a help page to learn how to whitelist the
Telegraph or simply close the overlay. Once the visitor closes the overlay they it will not reappear in their current session. It will be displayed every time
they come back to the site (in a new session) while their ad blocker remains on and the Telegraph is not whitelisted.

Note

It is an accepted risk that ad blockers may update their code and circumvent this ad blocker message. Should this happen the business will
need to make a call as to whether it is worth entering an arms race with the writers of ad blockers.

Step-by-step guide

Turn off your Ad Blocker if you have one running in your browser If you leave it on you will not be able to see the configuration of the Ad
Block Message component when you open it to edit it.
Go to the Advert Management page in the Tools area of AEM (/etc/telegraph/admin/advert-management.html)

Right click on the Ad Blocker Message component and select Edit

In the Configuration tab you can add/edit the text content in the richtext editor.
Look at the text upto the words .... Thank You (that is how much is available to edit and be displayed in the final page). There is some text that
appears on the live page after this that is hard coded.

In the Image tab you can set the path to the image being used by the Ad Blocker Message and the image alt text.

387
Click the Preview button to see what the message ill look like to visitors.
This open the overlay over the Advert Management page. Use the Close link to close the overlay and get back to the Advert
Management page.
Click the OK button on the Ad Block Message component to save your changes
Activate the page to make your changes available to visitors.

JIRA stories

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Extend ad blocker Sep 23, Nov 15, Andrzej Tomasz RELEASED Unresolved
6749 message configuration 2016 2016 Dolinski [X] Niedzwiedz
[X]

AEM- Feature switch for Ad Sep 09, Nov 15, Grzegorz Gavin Kirk RELEASED Unresolved
6626 Blocker Detected 2016 2016 Bednarski [X] [X]
message

AEM- Ad Blocker detection & Jul 15, Nov 22, Grzegorz Gavin Kirk RELEASED Unresolved
6236 message 2016 2016 Bednarski [X] [X]

3 issues

Ad Blocker Message

388
Adding content, javascript or CSS to a page using the
HTML Embed
If the HTML embed component is going to be used you must adhere to the following instructions:

Scripts and CSS must be included using one of 2 methods

Option 1

Recomended method

Lazy loaded HTML is the recommended method.

Leave 'Lazy loaded' option enabled, and then include the script/css using normal <script> OR <link> tags.

The entire contents of the html embed will not appear in the DOM (or be initialized) until the user scrolls within 1 viewport's height (configurable in the
code) up or down.

Option 2

Not in html mode!

This technique will not work if lazy loading is selected, clientlibs will not initialize!

If you know what you are doing you can load your css or scripts via clientlibs.

Make sure 'Lazy load' is unticked.

Inject your scripts/css into our 'clientlib' object, which gives you the added bonus of dependency injection!

389
If you always use the same namespace for your similar embeds, you can be sure that you will not be including duplicate scripts/css, as you will always
override it.

If you have a single dependency of one library for everything (eg. greensock) you can inject it in its own namespace.

ALWAYS test for a script/library (by checking for its primary object) - That way if someone else has already included it, you don't load it again!

window.clientlibs.js.myNameSpace = {
test: "document.querySelectorAll && !document.querySelectorAll('.myNameSpace').length",
load: ["//s3-eu-west-1.amazonaws.com/widget.cloud.opta.net/2.0/js/widgets.opta.js"]
};
window.clientlibs.css.myNameSpace = {
test: "document.querySelectorAll && document.querySelectorAll('.myNameSpace').length === 0",
load: ["//s3-eu-west-1.amazonaws.com/widget.cloud.opta.net/2.0/css/widgets.opta.css"]
};

Never extend beyond the bounds of the component itself


Be careful of:

Animations
Offset text
Position 'fixed' and 'absolute'
Negative margins

In some cases scripts might be used to inject into the DOM elsewhere or create overlays for example. This type of 'takeover' should always be agreed with
Product in the first instance.

Never log to the console unless in 'debug' mode


Always add a flag to switch debug on and off if you need to log to the console. Suppress logging if set to off.

Content must be responsive - always test down to 320px and make sure everything still works
We recommend having all content flex liquidly. Add media queries if necessary.

Always code defensively


If you are expecting an object/value to exist, do not assume it does, ALWAYS test for it first, wrap your code in conditionals.

Only expect JQuery and Hammer JS as dependencies


Everything else should be included as your primary js/css files.

Always optimise your images, and make them responsive

390
Blacklisting
Nickname Blacklisting, Blacklist tag
(s)

Description To assist with the launching on new channel a mean of hiding published content from list on live channels was needed. The Blacklist
tag and a two of groovy scripts where created for this.

The Blacklist tag is a Structure tag (a tag in the Structure namespace). In this regard there is nothing special about the tag it is simply
that this name and location of the tag were agreed with DigiPub so that everyone knows the correct tag to use.

When launching a channel the editors are called upon to pre-populate it with published articles while it is still hidden from the public by
WebOps. The problem arises that it then becomes possible for the published articles of the hidden channel to appear in the lists on
channels are are publicly accessible. So if a visitor was to click on one of these list item or is a search engine was to crawl it then the
link would 404.

To get around this we add the Blacklist to the Exclude tags field in all of the Lists that are on live pages AND add a Blacklist tag to
every article in the hidden channel. There are groovy scripts that have been created for this purpose. A developer would need to
configure the scripts to run on the correct channels for running them.

When the channel goes live (is no longer hidden from the public) then the Blacklist tags are removed the the articles and galleries of
the new channel (again there is a groovy script for this).

Note the Blacklist tag in the Exclude tags field is left in place for subsequent launches.

Interactions

Restrictions

Screenshot
(s)

Location
1. scripts/groovy/AEM-4021-hide-non-live-pages-on-lists.groovy

2. scripts/groovy/AEM-4021-add-non-live-tag-to-pages.groovy

3. scripts/groovy/AEM-4021-remove-non-live-tag-from-pages.groovy

JIRA AEM-4021 - Hide Business, Money, News & Science channels from lists until they launch RELEASED

Other

391
392
Bulk Tag Upload
The following describes the procedure to bulk import tags from a CSV file;

References
Adobe video instructions: https://adobe-consulting-services.github.io/acs-aem-tools/tag-maker.html
ACS AEM Tools download: https://github.com/Adobe-Consulting-Services/acs-aem-tools/releases
Example of previous spreadsheet with tags correctly formatted to export to CVS and upload to AEM - https://docs.google.com/a/telegraph.co.uk
/spreadsheets/d/16dKCdqQ4SDyb6IXRtnNgptplaY3f3iqN-WZDgk3T8LE/edit?usp=sharing

Procedure
1. Announce a 1 hour downtime of Authoring (TO BE VERIFIED)
2. Download the CSV files containing tag definitions
3. Open the Tag Maker tool (http://<aem_host>/etc/acs-tools/tag-maker.html)
4. Select the Primary converter as Title {{node-name}} and the Fallback converter as Default (Normal AEM Node Naming)
5. Open the CSV files in a text editor and make sure the separator is a comma. The separator can differ depending on the tools you used to open
and save the CSV files and the locale of your system. The default separator in the Tag Maker is a comma.
6. Open the tag_import_settings_used.png file enclosed with the RFC and confirm that your settings match the screenshot
7. Upload the CSV files one by one - READ ALL OF THE SUB-STEPS BEFORE EXECUTING
a. The CSV File field in the Tag Maker is a file chooser, use it to select the file to upload.
b. After selecting the file, click the blue Make Tags button and wait for confirmation.

Processing a large number of tags may take a long time.

c. Selecting another file in the CSV File field and clicking the Make Tags button again will make the output of the previous import
disappear.
d. The order of import should not matter but it's prudent to import a small file first and get familiar with the interface. During a trial on Demo,
the files were imported in the following order. Approximate number of tags and times taken to import on Demo in square brackets:
8. Confirm the presence of Sport tags in the AEM Tagging interface - http://<aem_host>/tagging
9. Confirm that Authoring works.
a. Open http://<aem_author_host>/etc/telegraph-author/index.html and see if a list of articles appears
b. Open an article and try adjusting an image crop
c. If the image crop is applied, everything works fine. If it's not, try restarting the instance. If this fails, contact an Authoring developer.
10. Announce the end of Authoring downtime

393
Business Segment
Context
Ad Ops want every page of the site to have a Business Segment it belongs to rendered as a meta tag in the head of the page (e.g: <meta name="tmgads.
businessSegment" content="portal">). There is centrally managed list of business segments in AEM and a channel (or any page) can be linked to a
business segment via page properties. A meta tag can then be configured for the channel in question to include the business segment meta tag on pages.

The Business Segment also drives the logic of whether list items promoting sponsored pages is shown as sponsored or not. If a list item that points to a
sponsored page appears on a sponsored page then it does not need to call out that the target page is sponsored. However if a list item that points to a
sponsored page appears on a page that is not sponsored then it does need to call out that the target page is sponsored.

To have the business segments defined for AEM we need to:

Administering Business Segments List


1. The business segments list is centrally managed in AEM. To view/edit the list entries, either access via URL http://{AUTHOR ENV}/etc/telegraph
/admin/business-segments.html or alternative you can find the page under Tools - Telegraph - Admin Tools. Double click the Business Segments
page to edit/view it.

2. You can now add new items into this list. Please fill in both the Title and Value for each item. Localised values are not used at the moment so no
need to fill those fields. Take care when editing existing values - if you update the Value it's a good idea to make a note of the ones you have
changed (you will need it in step 5). Same applies if you delete any of the existing entries. Once ready, activate the business segment page.
Note 1: It is not advisable to add duplicate entries to the list since this means users will also see multiple values in the dropdown (step 4) and it
will be confusing.
Note 2: Please always fill in both the Title & Value fields. The only exception to this is the empty value explained below.

3. By default, this list should already have an item with Title=(empty) and Value being empty. It's a good idea to have this empty item since it can be
used to clear any business segment values in the page properties. If this item is not present it can be re-created at any time:

394
4. Once the list is complete, go to AEM Channels authoring view. Business Segment is available as a setting under the page properties for most
templates and can be found under the Features tab:

5. You can now specify the Business Segment on the relevant pages.Please note that if you edited or deleted any of the values in step 2, it's a good
idea to now find the pages that were using those values and to check whether a business segment should be applied to them. You can re-set any
values to empty by choosing the "(empty)" value in the dropdown. Remember the activate the updated pages.

Using Business Segment in Page Metadata

To use Business Segment data on pages a metatag needs to be configured:

1. Access the relevant metatag configuration under Tools - Telegraph - core. There should be an existing metatag configuration page inside a core
folder as well as potentially channel specific metatag configuration pages under relevant folders. To add a metatag on the core level, double click
the configuration page to open it.
2. Check if metatag "tmgads.businessSegment" has already been configured. If not, you can add it by adding a new Meta Data component on the
page and configuring the following values:
Tag type: Name tag
Meta tag name: tmgads.businessSegment
Content type: Business Segment
Where to display metatag?: All pages

395
3. Once ready, activate the meta tag configuration page. Check that you can see the metatag for your channel page in author mode, and also activate the
channel home page to see the changes in publisher.

Related articles

Content by label
There is no content with the specified labels

396
Clearing down diskspace on Adobe instances
There are times when the disk space on Adobe instances may fill up, this is because when you delete anything from adobe it does not delete it from the
disk.

Step-by-step guide

1. Log into Adobe AEM


2. Open <server_name_port>/crx/explorer/config/index.jsp
3. Click 'Data Store Garbage Collection':

4. This will take you to the 'com.adobe.granite (Repository)' Page here, search for "runDataStoreGarbageCollection"
5. Click on the found link which should open this page:

6. Set the Boolean value to 'true' and click invoke, data will be cleared.

Related articles
Project Cheetah Test Automation Set Up
Deploy AEM environment using chef
Appium Mobile Device Automation Setup
Output: Spec / Guideline: How to build components
How to install Zen Garden

397
Commenting
General
This section contains general information about Commenting configuration in AEM.

398
Commenting Configuration
General
This section contains information about how to configure commenting in AEM and in Livefyre studio.

Commenting Channels & Sections Configuration


Commenting Global Switch Configuration
Default Commenting setting for new Channels and Sections
Feature flag for Commenting in Authoring
How to set initial commenting configuration for channels and sections
Livefyre Configuration for Single Story
Livefyre Configuration in AEM
Livefyre Global Configuration for Commenting

Local quick start


Overall steps for local deployment:

1. Build develop both (telegraph-component and authoring)


2. Then enable feature flag for authoring: https://confluence.aws.telegraph.co.uk/display/AEM/Feature+flag+for+Commenting+in+Authoring
3. In authoring there will be checkbox to enable commenting:

4. Make sure you enable commenting on channel/section configuration page: etc/telegraph/admin/commenting-configuration.html


5. When accessing a page you should see commenting in readOnly state for anonymous users
6. To mock login behaviour (Livefyre login will never work on your local environment) you need to create 2 cookies. Put the following in console:
Cookies.set('livefyre-token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJkb21haW4iOiJ0ZWxlZ3JhcGhtZWRpYS1pbnQuZnlyZS5jbyIsInVzZXJfaWQiOiJNZWwiLCJkaXNwbGF5X25hbWUiOiJNZWwgSCIsImV4cGlyZ
XMiOjE0ODYxODE3NTIuOTgsImlhdCI6MTQ3NjE4MTc1Mn0.1yJFow8REYllnFM9IqAlaon1pb6tYP-OEtrG9B0rRlM');

Cookies.set('tmg_session', 'test')
7. To switch to another user you need to remove livefyre-token cookie manually and then you can use another livefyre-token: Cookies.set('livefyre-
token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJkb21haW4iOiJ0ZWxlZ3JhcGhtZWRpYS1pbnQuZnlyZS5jbyIsInVzZXJfaWQiOiJrb3JuZWxpYWhhdGVzY2F0cyIsImRpc3BsYXlfbmFtZSI6Iktvc
m5lbGlhIGhhdGUgY2F0cyIsImV4cGlyZXMiOjE0ODYyNzgzODcuNjYzLCJpYXQiOjE0NzYyNzgzODd9.F58I1FqtcoFWsLobg3khgDlj_-
Pr1N45Fr0J4GZRqYQ')

Troubleshooting
Commenting using LiveFyre will only work if you are testing using the publisher i.e. local.telegraph.co.uk:4503. The livefyre behaviour is simulated on the
author. Add '127.0.01 local.telegraph.co.uk' to /etc/hosts if url doesn't work.

Login not working


When mocking login, duplicate cookies causes problems. Make sure there is only one 'tmg_session' and 'livefyre-token' cookie.

Page does render correctly on publisher


Login to https://qa18.telegraph.co.uk to ensure all local cookies are store for the telegraph.co.uk domain.

Check permissions for the everyone group. It needs reads access to /etc/design/telegraph and /etc/telegraph

http://localhost:4503/useradmin

399
400
Commenting Channels & Sections Configuration
General
This page contains information about Channel and section configuration for Commenting. This was implemented in
OPI-46 - Configure Comments by Channel / Section in AEM RELEASED .

The script to populate the configuration is attached to


OPI-143 - Create script to set initial Channels/Sections to 'Enabled' for Commenting in AEM config RELEASED

Commenting Channels & Sections configuration page


Configuration for channels and sections for commenting is available under:

/etc/telegraph/admin/commenting-configuration.html

Page can be also opened on AEM Author environment by going to: Tools > Telegraph > Admin Tools > Commenting Channel / Section Configuration page

On this page you can select / deselect channels and sections for which Commenting should be enabled. By selecting a channel, all subsections of that
channel will inherit the setting from channel, unless this is manually overridden at section level.

If you will select channel, and unselect all sections, then only articles in date folder structure and in evergreen section will have commenting enabled.
Articles in any section won't have commenting enabled in that case.

When configuration is done, page must be activated to reflect the changes on the live site. To do that press Save and Activate button, or go to Tools >
Telegraph > Admin Tools and activate the configuration page manually.

401
402
Commenting Global Switch Configuration
General
This page describes how to switch on/off commenting for whole platform. This was implemented in
OPI-134 - Configure Comments at Global level RELEASED

Please note, that even if the global switch is on, commenting might be disabled on a channel, section or article level.

Introduction
Commenting Global Switch is available on the same microservice as Paywall Meter switch, namely:

For non prod environments: meter-globalswitch.awspreprod.telegraph.co.uk


For prod environment: meter-globalswitch.aws.telegraph.co.uk

File which contains ESI variable for prod environment is called commenting-prod.html

This variable should contain value true or false:

<esi:assign name="commentingOn">false</esi:assign>

Akamai, when page will be requested will send a request for that file, will parse it, and will set the javascript global variable: tmg.COMMENTING_STATUS
based on what was set in "commentingOn" variable.

Bamboo plan to deploy the changes

Non prod environments


For Non prod environments, changes are deployed when something is commited to develop branch in this stash repository: https://stash.aws.telegraph.co.
uk/projects/WOC/repos/meter-globalswitch/browse?at=refs%2Fheads%2Fdevelop

Bamboo plan for manual deployment of changes from develop branch to meter-globalswitch.awspreprod.telegraph.co.uk:

https://bamboo.aws.telegraph.co.uk/browse/WOPC-CP

NOTE: Changes have to be commited to develop branch manually. After that the bamboo plan should start automatically. There is also a delay
on the microservice, so changes will be visible after few seconds / minutes.

Prod Environments
For Prod environments, changes are deployed manually. Changes should be made on master branch in this stash repository: https://stash.aws.telegraph.
co.uk/projects/WOC/repos/meter-globalswitch/browse .

Bamboo plan for turning on or off the commenting global switch are here:

Switching on: https://bamboo.aws.telegraph.co.uk/browse/WOPC-CPE


Switching off: https://bamboo.aws.telegraph.co.uk/browse/WOPC-CPD

WebOps team have access rights to run those two build.

Aditional information for Non prod environments


For testing purposes there is a way to switch commenting to on or off, without deploying anything to the meter-globalswitch microservice.

In OSGI There is a configuration of service called TMG - Commenting Configuration Service

In the configuration there are two fields, which can be configured. One of them is a URL to the html file in meter service. You can change that URL so it
points to a file with different value, for example there is a file called commenting-dev6-enabled.html which have variable commentingOn set to true.

NOTE: With this approach, if you want to see the results on articles that were already published, you need to flush the content on dispatcher.

403
Default Commenting setting for new Channels and Sections
General
This page describes how to set default value for commenting for new channels and sections.

Configuration
Every new channel or section, which is using HubTemplate should have commenting set. Default value can be set in OSGI. Please follow these steps:

1. Go to /system/console/configMgr
2. Search for 'HubTemplateCreationJobHandler'
3. Edit configuration
4. Check or uncheck the 'defaultCommentingValue' checkbox.

Of course, configuration for single channel or section can be changed later on Commenting Channel and Section Configuration page.

404
Feature flag for Commenting in Authoring
General
This page describes how to enable or disable commenting section in Authoring Tool.

Configuration
Commenting section can be enabled or disabled in Authoring Section by changing the feature flag value in OSGI Configuration. Follow these steps to
change the configuration:

1. Go to /system/console/configMgr
2. Search for 'Authoring Feature Flag'
3. Edit configuration
4. Check or uncheck the Commenting checkbox

405
How to set initial commenting configuration for channels
and sections
General
This page describes the process of setting initial commenting configuration for channels and sections using groovy script.

Configuration
Configuration is set via Groovy script.

List of channels and sections with proper setting needs to have format:

archery,,true
archery,bows,false
fashion,,true
news,,false
news,world,true

Configuration above will set

1. For channel archery commenting will be enabled for almost for whole channel, only section bows will have commenting disabled.
2. Whole channel fashion will have commenting enabled
3. Articles in date folders, in evergreen folder, and in almost all section of channel news will have commenting disabled. Commenting will be enabled
only for section world in channel news

Here is the spreadsheet with production channels and sections (it was taken on 14.10.2016): https://docs.google.com/a/telegraph.co.uk/spreadsheets/d
/1KAoWIc21PVxWsf0Sm2k8lCl3aX_6o3E3bacLvOhIVoQ/edit?usp=sharing

The best approach would be to set the configuration properly in that spreadsheet, and then export that document to a .csv format. Comma must be a
delimiter!

NOTE: Please make sure that you have removed the first row with column headings !

Script
When the configuration will be ready and it will be in the proper format, it needs to be copied into channelsSectionsList property, also if we want to save
the configuration the property REAL_RUN has to be set to true. Script is available below. You can find an example in the bottom of a page.

/**
* OPI-143: Script removes whole comment configuration for channels and sections.
* Next, it sets the new configuration based on the channels / sections passed as variable
"channelsSectionsList"
* Format of each entry should look like this:
* channel,section,value
* If section is missing, then setting will be set only for channel
* Value should be true of false.
*/
import org.apache.commons.lang3.StringUtils;
import com.day.cq.commons.jcr.JcrConstants;
def REAL_RUN = false
def COMMENTING_CONFIGURATION_PATH = "/etc/telegraph/admin/commenting-configuration/jcr:content/config"
def COMMENTING_PN = "commentingOn"
def PATH_SEPARATOR = "/"
info "initialised in ${REAL_RUN? 'PRODUCTION' : 'DRY RUN'} mode"
/**
* remove the configuration and recreate the configuration node
*/
def configurationResource = resourceResolver.getResource(COMMENTING_CONFIGURATION_PATH)
resourceResolver.delete(configurationResource)
configurationResource = ResourceUtil.getOrCreateResource(resourceResolver, COMMENTING_CONFIGURATION_PATH,
JcrConstants.NT_UNSTRUCTURED,
JcrConstants.NT_UNSTRUCTURED, false)

406
/**
* List of channels.
* Example which enables commenting for Whole channel Lifestyle, and disables commenting for section Fashion in
Channel Lifestyle:
* lifestyle,,true\nlifestyle,fashion,false
*
*/
def channelsSectionsList = """"""";
/**
* read and set the configuration.
*/
List<String[]> listOfInvalidEntries = [];
Scanner scanner = new Scanner(channelsSectionsList);
while (scanner.hasNext()) {
String configLine = scanner.nextLine();
String[] configEntry = configLine.split(",")
if (configEntry.length != 3 || StringUtils.isBlank(configEntry[0]) || StringUtils.isBlank(configEntry[2])) {
listOfInvalidEntries.add(configEntry)
} else {
setCommentConfiguration(configEntry, COMMENTING_CONFIGURATION_PATH, PATH_SEPARATOR, COMMENTING_PN)
}
}
printErrors(listOfInvalidEntries)
def printErrors(ArrayList<String[]> listOfInvalidEntries) {
if (!listOfInvalidEntries.isEmpty()) {
info "Following entries are invalid, please verify that configuration is proper: "
for (String[] entry : listOfInvalidEntries) {
if (entry.length == 3) {
info "Channel name: ${entry[0]}, section name: ${entry[1]}, comment configuration: ${entry[2]}"
} else if (entry.length > 0) {
info "Entry has invalid values. Channel name: ${entry[0]}"
} else {
info "Entry is completely empty, ignoring."
}
}
}
}
def setCommentConfiguration(String[] configEntry, String COMMENTING_CONFIGURATION_PATH, String PATH_SEPARATOR,
String COMMENTING_PN) {
def channelName = configEntry[0]
def sectionName = configEntry[1]
def configValue = configEntry[2]
def channelPath = COMMENTING_CONFIGURATION_PATH + PATH_SEPARATOR + channelName
def channelResource = ResourceUtil.getOrCreateResource(resourceResolver, channelPath, JcrConstants.
NT_UNSTRUCTURED,
JcrConstants.NT_UNSTRUCTURED, false)
if (StringUtils.isBlank(sectionName)) {
info "Setting commenting configuration to ${configValue} for channel \"${channelName}\""
setCommentingValue(channelResource, COMMENTING_PN, configValue)
} else {
info "Setting commenting configuration to ${configValue} for section \"${sectionName}\" in channel
\"${channelName}\""
def sectionPath = channelPath + PATH_SEPARATOR + sectionName
def sectionResource = ResourceUtil.getOrCreateResource(resourceResolver, sectionPath, JcrConstants.
NT_UNSTRUCTURED,
JcrConstants.NT_UNSTRUCTURED, false)
setCommentingValue(sectionResource, COMMENTING_PN, configValue)
}
}
def setCommentingValue(channelResource, String COMMENTING_PN, String stringValue) {
Boolean value = Boolean.parseBoolean(stringValue)
ValueMap channelValueMap = channelResource.adaptTo(ModifiableValueMap.class)
channelValueMap.put(COMMENTING_PN, value)
}
scanner.close();
if (REAL_RUN) {
info "SAVING CHANGES"
session.save()
} else {
info "REVERTING CHANGES"
session.refresh(false)

407
}
def info(String msg) {
println msg
log.info(msg)
}

Example

/**
* OPI-143: Script removes whole comment configuration for channels and sections.
* Next, it sets the new configuration based on the channels / sections passed as variable
"channelsSectionsList"
* Format of each entry should look like this:
* channel,section,value
* If section is missing, then setting will be set only for channel
* Value should be true of false.
*/
import org.apache.commons.lang3.StringUtils;
import com.day.cq.commons.jcr.JcrConstants;
def REAL_RUN = true
def COMMENTING_CONFIGURATION_PATH = "/etc/telegraph/admin/commenting-configuration/jcr:content/config"
def COMMENTING_PN = "commentingOn"
def PATH_SEPARATOR = "/"
info "initialised in ${REAL_RUN? 'PRODUCTION' : 'DRY RUN'} mode"
/**
* remove the configuration and recreate the configuration node
*/
def configurationResource = resourceResolver.getResource(COMMENTING_CONFIGURATION_PATH)
resourceResolver.delete(configurationResource)
configurationResource = ResourceUtil.getOrCreateResource(resourceResolver, COMMENTING_CONFIGURATION_PATH,
JcrConstants.NT_UNSTRUCTURED,
JcrConstants.NT_UNSTRUCTURED, false)
/**
* List of channels.
* Example which enables commenting for Whole channel Lifestyle, and disables commenting for section Fashion in
Channel Lifestyle:
* lifestyle,,true\nlifestyle,fashion,false
*
*/
def channelsSectionsList = """archery,,true
archery,bows,false
fashion,,true
news,,false
news,world,true"""";
/**
* read and set the configuration.
*/
List<String[]> listOfInvalidEntries = [];
Scanner scanner = new Scanner(channelsSectionsList);
while (scanner.hasNext()) {
String configLine = scanner.nextLine();
String[] configEntry = configLine.split(",")
if (configEntry.length != 3 || StringUtils.isBlank(configEntry[0]) || StringUtils.isBlank(configEntry[2])) {
listOfInvalidEntries.add(configEntry)
} else {
setCommentConfiguration(configEntry, COMMENTING_CONFIGURATION_PATH, PATH_SEPARATOR, COMMENTING_PN)
}
}
printErrors(listOfInvalidEntries)
def printErrors(ArrayList<String[]> listOfInvalidEntries) {
if (!listOfInvalidEntries.isEmpty()) {
info "Following entries are invalid, please verify that configuration is proper: "
for (String[] entry : listOfInvalidEntries) {
if (entry.length == 3) {
info "Channel name: ${entry[0]}, section name: ${entry[1]}, comment configuration: ${entry[2]}"
} else if (entry.length > 0) {
info "Entry has invalid values. Channel name: ${entry[0]}"

408
} else {
info "Entry is completely empty, ignoring."
}
}
}
}
def setCommentConfiguration(String[] configEntry, String COMMENTING_CONFIGURATION_PATH, String PATH_SEPARATOR,
String COMMENTING_PN) {
def channelName = configEntry[0]
def sectionName = configEntry[1]
def configValue = configEntry[2]
def channelPath = COMMENTING_CONFIGURATION_PATH + PATH_SEPARATOR + channelName
def channelResource = ResourceUtil.getOrCreateResource(resourceResolver, channelPath, JcrConstants.
NT_UNSTRUCTURED,
JcrConstants.NT_UNSTRUCTURED, false)
if (StringUtils.isBlank(sectionName)) {
info "Setting commenting configuration to ${configValue} for channel \"${channelName}\""
setCommentingValue(channelResource, COMMENTING_PN, configValue)
} else {
info "Setting commenting configuration to ${configValue} for section \"${sectionName}\" in channel
\"${channelName}\""
def sectionPath = channelPath + PATH_SEPARATOR + sectionName
def sectionResource = ResourceUtil.getOrCreateResource(resourceResolver, sectionPath, JcrConstants.
NT_UNSTRUCTURED,
JcrConstants.NT_UNSTRUCTURED, false)
setCommentingValue(sectionResource, COMMENTING_PN, configValue)
}
}
def setCommentingValue(channelResource, String COMMENTING_PN, String stringValue) {
Boolean value = Boolean.parseBoolean(stringValue)
ValueMap channelValueMap = channelResource.adaptTo(ModifiableValueMap.class)
channelValueMap.put(COMMENTING_PN, value)
}
scanner.close();
if (REAL_RUN) {
info "SAVING CHANGES"
session.save()
} else {
info "REVERTING CHANGES"
session.refresh(false)
}
def info(String msg) {
println msg
log.info(msg)
}

Groovy script needs to be run by WebOps team.

409
Livefyre Configuration for Single Story
General
This page describes how to change livefyre configuration options on a story level basis.

Prerequisites
Account in studio.livefyre.com

To start configuration open the page: http://studio.livefyre.com and select the proper Network, for which configuration should be applied.

This can be done by clicking the Network and then selecting the proper netowork from the list.

Next click on Apps in the menu bar

After that, list of the 'Apps' will be opened. Each app is a separate article in AEM. Article can be found by pageId, or page title, or article url.

Livefyre Configuration for a single Story


When article has been found, configuration page for it can be opened by clicking on it.

Now configuration tab needs to be opened.

That can be done by clicking the gear on the left hand side, like on the screenshoot below:

For the particular article following things can be configured:

Tags - you can add custom tags which can be used as a convenience to search for this article in Livefyre Studio
Allow new Content - This switch turns on/off possibility of adding new comments on the article. If it's set to off, old comments will be visible, but
no new comments can be added.
Article URL - Property which allows to override article URL
*Premoderate Content - Set to On, if comments should be premoderated before they will appear on live website
*Nest Level - Set the nest level for comments (number of reply indentations)
*Display Media - Set this to on if media (images, videos) should be displayed in comments
*Premoderate Media - Set this to on if content with media should be premoderated first
*Allow Photo Uploads - Set this to on if image uploading should be enabled
*Queue New Content - Set this to On if you want to disable live streaming and queue new content (comments/replies)
*Throttle Content - Set this to on if number of displayed comments should be reduced under high volume
*Enable Featured Comments - Set this to on to enable featured comments
*Allow Bulk Content - Set this to on to bulk content that contains the same text accross many different postings.

410
Livefyre Configuration in AEM
General
This pages describes how to configure livefyre account in AEM

Settings
In AEM Livefyre account configuration is under:

/etc/cloudservices/livefyre-configuration.html

Setting page contains one component which contains 4 parameters to configure.

Settings should be taken from confluence or from WebOps.

There is also possibility to take the configuration from Livefyre studio configuration.

Go to livefyre studio and login to an admin account (moderator account don't have access to the required pages);

Click on the gear in the top right corner:

Open Integration Settings tab.

In the Site Credentials search for prod site.

Copy Network Key and paste it in Network Key field in AEM Configuration

Copy Network Domain and paste it in Network Name field in AEM Configuration

Copy Site ID and paste it in Site ID field in AEM Configuration

Copy Site Key and paste it in Site Key field in AEM Configuration

Save the changes.

Activate the page by going to Tools > Cloud Services Configuration. Find Livefyre Configuration page and activate it.

411
Livefyre Global Configuration for Commenting
General
This page describe steps to configure Commenting in Livefyre Studio. Settings are set per network.

Each section on this page is a separate section in Livefyre studio, to make it easier to find the right setting.

Prerequisites
Account in studio.livefyre.com

To start configuration open the page: http://studio.livefyre.com and select the proper Network, for which configuration should be applied.

This can be done by clicking the Network and then selecting the proper netowork from the list.

Next click on the gear icon in the top right corner:

After that, configuration page will be opened. Make sure that Network Settings tab is opened.

Important: Configuration will be applied to every site in the given Network.

Moderation
First section is about the moderation. There are only few settings to configure here.

1. Settings
a. Confirm Trash should be turned on
b. Hide Replies should be turned on
2. Rules
a. Flag Rules
b. If Livefyre judges content as Containing PII, then Premoderate it
c. If content matches the Network profanity filter, Trash it
3. Profanity List
a. Enable Profanity checking should be turned on
b. Profanity List should be configured with list of words which are illegal.

App settings
Settings presented here are visible for users.

Default settings should be:

1. Nex level should be set to 2


2. Queue comments should be turned off
3. Queue Comments Show count should be set to 5, but it won't have any impact (because of 2nd point)
4. Premoderate Content should be turned off
5. Allow Revisions should be set to Edits
6. Edit window should be set to 5
7. Dsiplay media should be set to Links only
8. Premoderate media should be turned off
9. Allow photo uploads should be turned off
10. Allow Replies to reviews should be turned off
11. Top Content View should be set to Top Comments
12. Enable Featured Comments should be turned off
13. Translation set should be set to defaul
14. SocialSync shouldn't be configured.

Streams
Configuration of this section can be omitted as we are not using this feature by default.

ModQ

412
This is next section which contains configuration available for the user.

Premoderation:
1. Livefyre and Social Sync should be set to on
2. Curate should be set to always on

Flag Types:
1. User Flag - offensive should be turned on
2. User Flag - Spam should be turned on
3. User Flag - Off-topic should be turned on
4. User Flag - Disagree should be turned on
5. Profanity should be turned on
6. Spam should be turned on

SAFE rules:
All settings should be turned on.

Rights Management
Configuration of this section can be omitted as we are not using this feature by default.

Bans
If there are any known IP addresses which should be banned, they should be added here.

Translation Sets
Configuration of this section can be omitted as we are not using this feature by default.

Social Accounts
Configuration of this section can be omitted as we are not using this feature by default.

413
Commenting endpoints
General
This page contains information about endpoints which were added to support commenting functionality.

414
Channels and Sections Provider Servlet (OPI-46)
General
This page describes endpoint which is responsible for providing list of channels and sections with given template. Template list is configurable in OSGI ( /s
ystem/console/configMgr ) in ChannelsSectionsProviderService. To add a new template, you need to provide a JCR path to the template. By default
only channels and sections with hub template will be returned.

Request
Request is a simple GET request with Content-Type header set to application/json without any parameters.

/bin/telegraph/core/commenting/channels

Response
In the response, we get a list of channels and sections which were found.

[
{
"path":"/content/telegraph/lifestyle",
"label":"Lifestyle",
"children":[
{
"path":"/content/telegraph/lifestyle/fashion",
"label":"Fashion",
"children":[
]
},
{
"path":"/content/telegraph/lifestyle/health",
"label":"Health",
"children":[
]
}
]
},
{
"path":"/content/telegraph/business",
"label":"Business",
"children":[
{
"path":"/content/telegraph/business/wall_street",
"label":"Wall Street",
"children":[
]
},
{
"path":"/content/telegraph/business/something",
"label":"Wall Street",
"children":[
]
}
]
}
]

415
Commenting Configuration Reader Servlet (OPI-46)
General
This page describes endpoint which is responsible for providing configuration of commenting on Channel and Sections level.

Configuration is kept under /etc/telegraph/admin/commenting-configuration/config node in JCR.Configuration page for those settings is
available under /etc/telegraph/admin/commenting-configuration.html on AEM Author instance

Request
Request is a simple GET request with Content Type set to application/json without any parameters.

/bin/telegraph/core/commenting/config/get

Response
In the response, we get a list of channels which were saved last time.

{
"/path4":true,
"/path":true,
"/path/section1":true
"/path/section2":true
"/path2":false,
"/path2/section1":true
}

416
Save Commenting Configuration Servlet (OPI-46)
General
This page describes endpoint which is responsible for providing configuration of commenting on Channel and Sections level.

Configuration is kept under /etc/telegraph/admin/commenting-configuration/config node in JCR.Configuration page for those settings is
available under /etc/telegraph/admin/commenting-configuration.html on AEM Author instance

Request
Request is POST request with Content-Type header set to application/x-www-form-urlencoded and two parameters.

First one is configuration which should JSON like this:

{
"configuration":
{
"/content/telegraph/path":true,
"/content/telegraph/path/section":false,
"/content/telegraph/path2":false,
"/content/telegraph/path3":true,
"/content/telegraph/path4":true
}
}

Second parameter which is optional, is the parameter with name action. If it's passed with value set to saveAndActivate then configuration page will
be automatically activated after save.

Important: Channel and section path have to always start from '/content/telegraph'. Also section should include channel name, for example: /content
/telegraph/channel/section. Configuration for section is saved only when configuration is different then the channel configuration. For example given that
one want to save channel and section configuration and sends the request: {"/content/telegraph/path":true, "/content/telegraph/path
/section":true }. In such case only channel will be saved, because section has the same value as channel, so it can inherit this value. If section
would have value set to false, then both channel and section would be saved in the configuration.

URL:

/bin/telegraph/core/commenting/config/save

Response
In the response, we get a true or false string, depending if the save has succeed or if the save has failed.

"true" OR "false"

417
Commenting Solution Architecture
General
This page contains solution architecture document which describes the final solution for Comment feature on TMG websties.

Purpose
Currently on Telegraph websites, users can only read and share the articles in the social media. To engage users Comment component will be added to all
article pages. It is a custom component, which uses Livefyre commenting feature. All comments will be stored in Livefyre. Each user will have an account
in Livefyre and will be identified by name and surname. Anonymous users will only be able to read the comments. To add them, like them or flag them,
they will need to create an account in Telegraph.

Solution
At the begining comment component will be added only to pages which are using Article2 template (it will be embeded into Article2 template). On AEM
Author instance in edit mode or preview mode, placeholder will be displayed instead of the real component.

Comments will be configurable on different levels. On global level, which is the most important setting, which takes precedence over any other settings.
There will be also separate configuration for channels and sections, and also there will be possibility to override the channel or section setting on the article
level.

Component will be visible only on AEM Publish instances. When Commenting will be enabled for the current page, then after initialization comments will be
fetch from Livefyre. If the article is opened for the first time, then Livefyre will create a collection in the Livefyre cloud, which will contain all comments for
that particular article (in Livefyre Studio, this will be an App. Each article is a separate app).

Commenting feature will be release during the normal release, no changes in release process are required. No systems will be decommissioned as part of
this implementation.

Solution will not cause any data leak (any passwords, credit card numbers etc). Content is mostly generated by the users and it is moderated by Telegraph
Media Group employees.

Monitoring
Commenting monitoring will be implemented by WebOps team when Developers will provide example request, which can be used to test Livefyre services.
Livefyre also provides a service with information about their servers. Application itself will log errors, when configuration of the Livefyre Account is invalid or
when it is missing completely.

Commenting architecture

418
Commenting Configuration
Commenting configuration is available in different section. You can find it here: Commenting Configuration

It contains information:

how to configure commenting in AEM (account configuration, channels & sections configuration),
how to turn on / off commenting global switch
how to configure commenting in livefyre studio
what to do in case of the disaster scenario, where for example Livefyre will be unresponsive.

Sequence diagram for commenting flow (when page is requested)

419
420
Commenting support
This page should be moved to appropriate section.

General
This page contains scenarios and solution for them which are related to Commenting feature

Scenarios
For now there is no new relic monitoring, so most of the errors will be visible in logs or on live site

Scenario Effect Reason / Solution Comments

Livefyre is Commenting component Contact Livefyre support. In the meantime global switch should be turned off.
unreachable will not initialize, so end
user will not see the Instruction how to do this can be found here: Commenting Global Switch Configuration
comment component on a in Prod Environments section
page. JS errors will be
visible

Livefyre is Adding comments / loading Contact Livefyre support. In the meantime switching the global switch for commenting
slower than comments takes longer to off should be considered.
usual than usual. This should not
cause any issues on the Instruction how to do this can be found here: Commenting Global Switch Configuration
live website. in Prod Environments section

Component Users cannot add / read There might be few reasons of this scenario: Unknown User (krokosinskim), if
is not their comments we generate the pageId and
visible on 1. Page doesn't have pageId - in such case comment component will not be activate the story again then
the live displayed. There is no solution for that, as page id is added automatically during commenting component will
website the page creation. appear or not?
2. Global switch is turned off - In such case, switching it back to on should fix the
problem (make sure that it wasn't disabled on puropose) Yes, assuming that
3. Commenting is disabled on article level - in such case Commenting needs to comments are enabled for
be set to enabled on article level, and article needs to be republished channel or section or the
4. Livefyre configuration is missing - in this case, Livefyre configuration needs to article, when pageId will be
be provided, and page should be activated. How to do this is described here: Live generated, comment
fyre Configuration in AEM component will be displayed.
5. Commenting is disabled for new articles - this may happen because
commenting is disabled for channel and section where the article lives. Switching
it back to On on the article level and republishing that articleshould fix the
problem. If commenting should be enabled for all articles in that channel and
section, configuration for channel and section should be updated.
Instruction how to do this is available here: Commenting Channels & Sections
Configuration (make sure that it wasn't disabled on puropose)

For point number 1. there should be an info log that page id is missing.

For point number 4. there should be an error log, that livefyre configuration is invalid.

Comments Users cannot add new Contact Livefyre support. If comments cannot be added, but the component has been
cannot be comments initialized (and for example contains already some comments) then probaly something
added has changed / is not working on the livefyre site.

In the meantime Comments can be:

Globally turned off: Commenting Global Switch Configuration


Set to read only mode: Livefyre Global Configuration for Commenting

A lot of A lot of offensive / Comments might be disabled for that article on the article level in livefyre studio. Unknown User (krokosinskim), link
offensive inappropriate comments on Instructions how to do this is available here: Livefyre Configuration for Single Story for story article seems to be not
comments the live site working.
under the
specific Fixed
article

421
Livefyre Studio User Roles and permissions granted to
each user role

422
Setting up Livefyre Comment feature on Localhost
In order to be able to setup LiveFyre commenting feature on localhost environment, please follow the following steps. This document complements the
documentation currently available on this topic

Step-by-step guide
Follow the steps in the commenting configuration page on confluence

https://confluence.aws.telegraph.co.uk/display/AEM/Commenting+Configuration

2. Go to system/console/configMgr on author and publish and open the

TMG - Commenting Configuration Service

The commenting Global Status Service URL needs to be http://meter-globalswitch.awspreprod.telegraph.co.uk/commenting-dev.html

Other things to take into consideration while setting up commenting on localhost

- Ensure that you have the latest develop branch


- Rebuild the codebase

git pull
git checkout develop
mvn clean install
mvn crx:install -Dinstance.url=http://localhost:4502 -Dinstance.password=admin
mvn crx:install -Dinstance.url=http://localhost:4503 -Dinstance.password=admin

Also clear the dispatcher cache in the actual VM

docker exec dispatcher-publish sh -c 'rm -rfv /opt/aem/cache/core/*'


docker exec dispatcher-publish sh -c 'rm -rfv /var/cache/mod_pagespeed/*'

Related articles
AEM Core - Current release process
Creating a new Channel
How to configure Reg Walls in AEM
How to add HTML Embed in Global Navigation
How to configure Mid-Article Unit for content via LiftIgniter

423
Component Validation
When implementing a new component, it is a good practice to provide validation logic to prevent the component from being configured in a way that is not
acceptable. This page outlines common steps necessary to implement front-end (in a dialog) and back-end validation of Telegraph components.

Implementing AEM Component Back-End Validation


The back-end validation can be easily implemented by using existing Java interfaces and HTL (a.k.a. Sightly) templates. Here's how.

1. Implement the uk.co.telegraph.core.foundation.Validatable and (optionally) uk.co.telegraph.core.foundation.Blank interf


aces in your Sling Model. Extending uk.co.telegraph.core.foundation.AbstractValidatableModel may make it quicker.

@Model(adaptables = Resource.class)
public class HeadlineModel extends AbstractValidatableModel implements Blank {

protected static final int PRIMARY_HEADLINE_MAX_LENGTH = 400;

@Inject
@Default(values = "")
private String headline;

public String getHeadline() {


return headline;
}

@PostConstruct
private void postConstruct() {
validate(); // call validate on @PostConstruct to make sure the validation logic is executed every
time the model is instantiated
}

@Override
public void validate() {
if (StringUtils.isBlank(headline)) {
addError("Headline is not set"); // the addError method is implemented in
AbstractValidatableModel
} else {
addAllErrors(ValidationUtils.validateTextLength(headline, PRIMARY_HEADLINE_MAX_LENGTH,
"Headline")); // the addAllErrors method is implemented in AbstractValidatableModel
}
}

@Override
public boolean isBlank() {
return StringUtils.isBlank(headline);
}
}

2. In the HTL script rendering your component, use the validate or validateBlank templates
a. Import the template file using data-sly-use, the file is located in /apps/telegraph/core/commons/components/component
/templates.html
b. In a sly element, call the validate or validateBlank template
c. If implementing Blank, provide an HTML file called blank.html with an example rendition of the component. The file will be used by
the validateBlank template.
This is a flat HTML file representing what the component may look like when configured. For example:

Example blank.html content for the Headline component

<h1>Click here to enter a headline</h1>

The contents of blank.html will appear on the page once the component is dragged and dropped from the sidekick. It will be grayed-ut
and slightly transparent. The following screenshot shows examples for the Headline, Lead Asset and Byline components on a newly
created Article 2 page.

424
d. In a separate element, test if the model is valid and display it.

A simplified, minimal example from the Headline component.

Use of the validateBlank template in HTL/Sightly

<!--/* The model is expected to implement the Validatable and Blank intefraces (line 3) */-->
<!--/* Pass the model and the name of the component to be displayed next to validation messages as
parameters to the HTL template (line 5) */-->
<sly data-sly-use.componentTemplates="/apps/telegraph/core/commons/components/component/templates.html"
data-sly-use.headline="uk.co.telegraph.core.article.headline.HeadlineModel"
data-sly-call="${componentTemplates.validateBlank @ validatableWithBlank=headline, name='Headline'}">
</sly>
<h1 data-sly-test="${headline.valid}"> <!--/* Only display the actual component if it's valid */-->
${headline.headline}
</h1>

The blank.html view is optional. If you don't need it, don't implement the Blank interface and use validate as opposed to validateBlank.

425
Related articles
Article List
Topic Pages
Metatags
Ad Blocker Detector
Article 2 Template

426
Configure a TMG subscription product

Setting up a Product
Product Features (not public facing)
Product Configuration (not public facing)
Comparison Template (public facing)
UK vs International
Product Landing Page (not used)
Premium Products - Bare (public facing)

Setting up a Product
In AEM under the Telegraph node (Portal) open the Products folder (/content/telegraph/products) create a product feature page using the Product
Features template.

Product Features (not public facing)


Product Features pages serve as a container for the product pages. Each Product Feature page serves three purposes:

1. To set up a campaign or offer (although the campaign ID and offer ID are not configured in the Product Feature page but in the Product Detail
pages underneath it)
Note a campaign in this sense might be the route the user took get to the product page.
The Product Feature pages also get used to split out the different campaigns by inbound location (UK vs international).
2. To configure the list of features that exist across all of the products beneath. These are the line item that appear in the Product Comparison
page.
You can also set the order of the features in the page properties. This order gets used on the user facing Product Comparison page.
3. To house the Product Configuration pages that belong to this campaign

Note the the Product Feature pages are not public facing.

Product Configuration (not public facing)


Product configuration pages serve to store the content for each individual product and always live underneath a Product Feature page. Each Product
Configuration page serves the following purposes:

1. To hold the pack shot for each product.


2. To map the product's configuration to a Product Feature page. This does not happen by inheritance and needs to be mapped.
The practice is to place all Product Configuration pages underneath the Product Feature pages but the flexibility is there to map it to
another Product Feature page should the need arise.
3. The remaining product information can be entered in the fields if you open the page itself (properties include

Remember when you edit the properties on this page then you must save your amends by clicking the "Save Product Details" button at the bottom of
the page, then activate the page and also reactivate any pages that use this configuration (such at the Comparison Template pages).

Note the Product Configuration pages are not public facing.

Comparison Template (public facing)


The Comparison Template is used to promote registration and the various subscription products offered by TMG and is therefore used to create public
facing pages. Each Comparison page contains a baked in product comparison table that gets its configuration from a mapped Product Feature and its
mapped Product Configuration pages. The products are mapped by setting a path to the relevant Product Feature page in the Product group field on the Pr
oduct Information tab in page properties.

The Subscribe Now links in the comparison table redirect the user to the Aquisition page (/secure/payment) where they can purchase the subscription to
the selected product. As the visitor selects their product on the Comparison page the links in the Subscribe Now buttons include the product ID and
campaign ID to pass to the Aquisition page. These properties are provides to the buttons by virtue of the the content in the Product Configuration pages
and the mapping to this page.

427
Product ID is the identity value given to each product and held in Zuora (see Core API Configuration#Productids for details)
Campaign ID can be gotten by speaking with people in TMG Marketing.

UK vs International
Products that can be sold to both UK and international customers need to have to have a page for each location. There is a setting is the page properties
on the Location tab to configure which pages are the international ones (if the International checkbox is not checked then the page will be treated as UK).

In setting up the UK and international pages the convention used is to make the UK one be a parent of the international one. Both pages should be given
the same title but by convention the name of the international one is set as "international".

Product Landing Page (not used)


The Product Landing page template was in use up until the launch of Premium to create public facing pages that provide individual product details. With
the launch of Premium these have been replaced by the product pages within the Premium channel. The new pages use the Bare template.

Premium Products - Bare (public facing)


These are the product details pages that have been introduced with the launch of Premium and they replace Product Landing Page pages that used to live
under the Subscriptions page.

These new pages use the Bare template. The content of the page is provided by use of an HTML Embed component.

Any links from these pages to Aquisition page should include the product ID and campaign ID properties otherwise the user will not be able to purchase a
subscription. These properties will need to be hard coded in the HTML of the HTML Embed component as the Bare template has no way of being
mapped to the Product Configuration pages.

428
Configure clientlibs
Configuring client libs
To configure how the clientlibs are loaded and embedded in the page use the ".content.xml" files within each clientlib folder.
To modify the way it behaves modify / add / remove one of the following attributes:

Naming convention

Theme names cannot have dot's in their name, because they are used as a separator in a lazy loading functionality.

categories (required)
defines the name or names under which clientlib will be available to other clientlibs [single value or array of values]
there is a list of special fixed names for normal clientlibs (all will be loaded):
tmg.css.inline - css clientlibs to be inlined in head of the page
tmg.js.inline - js clientlibs to be inlined in head of the page
tmg.css.header - for css clientlibs to be loaded normally ( after inlined clientlibs )
tmg.js.header - for js clientlibs to be loaded normally ( after inlined clientlibs )
tmg.css.json - css clientlibs to be loaded in json mode ( loaded after DOM ready )
tmg.js.json - js clientlibs to be loaded in json mode ( loaded after DOM ready )
there is a list of special variable names for themes (only one from tmgthemes/THEME_NAME will be loaded):
tmg.theme - that this is a theme clientlib and can be chosen on the dropdown list in AM, value of it will be parsed from tmg.
THEME_NAME.css.(...) or tmg.THEME_NAME.js.(...)
tmg.THEME_NAME.css.inline - css clientlibs to be inlined in head of the page ( after normal clientlibs )
tmg.THEME_NAME.js.inline - js clientlibs to be inlined in head of the page ( after normal clientlibs )
tmg.THEME_NAME.css.header - css clientlibs to be loaded normally ( after normal inlined clientlibs )
tmg.THEME_NAME.js.header - js clientlibs to be loaded normally
tmg.THEME_NAME.css.json - js clientlibs to be loaded in json mode
tmg.THEME_NAME.js.json - js clientlibs to be loaded in json mode
e.g.:
categories="clientlib_1" - this client lib will be available under name of "clientlib_1"
categories="[clientlib_1,tmg.css.inline,tmg.js.header]" - this client lib will be available under name of "clientlib_1" & its css will be
loaded by injecting inline in head of the page & its js will be loaded via link in header
categories="[theme_clientlib_1,tmg.theme_clientlib,tmg.theme_clientlib.css.json,tmg.theme_clientlib.js.json]" - this client lib will
be available under name of "theme_clientlib_1" and "tmg.theme_clientlib" & its css and js will be loaded by asynchronous load
at the DOM ready
cssTest (optional):
run js test to define if the css files of that client lib will be loaded via json method ( test has to fail to init load )
e.g.:
cssTest="cssua.ua.webkit"
jsTest (optional):
run js test to define if the css files of that client lib will be loaded via json method ( test has to fail to init load )
e.g.:
jsTest="Modernizr.mq(&quot;only all&quot;)"
dependencies (optional):
if client lib category name is defined it indicates that this clientlib cannot be loaded before the one mentioned in that attribute [single
value or array of values]
e.g.:
dependencies="clientlib_1" - this client lib will be loaded after loading "clientlib_1"
dependencies="[clientlib_1,clientlib_2]" - this client lib will be loaded after loading "clientlib_1" & "clientlib_2"
embed (optional):
if client lib category name is defined the content of the clientlib with that name is copied into the one that contain that attribute [single
value or array of values]
e.g.:
embed="clientlib_1" - this client lib will include "clientlib_1" (nb, clientlib_1 must also be listed as a dependency)
embed="[clientlib_1,clientlib_2]" - this client lib will include "clientlib_1" & "clientlib_2" (nb, clientlib_1 & clientlib_2 must also be
listed as dependencies)

Desired load order of clientlibs


inline:
css:
core_inline.css ( skipped & embed in tmgtheme_cars_inline ) DEPRECATED
tmgtheme_cars_inline.css ( skipped & depends on core_inline )
js:
core_inline.js ( skipped & embed in tmgtheme_cars_inline ) DEPRECATED
tmgtheme_cars_inline.js ( depends on core_inline )

header:
css:
core.css ( skipped & embed in tmgtheme_cars & depends on json )
dfp.css ( empty )

429
tmgtheme_cars.css ( depends on core )
js:
dfp.js

json:
css:
json.css ( empty )
respond.css ( empty )
print.css
js:
json.js ( test )
respond.js ( test )
print.js ( empty )
core.js ( skipped & embed in tmgtheme_cars & depends on json )
tmgtheme_cars.js ( depends on core )

Current configuration of the client libs


core:
categories="[core,_tmg.js.json,_tmg.css.header]" dependencies="[json]"
core-inline:
categories="[core_inline,_tmg.js.inline,_tmg.css.inline]"
dfp:
categories="[dfp,tmg.js.header,tmg.css.header]"
json:
categories="[json,tmg.js.json,tmg.css.json]" jsTest="window.JSON"
print:
categories="[print,tmg.js.json,tmg.css.json]"
respond:
categories="[respond,tmg.js.json,tmg.css.json]" jsTest="Modernizr.mq(&quot;only all&quot;)"
tmgthemes
cars:
categories="[tmgtheme_cars,tmg.theme,tmg.cars.js.json,tmg.cars.css.header]" dependencies="[core]" embed="[core]"
cars-inline:
categories="[tmgtheme_cars_inline,tmg.theme,tmg.cars.js.inline,_tmg.cars.css.inline]" dependencies="[core_inline]" embed="
[core_inline]"

430
Creating a Channel
Refer to Digital Publishing documentation here - TMG Channels guide

431
Creating a new Channel
Contents

Create a Channel node


Applications folder
Setting up the application folder
Main Sidebar1
Onward journey list
Non-IAB
Navigation
Assign to Cluster
Create navigation
Create/edit navigation links
Business Segments
Enable Channel for Authoring
Expose Sections in Autoring
Remove sections from Authoring
Add default Tag
Channel style
Page Titles
Section pages
Comments
Meta Keywords
Social Media
RSS feeds for Twitter
Social Media Share and Follow settings
Share tools
Follow tools
Notifications
Webops whitelist
Platforms, API & Apple News
Premium & meter
aem_prod_notifications
Inform editorial
Snippets
Creating snippets
Using snippets

Reference guide for Channel creation tasks. Not all tasks are required for every channel.

Create a Channel node


The first step is to create a channel node under the main Telegraph node.

432
433
Applications folder
Setting up the application folder
The application folder is where the customisation of a channel is stored
It’s not a folder but a blank page

434
Main Sidebar1
The right side of the page is called the side bar. Customising the right side is something that can be done through the application folder of the channel. The
side bar only applies to Article 2 pages

Set up Editor's Choice list which will run across articles

435
436
In the “application” folder

1. Click “New Page…”


2. Click “New…”
3. Choose “Side Bar” template
4. Title: sideBar
5. Name: sideBar (the name must be 'sideBar')
6. Click “Create”

1. You can drag and drop components into the dotted area
2. Once you are done you can “Activate Page” and it will appear on all articles in that channel

404 page

In the "application" folder

1. Click “New…”
2. Click “New Page…”
3. Choose “Blank” template
4. Title: errorpages
5. Name: errorpages
6. Click “Create”

Under “errorpages”, add the 404 page

437
1. Choose “Generic Error Page” template
2. Click “New…”
3. Click “New Page…”
4. Title: 404
5. Name: 404
6. Click “Create”

The 404 page is a simplified article page. Edit links and onward journey list

1. Standfirst: “Perhaps this page has been moved or the URL has been mistyped” Headline: “Sorry - Page not found”
2. Add a bullet list with links to the channel, contact form and a reference to look at the list below
3. Add a list to the latest in the channel.

438
Onward journey list
The onwardJourney template allows you to add components to the bottom of an article page.

This only works with the Article 2 page template.

439
In the “application” folder

1. Click “New…”
2. Click “New Page…”
3. Choose “Onward Journey” template
4. Title: onwardJourney
5. Name: onwardJourney
6. Click “Create”

Set up List in Onward Journey page to populate 'X latest' at end of articles in channel

1. Add the components you wish into the dotted area


2. Once done, activate the template
3.

440
3. It should appear below articles in that channel

Non-IAB
The non-IAB component is used to surface Spark’s carousel unit and other commercial widgets (HTML embed) The non-IAB component is built into the
Article 2 and Hub page templates. You cannot control where this component goes. What is set up in the non-IAB component appears on all pages under
that application folder level

Warning: Do not place too many items into the non-IAB component because it will change the page layout

441
In the “application” folder

1. Click “New Page…”


2. Click “New…”
3. Choose “Non-IAB Advertisments” template
4. Title: <anything you want>
5. Name: noniab
6. Click “Create”

The non-IAB component has region specific zones.

Default
GB
US

442
Canada
Australia
Europe

The only thing you can put in the zone is an HTML embed.
Warning: Be careful when putting in 2+ embeds by accidentally deleting code

Navigation
Assign to Cluster
eg Fashion to Lifestyle

1. Open channel page properties


2. Cluster tab
3. Assign to cluster

Create navigation
1. In the application folder of a channel/section
2. Click “New…”
3.

443
3. Click “New Page…”
4. Choose “Blank Template”
5. Title: navigation
6. Name: navigation
7. Click “Create”

8. Under the “navigation” folder, add a new page which is a “Navigation Config”
Title: local
Name: local

444
9. Click “Create”

Create/edit navigation links


1. Open Applications / Navigation / Local
2. Add a “navigation item” in the dotted area
3. Enter the “Display Text”. This is the visible text that will be in the menu

445
4. Enter the “URL”. Use the search icon to find the path to the article or you can paste in the link

5. Once all of the navigation items are in the navigation config, you can reorder by using a drag and drop action for each item
6. If you are happy with the navigation, go to the Page tab and click on “Activate Page”

Business Segments
Instructions in this document:

https://docs.google.com/a/telegraph.co.uk/document/d/1BPsCZ0HUaRukM0iVLnY-6XxWIwOKQ1Hd5hwZORUP3TY/edit?usp=sharing

Enable Channel for Authoring


1. Go to Tools area of AEM, then Telegraph / Admin Tools
2. Open page called Feature Settings

446
3. Tick the Authoring box

447
4. Activate page.

Expose Sections in Autoring


1. Open Page Properties for each Section
2. Under TMG Authoring, tick "Is it a Section?"

3. Activate page

Remove sections from Authoring


1. Untick the 'Is it a section' box within the section - the reverse of the above.
2. Go to Tools area of AEM, then Telegraph / Admin Tools
3. Open page called Feature Settings - and untick the Authoring box for the whole channel and press Save.
4. Activate the Channel.
5. Then re-tick the Authoring box for the whole Channel and press Save.
6. Reactivate the Channel.
7. Sub-sections should now be removed from the Authoring list.

Add default Tag


If you add a structure tag to the hub page Tags menu under Page properties it will be automatically added to all new content pages created within that
channel.

Channel style
1. Open Page Properties for Channel page
2. Then Templates tab

448
3. Select channel style template

Page Titles
1. Open Page Properties for Channel page
2. Then Basics tab
3. Under the "More Titles"
4. Edit Page Title and Description

Section pages
Add Editor's Choice block to each page - 5 items, headline position First, Style version 11

Add Top split list - 10 items, headline position Body, Type Any, Style version 12

449
Add Lower split list - 20 items, offset start 10, headline position Body, Type Any, Style version 12

Add footer cluster list: Style version 1

Delete Facebook Like box

Comments
Each new channel needs to be set for default behaviour for reader Comments on new articles therein. This can be found under Tools.

https://chase.telegraph.co.uk/etc/telegraph/admin/commenting-configuration.html

Meta Keywords
- In tools: telegraph/core/<channel> folder
Need to create new channel meta tags folder, and copy the metaTags page in from a similar channel - not a Cluster.
Folder name must match channel name (websites, name field aka URL)

Sitemaps

Sitemaps should be automatic. However in order to trigger them you must publish the channel, then publish a piece of content therein, then republish the
channel.

Social Media
RSS feeds for Twitter
Request new RSS feeds of content from the Platforms team.

Social Media Share and Follow settings


Social Media settings inherit down from the Homepage to Channels and then to Subsections. A page will use the site defaults unless changes are
specified. This will usually be done at the Channel level.

All settings are managed within the Properties menu of the given Channel page. Go to the Social tab.

Share tools

450
Twitter Settings

Account: name the account (no @) to be referenced when content shared - via @TelegraphBooks

Disable Auto Tweet: Ignore, does nothing

Social Network Settings

Inheritance: Allows custom settings to be used

Share Networks

Show Social Media Counters: Displays share count to user. Only FB data.

Pinterest Share Options: Turn on Pinterest share option

LinkedIn Share Options: Turn on LinkedIn share option

WhatsApp Share options: Turn on WhatsApp share option - only seen by users on Mobile sized screens

451
Follow tools

Follow component

Component Heading: Custom title for the Follow box at the end of articles. Defaults to Follow the latest (channel name) news

Select Primary Follow Network: Changes which follow button is presented first

Hub Position A: Controls Follow box which appears in the right hand column of some Hub pages. The Primary placement is at the end of articles.

Follow buttons

For each network you can enable the Follow button and pick the specific account.

Facebook use account name OR full page URL

Twitter use account name without @

Instagram use account unique name from URL

Pinterest use account unique name from URL

LinkedIn use profile ID - we only have one - 9053

452
453
Notifications
Webops whitelist
Tell Websupport@telegraph.co.uk about the new channel so they can whitelist it for public access

Platforms, API & Apple News


Tell the platforms team about the new channel so that it can be included in the API correctly. You'll need to nominate an Apple News channel for the
content to be fed into.

Premium & meter


We have to set up the channel for Premium, otherwise Premium content will not be correctly restricted for readers. Contact Product team to ensure this is
arranged.

aem_prod_notifications
Add team addresses to email group aem_prod_notifications@telegraph.co.uk when they have access to AEM or Authoring. Email request to helpdesk.

Inform editorial
Tell the people what is happening

Snippets
Do you have something on your page that would need to be replicated across multiple pages?

An HTML embed
A curated list
A combination of components

Tired of redoing the same thing over and over? Then a snippet is what you need!

The Portal page uses snippets to pull in content from other channels to maintain channel specific styling.

Creating snippets
In the “application” folder

1. Click “New Page…”


2. Click “New…”
3. Choose “Blank” template
4. Title: snippets
5. Name: snippets
6. Click “Create”

In the “snippets” folder

1. Click “New…”
2. Click “New Page…”
3. Choose “Snippet” template
4. Title: anything you want
5. Click “Create”

454
A snippet has a single area to add components.

The area is full width and there is no way to view what this snippet looks like in a published view.

To be able to use the snippet remember to “Activate” it.

Using snippets
To use a snippet, you need to first add a “snippet reference” to the page.

1. Search for the path to snippet


2. Add snippet reference to page
3. Double click to edit
4. Click “Ok”
5. Click “Ok” once you see the path
6. Snippet should appear on page

455
Git Setup
Git Configuration
We have to make sure to use consistent Git settings. This page describes a number of configuration options that every new developer should take into
consideration.

Set up your username


If you're a contractor, you might be using different repos in your dev environment and you're probably using a different email for those. In order to configure
you username on a per-repository basis, navigate to your local copy of a telegraph project and run the following commands in the Git bash:

git config user.name "Your Name"


git config user.email "your.name@telegraph.co.uk"

This ensures that your telegraph account appears in the commit history.

Further reading on setting up user names in Git

Avoid merge bubbles


A merge bubble can appear when two (or more) developers are working on a single branch.

Here's an example scenario:

A branch contains a set of commits with A and B being the newest ones

remote (...)---A---B

Two developers, Alice and Bob checkout this branch and do some work

remote (...)--A--B
Alice (...)--A--B--C--D
Bob (...)--A--B--E--F

Alice pushes her changes to the remote

//Alice pushes her changes


remote (...)--A--B--C--D
Alice (...)--A--B--C--D
Bob (...)--A--B--E--F

Bob wants to push


Bob wants to push his changes but finds out that he has to pull first. This is when a merge bubble can occur, depending on the Git config. By default the
Git will attempt a merge when concurrent changes are pulled from the remote. The situation will look like this:

remote (...)--A--B--C--D
Alice (...)--A--B--C--D
Bob (...)--A--B--C--D--MRG
\-E--F--/

Where MRG is the merge commit that basically merges the branch into itself, creating a merge bubble

456
How to keep history cleaner
If Bob configures his Git client to perform a rebase instead of a merge when new code is pulled onto a branch from a remote, a linear history can be
achieved.

remote (...)--A--B--C--D
Alice (...)--A--B--C--D
Bob (...)--A--B--C--D--E--F

Bob's changes are simply replayed (rebased) on top of what was in the remote at the point of pulling.

To enforce this behaviour, a developer can use the following command:

git pull --rebase

Every time he or she pulls changes from a remote.

In order to avoid passing this parameter to every git pull command, this can be made the default choice by adjusting a global setting called autosetup
rebase. Execute:

git config branch.autosetuprebase always

to enable it for every branch in the current repository... or

git config branch.autosetuprebase always --global

to enable it for every repository on the developer's machine.

Please note that this will set the default behaviour for all branches to be created in future. Existing branches need to be explicitly updated using:

git config branch.*branch-name*.rebase true

Further reading

Place JIRA numbers in commit messages


Git commits do not belong to a single branch. They're part of a history (one that can even change) and once you merge your feature branch somewhere,
they keep existing even when the original branch is deleted. This is why a branch name is not enough to associate a change set with a particular story. It's
really a lot easier to inspect the code when you can just click it in your IDE and immediately find out where to look in JIRA to explain some design
decisions.

Please remember that even if you forget to use the number, it's not too late until you actually push the changes. git commit --amend allows you to
change the commit message (or even add changes to an already existing commit). To adjust a message, you can run:

git commit --amend -m "JIRA-ID: Updated commit message"

However, you should avoid amending commits that have been already pushed to the repository as these may be simply rejected by the server (depending
on its configuration) or, worse, mess up someone else's history.

457
Related articles
Git Setup

458
Hiding Channels prior to launch
In the lead up to the launch of a channel in AEM the Digi Pub team will create and publish a channel, sections, articles and galleries. Akamai is used to
hide the channel from the web however as the articles and galleries are published, AEM has no way of knowing that they should not be displayed in lists
on channels that are live. Therefore it would be possible for a user to see a link to an article or gallery that is not live in a list on a page that is
live. Clicking on that link would result in a 404.

To prevent this from happening a suite of scripts has been developed that need to be run on a regular basis whenever there are channels that are in
Production but not live. This page provides the instructions on how the scripts should be used.

As we are preparing the content on production environment before it goes live we need some mechanism to hide this content from lists that are visible on
the internet.

The idea
We are doing two things to hide non-live content:

1. We add special tag: structure:blacklist to content that is not live yet (should not be visible on lists)
2. We configure all live lists to exclude content that is tagged with structure:blacklist tag

So we need to have proper lists of:

channels that are to be hidden (in order to apply structure:blacklist tag)


channels that are live (in order to update the lists configuration)

Later on, when particular channel goes live we remove the structure:blacklist tag from this channel pages. We need also update this channel lists to not
show hidden content.

We should run the scripts probably on a daily basis, probably at night. there was an idea that this could be done with bamboo.

pages - content of Article2 or Gallery type


non-live channels - channels that are available on production AEM instances, but are not yet visible from internet

Step-by-step guide

Applying structure:blacklist tag to non-live content


This script will mark pages with the tag that will exclude them from live lists. Marking non-live content could also be done manually by applying the struct
ure:blacklist tag to the page.

1. Get the groovy script from https://stash.aws.telegraph.co.uk/projects/CHEET/repos/telegraph-component/browse/scripts/groovy/AEM-4021-add-


non-live-tag-to-pages.groovy?raw
2. Review the CHANNELS_TO_HIDE list in the script (should contain channels that are not live)
3. Run the groovy script in groovy console on author and publish instances:
a. http://author.local.telegraph.co.uk:4502/etc/groovyconsole.html
b. http://publish.local.telegraph.co.uk:4503/etc/groovyconsole.html

Updating live lists to exclude non-live content


This script updates live lists configuration to exclude pages tagged with structure:blacklist tag.
When new list is created within the live channels it may also be configured manually to exclude pages tagged with structure:blacklist.

1. Get the groovy script from https://stash.aws.telegraph.co.uk/projects/CHEET/repos/telegraph-component/browse/scripts/groovy/AEM-4021-hide-


non-live-pages-on-lists.groovy?raw
2. Review the LIVE_CHANNELS list (it should contain live channels, the lists on those channels will not show blacklisted content)
3. Run the groovy script in groovy console on author and publish instances:
a. http://author.local.telegraph.co.uk:4502/etc/groovyconsole.html
b. http://publish.local.telegraph.co.uk:4503/etc/groovyconsole.html

When the channel goes live


This script removes the structure:blacklist tag from pages within the specific channel.

459
1. Get the groovy script from https://stash.aws.telegraph.co.uk/projects/CHEET/repos/telegraph-component/browse/scripts/groovy/AEM-4021-
remove-non-live-tag-from-pages.groovy?raw
2. Update the CHANNELS_TO_SHOW list to contain channel or channels that are to go live
3. Run the groovy script in groovy console on author and publish instances:
a. http://author.local.telegraph.co.uk:4502/etc/groovyconsole.html
b. http://publish.local.telegraph.co.uk:4503/etc/groovyconsole.html

Related articles
See also:

Installing Groovy Console


Groovy script release

460
How to add HTML Embed in Global Navigation
Follow the below steps to add the Global Navigation HTML Embed to the Join Premium menu

******For Developers make sure changes are in the Training environment*******

Step-by-step guide

Initially test the Embed Markup in Training environment before deploying in the Production environment. Go to Environments for settings.

1. In AEM site admin, in the Author instance, navigate to the url: http://<<host>:<port>/content/telegraph/application/navigation/global.html eg for
Training to author instance go to global.
2. Open the navigation item - the grey bar to which the embed will be added. In this case, it is under Not logged in >> Join Premium today
3. Make these changes:
a. Select the Html embed tab
b. Check 'HTML Embed' checkbox
c. Width - add the width in pixels of the Iframe - (current width is 450)
d. Height - add the height in pixels of the Iframe - (current height is 400)
e. Enter CSS and Markup into HTML embed content field - this will be rendered into an iframe. (see current template*** below)

4. Save the input by selecting the OK button - this will be validate the input
5. If the content is invalid - the field is highlighted in red, and you will not be able to save the content. See the section Validation checks** to check
the validation checks
6. Correct the content if required and save - repeat if necessary
7. View the changes in Author Instance in AEM on any TCUK Training page. Hover over the "Upgrade to Premium" button or button affected and
you should your Iframe with the content you specified in step (3).
8. Activate/Publish the Global Nav component page (global) using the AEM CQ sidekick to publish the changes to the AEM publisher
9. Check how it looks on any webpage in the environment applicable.
10. Once happy with the results, repeat all steps in the Production environment.

Current Markup template ***

<!DOCTYPE html>
<html>
<head>
<base target="_parent">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Overlay</title>
<meta name="description" content="">
<meta name="keywords" content="">
<link href="" rel="stylesheet">
<style>.global--nav--container {
font-family: "Austin News Deck Medium", Georgia, Times, serif;
-webkit-font-smoothing: antialiased;
width: 450px;
height: 332px;
background-image: url("/content/dam/subscriptions/premium-product/bgd.png");
background-position: 0px 5px;
background-size: 100% auto;
background-repeat: no-repeat;
background-color: #F9F6F2;
display: flex;
flex-direction: column;
justify-content: space-between;
}

.global--nav--container .global--nav--content {
align-self: flex-start;
}

.global--nav--container .global--nav--title {
color: #9A6710;
font-size: 30px;
line-height: 32px;
width: 70%;
padding: 25px 0px 0px 25px;
}

.global--nav--container .global--nav--subtitle {
color: #6B5E3F;
font-size: 20px;
line-height: 22px;

461
padding: 20px 0px 0px 25px;
}

.global--nav--container a {
text-decoration: none;
}

.global--nav--container .global--nav--cta--container {
width: 150px;
height: 48px;
background-color: #C38419;
font-family: "Telesans Text Regular", Arial, sans-serif;
font-size: 14px;
text-decoration: none;
display: flex;
align-items: center;
justify-content: center;
margin: 25px 0px 0px 25px;
}

.global--nav--container .global--nav--cta {
color: white;
}

.global--nav--container .global--nav--footer {
width: 400px;
height: 40px;
padding-top: 10px;
margin: 0px 25px;
border-top: 1px solid #DDDDDD;
}

.global--nav--container .global--nav--footer .global--nav--footer--left {


width: 98px;
float: left;
margin-top: 4px;
}

.global--nav--container .global--nav--footer .global--nav--footer--right {


width: 106px;
float: right;
}

.global--nav--container img {
width: 100%;
height: auto;
}

</style>
</head>
<body>

<div class="global--nav--container"><div class="global--nav--content"><div class="global--nav--title">Unlimited access to exclusive stories<


/div><div class="global--nav--subtitle">Free for 30 days,
then just £1 per week</div><a href="http://www.telegraph.co.uk/subscriptions/sub-bar/?icid=generic_premiumsub_generic_generic_topnav-
hover&amp;redirectTo=www.telegraph.co.uk"><div class="global--nav--cta--container"><div class="global--nav--cta">Start free trial</div></div><
/a></div><div class="global--nav--footer"><div class="global--nav--footer--line"></div><div class="global--nav--footer--left"><img src="/content
/dam/subscriptions/premium-product/tele-micro.png"></div><div class="global--nav--footer--right"><img src="/content/dam/subscriptions
/premium-product/Premium-gold.png"></div></div></div></div>

</body>
</html>

Validation checks**

1. Ensure that the Width and the Height fields contain the Iframe dimensions in pixels

2. Script tags are not permitted, the presence of a script tag will cause validation to fail

3. There is a check on number of front and back angular brackets. If this does not match, the validation fails.

462
How to configure Mid-Article Unit for content via LiftIgniter
Step-by-step guide

1. Go to the appropriate Channel / Section "Application" folder, if the midArticleUnit is already there then just jump to step 3 below, otherwise select
"New" and create it

2. Select the newly created "Mid Article Unit" and set both title and name as "midArticleUnit"

3. Double click on it and:


if the Mid Article Unit was already present you have to remove the old list first by clicking on "Delete"

463
from the navigator drag "HTML Embed" into any slot available

4. Now click on "Edit" in the HTML Embed and add in the HTML area the LiftIgniter div <div class="li-mau-article"></div>

5. Save it, and activate it.

6. Enable Mid-Article Unit at Channel / Section / or sub-Section level


within AEM go to the appropriate Channel | Section | Sub-section which requires a Mid-Article unit, open the Page Properties
go to the Features tab and enable Mid-Article Unit (by default it has no setting initially)

464
7. Create and publish a new Article in Authoring
remember only new Articles will get the mid-Article logic, you will have to republish old Articles if you want them included

8. To get a mid-Article to appear, make sure the published article has enough text in two consecutive paragraphs above the middle 'Dynamic MPU'
(ie. at least 50 words)
look in the source code of the published article for the Dynamic MPU ie. "dynamicMpu section" - if there are none then you will NOT get
an Mid-Article to appear
count the number of Dynamic MPUs and look just above the middle one
in general to trigger a mid-Article it's best to have many shorter paragraphs (at least 50 words) rather than just a few large paragraphs in
an Article
there is an AEM parameter in the the AEM Web Console that controls how many words should be in a paragraph to trigger an mid-
Article (currently set as 50 words)
look for 'TMG Mid Article Service' for the parameter if you need to adjust it

9. There is also similar logic if there is just one MPU in an article, look above the MPU for two consecutive 50-word paragraphs

10. The original Mid-Article Unit implementation used a Tagged AEM List using LV15, but this has been replaced in ticket WEB-850 with a new
LiftIgniter version.
How a mid-Article Unit would appear within an Article, on the left-hand-side of the Article with text wrapping around it

465
466
How to configure Reg Walls in AEM
When you need to add a new reg-wall that is shown to customers before they can read the content. There is an AEM config page that needs to contain the
messaging and the new rules.

EG. I want to insert a reg-wall in-front of all 'Weddings' channel content.

NB: It also needs an Evolok configure but that is described separately in Confluence in document .....?

Step-by-step guide
Go to AEM CQ

1. Open the AEM folder tree structure : Telegraph > application > Paywall > Registration Wall > anonymous

2. To edit the Description and url links on the actual buttons on the reg-wall, click on the Edit button at the top of the config page (Reg button, Club
button, Login button)
This impacts all the reg-walls that have been configured

3. Click on the link at the top of the page, this will open a new page in a spreadsheet format that can be edited for the actual contents and rules for
each reg-wall

467
4. NB: if there is no specific reg-wall configured for your needs then the default reg-wall will be used (see the bottom of this config page)

5. Click within the spreadsheet to activate EDIT mode - see the pencil icon in the black bar, click on the pencil

6. Click on pencil and click on full-screen mode (last icon in the black menu-bar) to make editing easier

7. Click within the spreadsheet where you want to add the new Reg-wall and duplicate an existing row (use the 5th icon within the menu-bar) - this is
easier to edit and removes the chance of entering invalid chars

8. Over-type the details into each column:

468
8.

Match = the channel or section or tag that needs the new Reg-wall eg. politics is a channel
Headline = what appears at the top of the Reg-wall in bold and teal colour
Body = the bullet points under the main Headline, usually lists the advantages to the customer of registering
Newsletter = which newsletter will be assigned to this Reg-wall and will get sent to the customer, if no newsletter is required set this to : registr
ation&icid=........ also add any analytics required with the icid parameter
Match Type = set this to sectionid (for Channels and Sections which will equal the MATCH parameter) or tag (for tag driven content)
Online = set this to true

9. Come out of full-screen mode and save your changes (use the large tick icon)

10. Then activate the 'anonymous' file and 'paywall' folder (publish both)

11. Then publish registration-wall within the products file as well:

12. wait a few minutes for the cache to clear - and test the new reg wall on your selected Channel/Section/Tag driven page
NB: you may need an Evolok change as well to trigger this behaviour (but usually this just needs setting up once, unless the Evolok rules need
updating)

Related articles
How to configure Reg Walls in AEM
Understanding application configuration pages

469
How to Flush Content on Secure 8
When code is deployed for testing to Test 8, we need to make sure that the pages on which the feature is to be tested are flushed from Akamai and
CloudFront.

The environment is a clone of Production and, as of the time of writing of this article, the only pre-prod environment sporting a Secure domain available to
the AEM dev teams. Simply flushing the entire cache on Akamai and CloudFront is not feasible and is not a realistic scenario in the live environment.
Therefore, selective flushes, in which only specific files are removed from the cache, needs to be performed.

In order to understand what needs to happen for us to see up-to date code on a page, let's have a high-level view of the deployment architecture.

The Dispatcher serves as the first layer of cache. If it doesn't have a file cached, it requests the relevant content from the AEM publish instance. The
second layer of cache exists on Varnish. Varnish maintains separate caches for every domain. Varnish only requests files from the dispatcher if they're not
available in its own cache. The last layer of cache lies on Akamai (for HTTP domains) or CloudFront (for secure domains server over HTTPS).

When code is deployed to an environment, it is only the Dispatcher cache that gets cleared. It is, therefore, possible for one to see the most recent code
when using the Web domain (such as http://web1.aem-test8.awspreprod.telegraph.co.uk) but stale code when looking at Akamai 8 or Secure 8.

How to flush the cache correctly


Troubleshooting the cache (confirming that a cache clear will actually help)

1. Go directly to the Web or Publish instance to verify that your problem is indeed with the Varnish/Akamai/CloudFront cache only. If your code
behaves as expected on the Publish instance, flushing the right files from the cache should be sufficient.
2. Go to the Akamai/Secure page, if it looks different in any way from the one on the publisher, you need to clear the cache

Clearing the cache

1. Identify the files you need to flush from the cache. Most often, it's the case of the minified clientlibs for the pages served from the Secure domain
but that does not have to be the case. Inspect, in Chrome dev tools, an element you expect to be different to check which CSS and JS files it's
using.
2. Invalidate the Varnish cache for the domain you're using (Secure or Akamai). This can be done via a Bamboo plan:
a. Go to https://bamboo.aws.telegraph.co.uk/browse/WEBOPS-APF
b. Click Run customised
c. Specify the domain by overriding the FLUSH_HOST variable. Note that even though the plan is called Akamai Preprod Flush, it can also
be used to flush the Varnish cache for Secure 8, counterintuitive as it is.
i. For Akamai 8, this needs to be set to www.akamai8.awspreprod.telegraph.co.uk
ii. For Secure 8, this needs to be set to secure8.telegraph.co.uk
d. Specify the paths you want to flush by overriding the FLUSH_PATHS variable. This is a space-
separated list of absolute paths to the files. For EXAMPLE (but not necessarily what you need to
flush)

/etc/designs/telegraph/core/clientlibs/tmgthemes/commercial/account.min.2-92--0.js /etc/designs
/telegraph/core/clientlibs/tmgthemes/commercial/account.min.2-92--0.css

e. Trigger the plan


3. If you're testing the feature on an Akamai domain, this should be sufficient. The plan you just triggered takes care of that as well. You don't
need to read further.
4. If you need to test on CloudFront, there's one additional step you need to perform. Once the Varnish cache has been cleared, CloudFront is ready
to re-cache the files. To make it do so, simply trigger the following Bamboo plan: https://bamboo.aws.telegraph.co.uk/browse/WEBOPS-SCI-21 Mi
nd that this plan is time consuming, it takes about 15 minutes to complete. It can't be customised to flush specific files. It wipes all of the
CloudFront cache from Secure 8 as well as Secure 5. It is also impossible to choose just one environment or use it with a different environmetn.
This one is following what's called the Nuke it from orbit approach in the technical jargon.

470
Related articles
Hard Regwall (ESI)
Paywall, meter (ESI)
Optimizely and ESI Switches
How to Flush Content on Secure 8
Authoring configuration

471
Inject Sponsor logo and message using JS (spark)
To test POLAR injection of sponsorship slots, paste 3 lines into console:

ABOVE HEADLINE

$('.sponsor-slot__above-headline .sponsor-slot__logo').html($('<img/>').attr('src', 'http://placehold.it


/150x50'));
$('.sponsor-slot__above-headline .sponsor-slot__text').text('Brought to you by');
$('.sponsor-slot__above-headline').addClass('sponsor-slot--active');

BELOW HEADLINE

$('.sponsor-slot__below-headline .sponsor-slot__logo').html($('<img/>').attr('src', 'http://placehold.it


/150x50'));
$('.sponsor-slot__below-headline .sponsor-slot__text').text('Brought to you by');
$('.sponsor-slot__below-headline').addClass('sponsor-slot--active');

HEADER

$('.sponsor-slot__header .sponsor-slot__logo').html($('<img/>').attr('src', 'http://placehold.it/150x50'));


$('.sponsor-slot__header .sponsor-slot__text').text('Brought to you by');
$('.sponsor-slot__header').addClass('sponsor-slot--active');

Positioning

$('.sponsor-slot__header' / '.sponsor-slot__below-headline' / '.sponsor-slot__above-headline').addClass('.


sponsor-slot--align-top' / '.sponsor-slot--align-bottom' / '.sponsor-slot--stack');

472
Mobile previews
Mobile previews documentation:
1. How to enable the mobile devices in telegraph pages.
2. How to manage devices.

3. How to add new mobile device.

1. How to enable the mobile devices in telegraph pages.


Root page "telegraph" need to be created via Telegraph template. Now all chidrens pages should have enable mobile devices.

2. How to manage devices.


To manage mobile devices open page in Tools -> Mobile -> Device Group -> Responsive Devices and click "edit" in the top of the table. Here you can
disable/enable device in side kick and change their order. CQ path to this page "etc/mobile/groups/responsive.html" .

473
3. How to add new mobile device.
There are two ways to do this. First is follow documentation here https://dev.day.com/docs/en/cq/current/developing/emulators.html .
Second in CRXDE Lite copy example node from "/apps/telegraph/core/commons/components/emulators" and define for him name, title, height, width,
and change icon.

474
475
Related articles
Generic process for javascript debugging
Set up IntelliJ to run Jasmine unit tests

476
New Developer Application Setup 2
This list describes the steps required to setup the developer's machine

Step-by-step guide
1. Install Chrome - check you have access to email and calendar. Chrome gives access to Hangouts
Please use your login credentials (SmithJ / LastnameFirstnameInitial) to access other sites listed below;
JIRA (https://jira.aws.telegraph.co.uk/)
Confluence (https://confluence.aws.telegraph.co.uk/)
Stash (https://stash.aws.telegraph.co.uk/)
Bamboo (https://bamboo.aws.telegraph.co.uk/)
Crucible (optional, https://crucible.aws.telegraph.co.uk/)
2. Slack (https://telegraph.slack.com) - Google Auth
3. Development Environment Specific
4. Install Brew which is a command line installer - by running the instruction: /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com
/Homebrew/install/master/install)"
5. Install Java 8 using Brew: brew cask install java
Oct 2017 Update:
Running the above command it will install Java9 which is not yet fully compatible.
If you want to use brew you can take the following steps as described in https://goo.gl/g8yK5F :
brew tap caskroom/versions
brew cask search "java*"
You should be now able to see few more casks than usual, namely “java6” and “java8” etc.
brew cask info java8
brew cask install java8
Alternatively use jenv in order to have two version of Java and be able to switch between them.
6. Install Maven using Brew: brew install maven
7. Install IntelliJ Community Edition using Brew: brew cask install intellij-idea-ce
8. The project components are in the Stash repository
Stash access setup
Follow the Stash instructions to generate and install public and private keys
9. Follow commands in Jira task to setup Docker container: AEM-6878 - Setup docker aem stack RELEASED

10. Pull the following components from Stash


telegraph-component - Java component
ooyala-adobe-aem - Java component
telegraph-author - Java component
cheetah-automation - Ruby component
11. Build all Java components - using command line instruction: mvn clean install
12. Follow docker document to install these components in the local AEM docker instance
13. Now you are going to need AEM contents, hot fixes etc. Follow step by step this guide.

Related articles
AEM Core - Current release process
Creating a new Channel
How to configure Reg Walls in AEM
How to add HTML Embed in Global Navigation
How to configure Mid-Article Unit for content via LiftIgniter

477
New Developer Setup
This list describes the steps for setting up as a new developer - from scratch to a full environment.

Step-by-step guide
1. Check if you have access to the environments:
a. Google mail (john.smith@telegraph.co.uk) – use your credentials to access every other account
b. JIRA (https://jira.aws.telegraph.co.uk/)
c. Confluence (https://confluence.aws.telegraph.co.uk/)
d. Stash (https://stash.aws.telegraph.co.uk/)
e. Bamboo (https://bamboo.aws.telegraph.co.uk/)
f. Crucible (optional, https://crucible.aws.telegraph.co.uk/)
g. Sonar (http://sonar.aem.awspreprod.telegraph.co.uk/) – read access without logging in, tech leads get a dedicated account to alter sonar
Consider integrating with IDE (a guide for InteliJ here) – use full server URL and anonymous access
2. Connect to HipChat (https://hipchat.aws.telegraph.co.uk/)
a. credentials: the google account
b. if it doesn't work you may need to reset your password on the hipchat (https://hipchat.aws.telegraph.co.uk/forgot_password)
c. Optional: install hipchat client (https://www.hipchat.com/)
d. when using the client, change server when connecting: hipchat.aws.telegraph.co.uk
3. Check if you have VPN access
a. http://connect.telegraph.co.uk/
b. You must access it from an external network to see the VPN gate
c. There are some cables with outside network scattered across the office
d. The credentials for VPN are separate from the Google account above
e. Requires you to install a Citrix VPN client via the browser – must be this one, clients from other sources won't get configured
f. Once connected all your traffic goes through the VPN
4. Install Java 8
5. Setup local AEM instance,
a. version: 6.0 SP1 – but double check if still valid
b. Optional: setup a full testing stack using Vagrant
6. Install a Git client (e.g. Sourcetree),
7. Configure Git: https://confluence.aws.telegraph.co.uk/display/ML/Configure+Git
8. Checkout source code
a. Stash -> Cheetah -> aem--stack -> master
b. Stash -> Cheetah -> telegraph-component -> develop
c. Stash -> Cheetah -> ooyala-adobe-aem -> develop
d. Stash -> Cheetah -> telegraph-author -> develop
e. Stash -> Cheetah -> telegraph-web-shared-libs -> develop
9. Install Apache Maven, and
a. When using AEM on a port different than 4502, put two properties into your settings to point to your instance: core.instance.url and
telegraph.instance.url
10. For project (a) run docker-compose up -d to start docker
For project (b,c,d) Build and install the three projects (mvn clean install crx:install).
For the fifth project to build and deploy you can run ./gradlew . A README.md file present for more information.
11. Install IDE of your choice and import the projects
12. Check out more hints on AEM Development

Nitro specific setup


1. Install Postman Chrome plugin

Related articles
AEM Core - Current release process
Creating a new Channel
How to configure Reg Walls in AEM
How to add HTML Embed in Global Navigation
How to configure Mid-Article Unit for content via LiftIgniter

478
Optimizely and ESI Switches
Previously the Optimizely script was served Synchronously via AEM on all pages in the <head> tag.

This was a major performance hit and in order to mitigate this as much as possible we switched to serving Optimizely via Akamai. The switches are simple
booleans that dictate how to serve the optimizely script e.g. in the head or the body, in sync/async loading.

The switches work based on path matching e.g. all pages under and including ".../travel/" will have the effects of the travel switch.

Details as follows:
There are 6 main "switches" that reposition the optimizely script for the site.

1. Global switch https://bamboo.aws.telegraph.co.uk/browse/WOPC-OPEN - sync in head.


2. Global switch https://bamboo.aws.telegraph.co.uk/browse/WOPC-OPDIS - async in body.
3. Travel Switch https://bamboo.aws.telegraph.co.uk/browse/WOPC-OTPRODE - sync in head.
4. Travel Switch https://bamboo.aws.telegraph.co.uk/browse/WOPC-OTPRODD - async in body.
5. Financial Services Switch https://bamboo.aws.telegraph.co.uk/browse/WOPC-OFSPRODE - sync in head
6. Financial Services Switch https://bamboo.aws.telegraph.co.uk/browse/WOPC-OFSPROD - async in body

The global switches will change the position and load method of the optimizely script throughout most of the site. However Travel and Financial Services
(FS) have their own independent switches as they have their own A/B testing teams that require autonomy to run and stop their experiments.

The result of this will be could be in Global site's optimizely script will be loaded async in the body while the FS script is loaded in the head synchronously.

Important Note on Secure Pages

Secure pages, at the time of writing this, are served via CloudFront and does not support the global switch, there is currently a check in the
code base for the "/secure" path and the optimizely script is included on those pages via AEM. This should be removed when we serve these
pages via Akamai.

Hard Regwall (ESI)


Paywall, meter (ESI)
Optimizely and ESI Switches
How to Flush Content on Secure 8

479
Performance impact of Inheritance Value Map
Performance impact of Inheritance Value Map
Objective
Style switching functionality sets a property in a root page of a potentially extensive content tree. To access this property we are using
InheritanceValueMap so that all subpages can access this property. This mechanism may be a performance bottleneck since ever rendered page must
read properties of parent pages up to the root level. This has O(log(n)) impact on page rendering time, where n is depth of subpage in relation to the root
page.

Alternative option is to use backing OSGi service that can read this property once and serve it to every page. Performance impact of this solution would be
O(1).

Performance needs to be measured on page load time on two possible approaches.

Test Procedure
For the purpose of the test a script has been written that lies in 'CHEET-430-performance-of-style-switching' branch in Stash repository.

Tests are run inside Performance template created for that purpose that has associated WcmUse class that contains test code. To execute the tests, one
must create a new page using this template and open it. While testing such page was created under '/content/performance/' path.

Before a test is executed test tree of pages is created under /content/performance page. Size of test tree can be controlled by accessing Page Properties
of /content/performance page. Tree width determines how many children will each page have. Tree depth will determine maximum length of a path from
/content/performance/test-root to a leaf page (one that does not have any subpages). Test-root page is a parent page under which all other sub pages for
a test are created. 'testProperty' that is being accessed is set on '/content/performance' page.

Test generate a separate test-root page for it's own purpose to avoid use of CRX package. After tests are complete generated content structure is
removed.

Each test performs following: a resolution of a path to a resource, adapting resource to a page and the obtaining a 'testProperty' property from the root
page. First test uses InheritanceValueMap to retrieve value of that property. Second test uses

1. Start Timer
2. Get random path from generated tree structure
3. Resolve a path to a resource
4. Adapt resource to a Page
5. Retrieve property
6. Stop Timer

Difference two test is in step 5. First Test creates HierarchyNodeInheritanceValueMap object and invokes getInherited method to obtain 'testProperty'
which is set on /content/performance page. Second one uses SlingScriptHelper to obtain reference to OSGi Service. We use OpenTagService as this
performs a simple operation of retrieving a text property.

Test Results
Same tests have been run for differently sized content. Tree depth and tree width are content generation parameters explained in Test Procedure section.
Pages Resolved illustrate how many pages were actually rendered in each of the test. All pages load time is the time of the whole test execution. Avg
single page load time ilustrates the average time it took to load a single page in the particular test run. All times are in milliseconds.

Inheritance Value Map Tests OSGi Service Tests

Test Run Tree Depth Tree width Pages Resolved All Pages Load time Avg single page load Time Time (OSGi) Avg single Page Load

1 3 3 39 24 0.615384615 3 0.076923077

2 3 3 39 23 0.58974359 2 0.051282051

3 3 3 39 17 0.435897436 2 0.051282051

4 5 2 62 44 0.709677419 4 0.064516129

5 5 2 62 55 0.887096774 5 0.080645161

6 4 3 120 182 1.516666667 9 0.075

7 4 3 120 60 0.5 8 0.066666667

8 4 3 120 51 0.425 8 0.066666667

9 3 6 258 108 0.418604651 12 0.046511628

480
10 3 6 258 109 0.42248062 15 0.058139535

11 3 6 258 102 0.395348837 12 0.046511628

12 4 4 340 316 0.929411765 17 0.05

13 4 4 340 157 0.461764706 18 0.052941176

14 4 4 340 317 0.932352941 19 0.055882353

15 5 4 1364 1111 0.814516129 175 0.12829912

16 5 4 1364 1162 0.851906158 75 0.054985337

17 5 4 1364 1104 0.809384164 157 0.115102639

18 5 5 3905 4281 1.096286812 357 0.091421255

19 5 5 3905 4091 1.047631242 291 0.074519846

20 5 5 3905 4180 1.070422535 302 0.077336748

21 6 4 5460 6866 1.257509158 491 0.08992674

22 6 4 5460 6585 1.206043956 405 0.074175824

23 6 4 5460 7168 1.312820513 455 0.083333333

24 6 6 55986 151261 2.701764727 253872 4.534562212

25 6 6 55986 1074308 19.18886865 31248 0.558139535

26 6 6 55986 466241 8.327814096 24078 0.430071804

481
Troubleshooting Advice
Differences between author and publisher
Common cause for such errors is differences in the packages deployed. First steps for troubleshooting should be:

1. Login to crx/packmgr on both author and publisher


2. Ensure same Telegraph packages on author are deployed on publisher
3. Ensure packages have the same versions

Related articles
AEM Core - Current release process
Creating a new Channel
How to configure Reg Walls in AEM
How to add HTML Embed in Global Navigation
How to configure Mid-Article Unit for content via LiftIgniter

482
UI Environment Cheetsheet
UI Environments

Information on this page is deprecated. Please discard

Environment Location Link

DEV-UI CQ Author azaem-dev3:4502 http://azaem-dev3.awsdev.telegraph.co.uk:4502/

DEV-UI CQ Publish azaem-dev2:5403 http://azaem-dev2.awsdev.telegraph.co.uk:5403/content/telegraph/news.html

DEV-UI Dispatcher azaem-dev1:80 http://azaem-dev1.awsdev.telegraph.co.uk/news

TEST HTML Mocks azaem-mock1-test:80 http://azaem-mock1-test.awsdev.telegraph.co.uk/html/


azaem-mock2-test:80 http://azaem-mock2-test.awsdev.telegraph.co.uk/html/

DEMO HTML Mocks azaem-mock1-uat:80 http://azaem-mock1-uat.awsdev.telegraph.co.uk/html/


azaem-mock2-uat:80 http://azaem-mock2-uat.awsdev.telegraph.co.uk/html/

UI Bamboo Builds and Deployments


Build Notes

Build Design and Deploy to DEV-UI Use to push the design (/cq/core-design) to the DEV-UI author and publish

Build Mocked HTML and Deploy to DEV Use to create a new HTML Mocks drop (use with deployment project below)

Deploy HTML Mocks Use to push HTML mocks to TEST and DEMO environments (use with build project above)

Deploy Cheetah Use to push latest build to DEV-UI environments (please ignore others)

Related Articles
Generic process for javascript debugging
Set up IntelliJ to run Jasmine unit tests

483
Understanding application configuration pages
Read this when cConfiguring a Channel or learning how the site is structured.

Step-by-step guide
Configuration content can be placed at /content/telegraph/application and, optionally, in channel-specific configuration folders ( /content
/telegraph/fashion/application, /content/telegraph/art/application). Similar configuration can be provided for Clusters and even
Folders. It will be inherited by all descendants of the given page.

An application node can contain the following settings:

1. Error pages - error documents, see Error Pages


2. Navigation - configuration of the global and local navigation, see Navigation
3. Paywall - content to be displayed on the paywall (different versions for registered and anonymous users), see Paywall, meter (ESI)
4. Dynamic - content to be consumed by the Most Viewed List component.
5. Snippets - snippet pages with content that can be re-used by the Snippet Reference component.

Related articles
How to configure Reg Walls in AEM
Understanding application configuration pages

484
Using Sponsor Slots
Sponsor slots have been placed on certain templates that enable Spark to add client campaign assets to one of three agreed positions on the page.

The templates this applies to are:

Article 2
Gallery
Hub
Destination
Cluster
Topics

The slot positions are:

Header - used for Sponsorship (editorial content)


Above the Headline - used for Sponsorship (editorial content)
Below the Headline - used for Sponsored content (commissioned or advertorial content)

Spark will usually use Polar for adding client assets for Sponsorship campaigns and the CMS for Sponsored campaign. Technically the implementation
lets them use either Polar or the CMS for all three positions and how they choose to do this is up to their discretion.

Polar Notes
Please fill in cheat sheet of positions and class names and slot markup structure

Header slot

<div class="sponsor-slot sponsor-slot__header">


<span class="sponsor-slot__text"></span>
<span class="sponsor-slot__logo"></span>
</div>

Above Headline slot

<div class="sponsor-slot sponsor-slot__above-headline">


<span class="sponsor-slot__text"></span>
<span class="sponsor-slot__logo"></span>
</div>

Below Headline slot

<div class="sponsor-slot sponsor-slot__below-headline">


<span class="sponsor-slot__text"></span>
<span class="sponsor-slot__logo"></span>
</div>

485
Web images with Akamai Image Manager
Background
Currently, when images are uploaded to the DAM, several renditions are generated. These renditions are then made available to be used across the
various TMG platforms.

We are migrating to Akamai Image Manager which operates on the original image. It create a set of renditions and caches them on Akamai when the
image is requested. This removes the need to store the different renditions on the DAM. Instead, Akamai will serve the required rendition based on
querystring parameters in the image URL.

Updating URLs
Instead of requesting one of the old files, you should be requesting the original image. Make sure that the renditions aren't appearing in the URL -xsmall, -
small, -medium, -large etc...

<img src="/content/dam/Travel/Tours/orta-small.jpg" alt="...">


<img src="/content/dam/news/2017/04/11/TELEMMGLPICT000125685463-
large_trans_NvBQzQNjv4BqDS39VuaGS1Lsrey3a1J6Ta6k0GqVa7pZR6VaWbmH4zk.jpeg" alt="...">

// Should be...
<img src="/content/dam/Travel/Tours/orta.jpg" alt="...">
<img src="/content/dam/news/2017/04/11
/TELEMMGLPICT000125685463_trans_NvBQzQNjv4BqDS39VuaGS1Lsrey3a1J6Ta6k0GqVa7pZR6VaWbmH4zk.jpeg" alt="...">

Image policies
Image policies are predefined sets of rules that can be applied to an image. The rules define: the various widths to generate, image quality, and
transformations to apply (greyscale, opacity, resize, etc).

When an image is requested, a policy is applied to it. To specify a policy, add impolicy=<policyName> to the querystring. If no policy is set, then the auto
policy is used.

// Apply the 'thumbnail' policy


<img src="/content/dam/Travel/Tours/orta.jpg?impolicy=thumbnail" alt="...">

// Fallback to 'auto' policy


<img src="/content/dam/Travel/Tours/orta.jpg" alt="...">

Available policies

Policy Widths Quality Transformations

auto 320, 480, 640, 960, 1280, 1920, 5000 Medium High None

thumb 160, 320, 640 Medium High None

square 160, 320, 640 Medium High Resize (fill / 640 x 640)

poster (tbd)

banner (tbd)

logo (tbd)

NOTE: If no widths are specified, AIM uses the defaults 320, 640, 1024, 2048, 5000.

There is a limit of 32 derivative widths on the API token across all policies, including default values.

Image widths
The width of the image returned is determined by the screen size of the device. AIM looks up the screen size, and selects the next size up in the policy's
range of widths. If there isn't a larger size, then the next size down is returned.

In most cases, you will want an image that is smaller than the screen size. To do this, pass a hint about the width you require. To specify a width, add imwi
dth=<size> to the querystring.

486
// Apply the 'thumbnail' policy and return an image at least 200px wide
<img src="/content/dam/Travel/Tours/orta.jpg?impolicy=thumbnail&imwidth=200" alt="...">

// Fallback to 'auto' policy and return an image at least 620px wide


<img src="/content/dam/Travel/Tours/orta.jpg?imwidth=620" alt="...">

NOTE: that this is just a hint. If the policy does not have 200 or 620 in the policy's range of widths, then the next size up will be returned. If there isn't a
larger width, then the next size down is returned.

Fixed width images


When you know an image won't change size regardless of screen size or layout, use imwidth to specify the size you want.

<img src="/content/dam/Travel/Tours/orta.jpg?imwidth=200" alt="...">


<img src="/content/dam/Travel/Tours/orta.jpg?impolicy=thumbnail&imwidth=200" alt="...">

You can specify a retina version of the image using the srcset attribute and the x suffix.

<img
src="/content/dam/Travel/Tours/orta.jpg?imwidth=200"
srcset="/content/dam/Travel/Tours/orta.jpg?imwidth=400 2x"
alt="...">
<img
src="/content/dam/Travel/Tours/orta.jpg?impolicy=thumbnail&imwidth=200"
srcset="/content/dam/Travel/Tours/orta.jpg?impolicy=thumbnail&imwidth=400 2x"
alt="...">

Responsive images
If the image width changes in response to the viewport width, use the sizes attribute to tell the browser what the width will be at each breakpoint. The
value with no media expression is the fallback when none of the expressions can be matched. The other values should match up with the breakpoint
variables used in CSS.

Use the srcset attribute to tell the browser which image sizes are available. In this example, the three different values specified in the media expressions
are used. For each of these images, a double sized image is also added for 2x resolutions.

Given this information, the browser can calculate the best image to request based on the current viewport width and pixel density.

NOTE: When the sizes attribute is used, srcset values must use the w (width) unit. Pixel density is not supported in this case.

<img
src="/content/dam/Travel/Tours/orta.jpg?imwidth=450"
sizes="(min-width: 1008px) 620px, (min-width: 730px) 700px, (min-width: 480px) 450px, 100vw"
srcset="/content/dam/Travel/Tours/orta.jpg?imwidth=450 450w,
/content/dam/Travel/Tours/orta.jpg?imwidth=620 620w,
/content/dam/Travel/Tours/orta.jpg?imwidth=700 700w,
/content/dam/Travel/Tours/orta.jpg?imwidth=900 900w,
/content/dam/Travel/Tours/orta.jpg?imwidth=1240 1240w,
/content/dam/Travel/Tours/orta.jpg?imwidth=1400 1400w"
alt="...">

Art directed images


When the physical image needs to change between breakpoints then use a picture element. An example might be a logo that should appear in it's
abbreviated form on mobile, and its full form on desktop.

<picture>
<source
media="(min-width: 730px)"
srcset="logo-expanded.jpg?imwidth=320, logo-expanded.jpg?imwidth=640 2x">
<source
media="(min-width: 480px)"
srcset="logo-square.jpg?imwidth=250, logo-square.jpg?imwidth=500 2x">
<img

487
src="logo-icon.jpg?imwidth=100"
srcset="logo-icon.jpg?imwidth=200 2x"
alt="...">
</picture>

Retina image problems


There is a risk that images may not always be displayed at the correct size. This is due to the behaviour of AIM when the requested imwidth is not
available. Instead, a smaller image is returned which may not fit the rendering area. This can happen in one of two ways... if the policy widths are too
small, or the original image is too small to cover the policy widths.

This is more likely to happen with retina images, but could also happen with 1x images. The problem is that we are telling the browser that images are a
certain width using srcset, but can't guarantee that width is being returned by AIM.

The browser does not check the returned image size. It trusts that the 2x image large enough and scales the rendering area down so that the larger image
will fit. If the retina image is too small, then it will not expand to fit the area.

1x image is 620px - content area is 620px 2x image is 750px - content area is 620px

The fix
In most cases the mages returned will be larger than requested and will need scaling down. In the cases that they are smaller, then they will need scaling
up. As we can't be sure when this will happen, it's better to code for both cases. This isn't ideal as scaling up can affect image quality, however in this case,
it's the only solution.

Normally you would want to apply a max-width of 100% to responsive images, but instead we need to apply that to the width instead.

.my-image {
width: 100%;
}

Browser support
Support for srcset and picture elements is good, but was only recently adopted in IE, Safari, iOS, and Android. Make sure that the src attribute is still used
so that older browsers have a fallback.

Client hints may be something for the future, but has little support today.

Useful links
https://www.mydevice.io/
http://edc.edgesuite.net/

488
https://developers.google.com/web/fundamentals/design-and-ui/responsive/images
https://css-tricks.com/responsive-images-css/

489
Technical

490
Application Monitoring
AEM-2017 - TRANS: Define, design and configure application monitoring CLOSED

Monitoring provided by the AEM platform


Server availability
Disk Space / CPU / Network (Nagios?)
AEM instance monitoring

Authoring specific monitoring

Front end Size: RELEASED


JIRAs: AEM-1223 - Implement New Relic for Authoring Tool - Front end monitoring
monitoring M

Description:

Monitor JavaScript errors occurred in production environment. NewRelic has feature for this.

Ideally we should get notifications if error rates go up and have access to historical data of total error numbers and each error type categorised
separately.

Monitoring could be implemented in CI and DEMO environment to catch issues before release is done.

Benefit:

If we release changes that cause unexpected errors for the users of the application this can notify us immediately allowing quick fixing or release
rollback.

Automated sanity Size: CLOSED


JIRAs: AEM-3005 - Automated sanity checking - Basic
checking M-L
AEM-3007 - Automated sanity checking - Advanced CLOSED

Description:

Use Selenium to login to Authoring production environment and use it to ensure basic functionality is working as intended. There's limitations what can
be safely tested (e.g. can't modify content)

Benefit:

Supplement platform monitoring tools with scripts that replicate actual user behaviour. Get quick warnings from number of issues that could cause
unavailability of the tool.

API layer response Size: M CLOSED


JIRAs: AEM-3003 - Implement New Relic monitoring for Authoring Tool - API layer
times

Description:

Monitor response times for each API to identify possible performance issues in production. For example if API response times increases from 150ms to
600ms this could be still reasonably ok from users point of view but should trigger investigations into what has changed.

Same monitoring can be applied to CI environment to produce data with less fluctuations.

NewRelic can be potentially used for this.

491
Benefit:

Production performance issues can be noted as soon as they happen and in some cases fixed before there's significant impact on users. If CI
environment is also monitored this can be used to avoid releasing changes that would have negative performance impact on the users.

Elasticsearch Size: ? CLOSED


JIRAs: WS-3088 - Ensure Authoring Elasticsearch is production ready.
monitoring

Description:

Elasticsearch should be monitored in some way. This could be responsibility for WebOps?

Monitoring should include performance and disk space / index size.

Benefit:

By monitoring Elasticsearch it's possible to react to incidents that can cause Authoring tool becoming unavailable before they happen.

API monitoring Size: RELEASED


JIRAs: AEM-3004 - API monitoring - Basic
S-M

Description:

Monitor Authoring APIs using HTTP calls. This is easier and more reliable than Selenium/WebDriver based monitoring because it can be done with
command line tools like curl.

Benefit:

Ensure all monitored APIs are available and respond in acceptable time. Can be quite simple to implement and maintain compared to Selenium
/WebDriver approach mentioned above but doesn't monitor possible problems with front end code.

492
Asynchronous Solution
General
This section contains information about asynchronous solution in Authoring project.

Asynchronous browser communication


Asynchronous Communication - Known issues
PubNub Configuration

493
Asynchronous browser communication
Background
There's need to send asynchronous messages to browser for example when events take place in server. First story to require this is AEM-1741

This will implemented using PubNub but implementation is done in a way that it's easy to switch to alternative solution is so desired.

Channel names
Messages in PubNub are sent to named channels. This can be used to ensure that messages are only sent to clients which are interested in those.

Channel name will be of the format [ENVIRONMENT]_[TYPE]_[ID] , for example PROD_STORY_dd9d02ca-2a46-11e5-8c65-063dfce7e91f

Environment name is added so that single PubNub application can be used for all environments without having to worry about conflicts.

Message type 'STORY'


This message is broadcasted when there is change to story (e.g. article, gallery) status.

Field Description

pageId Authoring ID for the story that has changed

action Event that took place. One of 'published' or 'unpublished'

timestamp Unix timestamp when event took place.

server Computer name which sent this message. For debugging use only.

Sample message

{
"pageId": "dd9d02ca-2a46-11e5-8c65-063dfce7e91f",
"action": "published",
"timestamp": "1438852709000",
"server": "cms1.aem-dev6.awspreprod.telegraph.co.uk"
}

Message type 'NOTIFICATION'


This message is broadcasted when there is information that that should be showed to everybody looking at the story. Front end is not expected to do
anything else than display this message (for example it shouldn't try to re-publish based on message contents)

Field Description

pageId Authoring ID for the story that has changed

message Clear text message that should be shown to user.

timestamp Unix timestamp when event took place.

server Computer name which sent this message. For debugging use only.

494
Sample message

{
"pageId": "dd9d02ca-2a46-11e5-8c65-063dfce7e91f",
"message": "Failure publishing article",
"timestamp": "1438852709000",
"server": "cms1.aem-dev6.awspreprod.telegraph.co.uk"
}

495
Asynchronous Communication - Known issues
General
This page contains information about known issues related to the asynchronous communication between frontend and backend

Known Issues
1. Page won't be notified about activation/deactivation, when any of the parent pages were activated/deactivated.
2. Story won't be notified about success/failure of activation/deactivation of that story, when replication queue has been cleared.
3. Currently there is no retry limit set on replication event, so it means that story will be replicated until it will end with success. This means, that
message with type NOTIFICATION will be sent each time, whenever replication fails.
a. If retry limit will be set, then message with type NOTIFICATION will be send only, when retry limit will be reached.

496
PubNub Configuration
General.
This page contains information about configuration of integration with PubNub.

Channel name configuration


PubNub channel name configuration can be found under

/system/console/configMgr

Please search for Channel Name Provider

Three fields can be configured:

1. Instance name - property should be set to PROD for production environments, or NONPROD (default value) for every other environment

PubNub keys configuration


PubNub keys configuration can be found under

/system/console/configMgr

Please search for PubNub Key Provider.

Configuration contains three fields:

1. Publish key
2. Subscriber key
3. Secret key

All fields must be filled in to integrate with PubNub

497
Authoring Automation tests
Automated Tests - useful links
Solutions

498
Automated Tests - useful links
Ruby

ruby website: https://www.ruby-lang.org/

online ruby course: http://www.codecademy.com/tracks/ruby

Most important frameworks we use

site prism - this wraps html into page objects: https://github.com/natritmeyer/site_prism

capybara - we use this to wrap selenium calls: https://github.com/jnicklas/capybara

BDD

http://en.wikipedia.org/wiki/Behavior-driven_development

cucumber - bdd framework: http://cukes.info

https://github.com/cucumber/cucumber/wiki

Selenium

ruby selenium: https://code.google.com/p/selenium/wiki/RubyBindings

technical doc ruby / selenium: http://selenium.googlecode.com/git/docs/api/rb/index.html

Our code can be found in stash under:

http://stash.aws.telegraph.co.uk/projects/CHEET/repos/cheetah-automation/browse

Other Confluence pages

Test Automation

Vagrant

Running tests in command line

499
Solutions

500
Remote image upload
General
This page describes solution which was used to write test for AUT-63 - Upload a new image to Assets RELEASED .

Solution
Test which was quite simple to write, was working only on local machine, or rather: on local browser.

Our jobs in Bamboo run tests on the remote browser. Tests are fired on CentOS environments, (and also here all ruby code is executed), and browser is
opened on Windows environements.

Tests were failing on bamboo, because we tried to upload image, which was generated on CentOS, and Windows machine didn't have access to those
images.

The simplest solution would be to just upload images to Windows machines, and hardcode the path to those images, but this solution had some
drawbacks:

Everyone which was firing the test, would need to have test images in the same path
Bamboo uses windows machines, so when we would hardcode the path to file, automatically tests couldn't be fired on Unix machines (because of
Windows path)
When the path will change, everyone will also have to change on their local machines, and also it will have to be changed on every Windows
machines

Because of those reasons, we needed better solution, and this solution is provided by Selenium out of the box.

File detector is an object which checks if path is a path on the machine, which hosts the browser, or is a path on machine from which tests are fired.

Such check is done when test attach file to input.

To attach file to input you can use send_keys or attach_file. The second one is better, because internally, it checks if file exists.

If we would use send_keys function, we would have to check if file exists in File detector.

Adding File detector


File detector can be added only to Remote Web Driver instance. This is very important, as if you will try to add it to normal driver, you will get unknown
method exception.

So before you will add it, you need to check if we are using remote browser. In our Ruby framework you can do that by adding simple if statement:

if ENV['REMOTE'] =~/grid/i

end

Thanks to this, we will add file detector only when we really need it.

How we can add file detector? Here is the code:

selenium_driver = page.driver.browser
selenium_driver.file_detector = lambda { |args|
args.first.to_s
}

We take driver from the page and we take arguments passed to file_detector. We take first element of the array and we return them as string. That's all

If we would use send_keys we would have to check if the file with given name (first element of the args array) exists.

501
Authoring Coding Standards
General
This page describes coding standards for authoring.

Test Driven Development


Dealing With Bugs
Coding Standards
Java Standards:
Sigthly Standards:
Groovy Scripts standards
Code Formatting
Code quality cleanup (Sonar warnings)
Naming Conventions
Fluent APIs Coding Convention

Coding Standards
Java Standards:
All Java-files should contain Javadoc (at least for the header)
Comment should be added for non trivial business logic in code.
Not allowed to use deprecated classes
No author / developer names in the code
No code in comment i.e. do not comment out code, delete it instead
Use Hamcrest notation for unit test assertion
Constants should be always used instead of literals.
New constants definitions should be created only if one isn't created yet. They should reside inside class they are logically connected to.
Reuse Apache Commons functionality whenever possible. Eg. String utilities, date formatting, array/hashmap creation
Avoid returning 'null' and prevent your code from failing when a null parameter is used. Eg. perform null check if method can return null, avoid
method chaining and write methods that return an object.
There should be no compiler warnings in java classes, including tests. If you really cannot refactor your code to avoid warning, use @SuppressWa
rnings annotation as a last resort.
Avoid casting by using commons PropertyUtils and generic methods (eg valueMap.get("property", String.class) )

Groovy Scripts standards


Avoid recursing through all the nodes under /content. Instead query for specific nodes that require alternations.
Log both to stdout and log file, to provide feedback in case the script will make groovy console unresponsive.
Scripts must start with related JIRA issue key
Always provide dry-run mode that only logs changes to be made. Be careful when invoking other services, as they may make changes on their
own or commit your session.
Use global variable REAL_RUN to indicate weather it's a real_run (REAL_RUN == true) or dry_run (REAL_RUN == false //default)
Include details if any content needs to be activated after running the script
Script should have a brief header or class comment with brief description of what is to be done.

Code Formatting
Code should be formatted according to formatter below which is standard build-in eclipse style with extended line wrap at 120 characters (including
comments).

IntelliJ formatter
Eclipse formatter

Code quality cleanup (Sonar warnings)


Authoring has a sonar build which is executed with every CI build. If sonar fails, CI build will also fail.

Currently the main rules for authoring are:

Unit Test Coverage level above the 70%


0 blockers
0 criticals

Naming Conventions
Java naming convention defined by Oracle should be followed for naming Java classes, Interfaces, Methods, Variables, constants. (http://www.
oracle.com/technetwork/java/codeconventions-150003.pdf) From Document:

502
Identifier Rules for Naming Examples
Type

Classes Class names should be nouns, in mixed case class Raster;


with the first letter of each internal word capitalised i.e. UpperCamelCase. Try to keep your class names class
simple and descriptive. ImageSprite;
Use whole words—avoid acronyms and abbreviations (unless the abbreviation is much more widely used than
the
long form, such as URL or HTML)

Interfaces Interface names should be capitalised like class names i.e. UpperCamelCase. interface
RasterDelegate;
interface
Storing;

Methods Methods should be verbs and named in lowerCamelCase. The method name should be descriptive and run();
should do only one thing (refactor if necessary). runFast();
getBackground
();

Variables Except for variables, all instance, class, and class constants are in lowerCamelCase. Internal words start with int i;
capital letters.Variable names should be short yet meaningful. char *cp;
The choice of a variable name should be mnemonic— that is, designed to indicate to the casual observer the float myWidth;
intent
of its use. One-character variable names should be avoided except for temporary “throwaway” variables.
Use wrapper of the primitive classes where possible e.g. use Integer instead of int

Constants The names of variables declared class constants and of ANSI constants should be all int
uppercase with words separated by underscores (“_”). (ANSI constants should be avoided, for ease of MIN_WIDTH =
debugging.) 4;
int
MAX_WIDTH
= 999;
int
GET_THE_CP
U = 1;
Template and components : Followings are the common naming conventions that are followed for templates and components:
lower Camel case: Example: listChildren, adaptiveImage, userInfo
Node names should be all lowerCamelCase
The recommended coding standard for html/css can be found using the following link http://google-styleguide.googlecode.com/svn/trunk
/htmlcssguide.xml
OSGI Services/Components:
Vendor: Telegraph Media Group
Service/Component Label - put "TMG -" prefix before name, ex: TMG - MyService
Always put description
Use short property names in configs (without package and service name - just property name)

503
Authoring git standards
General
This page describes git standards in authoring projects

Git standards

Git configuration

config user.name "Name Surname"


git config user.email "name.surname@telegraph.co.uk"
git config branch.autosetuprebase always
git config --global core.autocrlf input

Commits
All your commits should have JIRA Ticket in their name.

Example commit name: AEM-1234 Implemented amazing feature

In case of bugfixes, please put the JIRA ID of the bug, even if the bugfix is done on the story branch. For sub-tasks put both sub-tasks and main story ID.

Branches
Branches should be created in JIRA. This ensures consistent naming in each repository.

If branch was already created, please use the same name for each repository. (Cheetah automation, telegraph-author, telegraph-component, ooyala, acs-
aem-commons-fork).

Git flow
Our git flow is described here: Gitflow branching model

504
Authoring performance testing
Performance testing in July / August 2015
http://www.qualitestgroup.com/ was hired to implement performance testing framework for AEM platform and/or Authoring. Work they did was based on Gat
ling

At the same time Authoring - Performance Test Strategy v1.0.docx was created.

Testing scripts are available in a branch https://stash.aws.telegraph.co.uk/projects/CHEET/repos/telegraph-author/commits?until=feature%2FAEM-1625-


api-performance-tests and have been since updated by TMG staff.

It's possible (or even likely) that this work will be foundation for the performance testing in AEM going forward.

Performance testing in October 2015


Because previous performance testing did indicate that there are some issues with the performance that were fixed by implementing Elasticsearch on
Authoring it was required to repeat performance testing before Authoring tool was taken into production use. Due limited time and skills this was
implemented with JMeter

Typical tasks and and their duration was documented at https://docs.google.com/a/telegraph.co.uk/spreadsheets/d


/1myzgyQRvYDZP56NWw1Bz5hTaRrSLVdU5zdwfLe-wqSc/edit?usp=sharing

Scripts are in author-performance testing directory.

Running tests

1. Install JMeter
2. Install Standard Set plugins from http://jmeter-plugins.org/
3. Copy JSON parser minimal-json-0.9.5-SNAPSHOT.jar file from 'lib' directory to JMeter lib directory.
4. Use create-users.groovy script to configure sufficient number of test users.
5. Open test plan AuthoringTest.jmx
6. Select environment and configure load
7. Run the test.

Test runs executed were with 10 users and by modifying speed parameter multipliers were added to simulate 50 and 200 users.

Results

Results are documented at

https://docs.google.com/a/telegraph.co.uk/document/d/1kDPmB7e-QGkPydBpXbu6lhUsThhMvTJSHwXyH6K9leI/edit?usp=sharing
https://docs.google.com/a/telegraph.co.uk/document/d/1xzbua27jSvukOUwZxldVZRGoV8cNZb5wIiwCXUAwED8/edit?usp=sharing

Current status is that we are ok with 10 users but 50 users have capability of causing problems.

505
FS Performance Testing
Performance testing
Running tests

1. Install JMeter
2. Install Standard Set plugins from http://jmeter-plugins.org/
3. Copy JSON parser minimal-json-0.9.5-SNAPSHOT.jar file from 'lib' directory to JMeter lib directory.
4. Use create-users.groovy script to configure sufficient number of test users.
5. Open test plan AuthoringTest.jmx
6. Select environment and configure load
7. Run the test.

Test runs executed were with 10 users and by modifying speed parameter multipliers were added to simulate 50 and 200 users.

Results

Results are documented at

https://docs.google.com/a/telegraph.co.uk/document/d/1kDPmB7e-QGkPydBpXbu6lhUsThhMvTJSHwXyH6K9leI/edit?usp=sharing
https://docs.google.com/a/telegraph.co.uk/document/d/1xzbua27jSvukOUwZxldVZRGoV8cNZb5wIiwCXUAwED8/edit?usp=sharing

Current status is that we are ok with 10 users but 50 users have capability of causing problems.

506
Installing & running jmeter
Two options here.

1. Download the pre-build jmeter (apache-jmeter-2.13.zip) containing all the required plugins and jars to open Authoring Performance Test plan
2. Configure everything manually by following these steps:
a. Download jemter 2.13 from apache jmeter website http://jmeter.apache.org/download_jmeter.cgi
b. Download and install Jmeter Standard, Extra & ExtraLibs from http://jmeter-plugins.org/downloads/all/
c. Download and install following from Maven Central Repository:
i. json-smart-1.2.jar
ii. json-path-0.9.0.jar
iii. json-lib-2.4-jdk15.jar
iv. minimal-json-0.9.4.jar
3. Run Jmeter & open telegraph-author/author-performance/src/test/jmeter/AuthoringTest.jmx file
4. Follow the steps in this link.
5. Select & enable correct set of properties to use (Depending on your environment)
6. Select and enable the type of journey you want run
7. Run the test
8. During test run:
a. Carefully observe AEM error.log file for any unexpected errors
b. Carefully observe View Result Tree Listener to see if lots of calls are failing for no apparent reasons. If they do, stop the test and
investigate before proceeding further
c. Carefully observe jp@gc - Response Times vs Threads Listener to see if response times are unreasonably high. If they are, stop the
test and investigate before proceeding further
9. At the end of the test, look at the numbers in Summary Report
10. If loadsophia plugin is enabled, them you can also view tests at loadosophia.org (Account details to be added later)

507
Performance Test: Pre-conditions
1. Select Performance Environment to run test against
2. Purge all old data from AEM and load latest Production data dump into it:
https://bamboo.aws.telegraph.co.uk/deploy/viewEnvironment.action?id=52953315
3. Create required number of performance users using groovy shell script. To run, http://aem-cmsa-xxxx.awspreprod.telegraph.co.uk:4502/etc
/groovyconsole.html
4. Make sure Authors used in performance tests are available. (Install this package if they are not there).This will change in the future when
performance test search and select Authors at runtime.
(3,4 are automated here - https://bamboo.aws.telegraph.co.uk/chain/admin/config/defaultStages.action?buildKey=APA-APA there is also a step to
reindex assets and pages on the environment)
5. Deploy Release candidates (Core, then Authoring if applicable):
https://bamboo.aws.telegraph.co.uk/deploy/viewEnvironment.action?id=52953186
https://bamboo.aws.telegraph.co.uk/deploy/viewEnvironment.action?id=52953187
6. Make sure NewRelic agent is enabled and working(OSGI configuration has switch), only if applicable
7. Make sure NewRelic server agent is enabled and working, only if applicable
8. Follow 'Steps after fresh data copy from Production to Performance environment' below
Note from Owen: only step 5 should be necessary, as all other parameters are kept in Chef/ AEM codebase. Please highlight if these are
incorrect: if nothing is highlighted in the next few weeks I will remove these steps from the page. We hope to automate step 5 soon.
9. Running JMeter test via Bamboo

Steps after fresh data copy from Production to Performance environment


1. Check elastic search config
2. Check Author JVM params
3. Make sure that agents are pointing to correct publishers and dispatcher instances
4. Check that dispatchers are paired up with correct publishers
5. Create five new live articles and put them in Major news and top news snippet
6. Make sure that Author & Publish agents are configured correctly e.g. timeout settings
7. Ensure correct oak indexes are deployed and that indexes are rebuilt correctly after package installation. Indexes project link

508
Running groovy script to crunch SI values
Please run the bamboo job: https://bamboo.aws.telegraph.co.uk/browse/JMET-JAP

If this fails then please follow the options below:

1. Download script-project.zip and unzip it.


2. Navigate to [LOCATION]/script-project/wpt/script
3. Run this command
groovy -cp ".*:libs/*" CollateSCData.groovy "AEM 3.1" 94961 94960

where 1. AEM 3.1 is the name of the sheet created inside releases folder.

2. 94961(cold cache) & 94960(warm cache) are cold and warm cache "deploy_id" which can be found from JMeter pipeline bamboo logs.

Groovy script parses bamboo logs and writes to excel sheet.

Note : It requires access to view sheet in releases folder.

509
Running JMeter test via Bamboo
Important links
Bamboo Pipeline: https://bamboo.aws.telegraph.co.uk/browse/JMET-JA
Sense Authoring Project: https://sense.blazemeter.com/gui/projects/27253/ (Login details in last pass)
Sense Dispatcher Project: https://sense.blazemeter.com/gui/projects/29623/ (Login details in last pass)
Authoring Performance Test Result Sheet: https://docs.google.com/spreadsheets/d/1O7pYzMQZEq_5wEycGzQL78X8qk3uhJ7LvAstoiGsew4
/edit#gid=0
Speed Governance Page

Manual data setup in Staging Env before test run:

Authoring performance test script runs 2 separate Live Article journeys where, one journey keep blogging on 5 pre-defined Live Articles (2 lives in
Major News and 3 lives in Top Stories snippets) and the second journey create and blog on new live articles
These pre-defined Live articles needs to be replaced with new ones for each new release candidate testing. To do this:
Create 5 new live articles and tag them with the same tags as the one they are replacing(for example image description image, live
article body, first post, headline Live Article RC - 1 etc.). We are working on to automate this step.
1. Create 1st news live article with tags "Bank of England" and "Mark Carney", use the first image from images attached.
2. Create 2nd news live article with tags "Labour party" and "Jo Cox", use the second image from images attached.
3. Create 3rd sports live article with tags "Andy Murray" and "Wimbledon", use the third image from images attached.
4. Create 4th sports live article with tags "Lionel Messi" and "Football", use the fourth image from images attached.
5. Create 5th sports live article with tags "Muhammad Ali" and "Boxing", use the fifth image from images attached.
Just fill up enough data to get them published e.g. Lead image required metadata, first live blog post etc
Go to Websites
Open Major News snippet and replace old articles with new ones.
Open Top Stories snippet and replace old articles with new ones.
Activate both components and validate data correctness on all web dispatchers
Checkout a release candidate branch for telegraph-author project
Update telegraph-author/author-performance/src/test/jmeter/data/live-blogs.csv file with newly created Live article uuids
Update telegraph-author/author-performance/src/test/jmeter/data/dispatcher/TestPages.csv file with newly created Live articles
(dispatcher) url suffixes (CSV target key is Live Article)
Check if the environment yaml file is there at the location telegraph-author/author-performance/script/authoring/scripts/ and if it's not
there, create <ENVIRONMENT>-config.yaml file in telegraph-author/author-performance/script/authoring/scripts/<ENVIRONMENT>-
config.yaml, (You can copy paste existing one and update the values with the environment details on which performance testing is going
to be running)
Commit and push changes to version of release made and develop (the latter for consistency)
Make sure telegraph-author/author-performance/script/authoring/scripts/perf-config.yaml is updated with perf environment password.
Invalidate all Dispatcher caches (See the following script or the following page)

Pre-run checks:
If the perf environment was recently refreshed, a groovy script must be run to generate perf users. Check https://author-tmg-stg-fds11.adobecqms.
net/useradmin and search for "perf" if no results then run the following script
Check if endpoints in osgi are pointing to correct environments, e.g. chp image service isnt pointing to prod

To run:
Browse to Jmeter bamboo pipeline
Click on Run Customised...
Click Override a variable link
Select BRANCH from dropdown and paste the Git branch value you are testing against e.g. release/2.91
Select other variable values (e.g. CLEANUP, ENV, RESTART_AUTHOR_SERVICE) depending on your use-case/run
Default CLEANUP value of Y means that Load Injector server will be terminated at of run
Default ENV value of perf means that tests will pick up the PERF config and inject the corresponding value into JMeter
Default RESTART_AUTHOR_SERVICE value of yes means that target Author instance will be restarted before the start of the test -
NOTE: sometimes this fails to restart, check logs for blocks of "connection refused" and start author manually.

After Run Completed:

Once the tests have completed a notification is sent to the Web Performance Channel in Slack so keep an eye on it. The tests currently take around 90-
100 minutes to run. There will be a brief note mentioning if the speed has improved compared to the last build.

If the speed has regressed on the note you can click on the link in posted in slack and it will take you to the compare deployments page or click here to
compare the current to previous performance builds.

If the performance has regressed you can rerun the tests and the average reading can be taken for the different measures. To see why they have
regressed there are analytical tools that can be used to see where the regression has occurred. Analysis instructions can be found here.

IMPORTANT: If any of the measures are either worse than the previous release baseline OR not trending toward the target the release is usually
rejected. However if the release contains critical and time sensitive changes then the release manager must discuss the increase with the
project team and sign off the release adding a note using this link justifying the release.

510
To ReRun:

It is possible to run the same performance test build life run two more times. This sometimes it is required because there maybe external factors
effecting the results of these tests (such as Google Analytics). By going back to the Jmeter bamboo pipeline you can click rerun from the top
right.
Creating the Live Articles again is not needed.

What is/and not covered by the Bamboo pipeline:


The pipeline runs Dispatcher and Authoring JMeter performance tests
Once Authoring test is finished, Authoring Performance Test Results google spreadsheet gets updated automatically. However, this update fails
most of the time due to buggy/unstable nature of BlazeMeter plugin. Please see next section for workaround.
Automatic upload of Dispatcher test, more or less, fails always. So you will have to download pipeline artifact, unzip it and manually upload
Dispatcher's .jtl.gz output file onto Sense dispatcher project
Updating Speed Governance page is a manual step

Authoring spreadsheet result update failed? - Here is the workaround


Execute following steps whenever JMeter BlazeMeter plugin failed to upload results to Authoring and Dispatcher projects:

Open target Bamboo JMET-JA build e.g. https://bamboo.aws.telegraph.co.uk/browse/JMET-JA-XXX


Open Artifacts tab
Download jmeter logs artifact
Uncompress downloaded aem-jmeter-logs.tgz file
Inside <uncompressed folder>/log/jmeter, you will find two Sense_XXXXXXX.jtl.gz files
Smaller Sense_*.jtl.gz file is an Authoring test result file (normaly < 500kb), Select and upload it to Sense's Authoring project. Change it's
name to reflect release candidate number
Bigger Sense_*.jtl.gz file is a Dispatcher test result file (normally > 9mb), Select and upload it to Sense's Dispatcher project. Change it's
name to reflect release candidate number
Checkout the telegraph-author project from Git, if you don't have it already
cd <telegraph-author>/author-performance/script/authoring/scripts/reporting
follow the readme in this directory

511
How to Analyse Performance Test Results
Once a build life has gone through a Performance Test Run it is possible to see how it compared to with a previous build life.

http://tmgperfreports.telegraph.co.uk/tmg/compareDeployments?siteId=11547&cur=&prev=&submit=Submit

So what do these results mean:

Metric Acronym meaning Definition

SpeedInd The time is takes to render the page in view (AKA: known as the fold)
ex

TTFP Time to first paint The time taken for the first item to be rendered on a blank webpage.

TTI Time to Interact A user can interact with a web page element once the page has rendered. After a shopper clicks on the
add-to-cart button, for example,

TTI measures the time it takes for the an interactive element on the next page to become usable, such as
the checkout button.

TLT Total Load Time Total load time measures how long it takes the browser to process and download all content on a web
page

Requests Total number of requests to It's a measure of how effectively things are cached on disk. The lower the number the better.
build a page

Page Sum total of all assets downloaded to serve the page


Weight

SpeedIndex and TTFP are the most important metrics to keep an eye on.

If you click on the SpeedIndex on the Business Channel for desktop, you will be navigated to the WebPageTest page. There is a slider you can use to see
where the extra time has been added causing the delay.

512
Authoring Publishing Flow
Authoring Publishing flow sequence diagram

Note: Link to edit the diagram: Edit diagram

Authoring Publish Flow - Description


Diagram above shows end to end Publishing flow in Authoring tool. Below you can find description of each step. Steps describe what is happening on the
backend side after the Publish button is clicked by the User.

1. When user clicks Publish button, before actual Publish, ContentManagerService performs Save action and after that AEM triggers event with
topic 'org/apache/sling/api/resource/Resource/CHANGE'.
2. Steps 3-5 are executed in the background, asynchronously, Publish request processing is continued in the same time (go to point number 6, if
you are not interested of processing of Change event).
3. ChangeIndexListener listens on 'org/apache/sling/api/resource/Resource/*' so it catches the event. For authoring articles (those which contain
authoring unique id), job with topic 'uk/co/telegraph/core/elasticsearch/reindex' is added
4. ReindexJobConsumer is responsible for processing jobs with topic 'uk/co/telegraph/core/elasticsearch/reindex' so in the background it builds
page properties and it triggers reindex of the given page in ElasticSearch using ESSingleReindexService class
5. ESSingleReindexService class is responsible for preparing the request to elasticsearch based on provided properties and of course for
sending that request. It can reindex single page or single asset.
6. When save is successful, the actual Publish request is sent to the backend. At the begining it is processed by WorkflowManagerService which
is not visible on the diagram. This is because this service is responsible for forwarding the request to the aproprierate service based on the action.
Actions are: Publish, Unpublish, Schedule, Unschedule. The first two are handled by PublishManagerService, the latter two are handled by S
cheduledManagerService. The PublishManagerService is described in the next few points. ScheduleManagerService will be
described separately.
7. When request hits the PublishManagerService then few action are happening:
a. For unpublish requests:
i. The Page path is added to a in-memory map in ProcessedAgentsStorageService class. This map contains a page path
as a key, and as a value it contains the number of Replication agents, based on which we want to calculate the story status.
Number of agents is provided by UsedReplicationAgentsService class
ii. In the next step ReplicationOptions object is created and it is used to unpublish a page. ReplicationOptions object
contains information if the page is a Live page (in that case, the priority replication agent is used for replication). In case of
Unpublish action, references are not deactivated.
iii. When replication is triggered, AEM fires event with topic 'com/day/cq/replication' which is listened by ResourceActivationLi
stener class. This listener executes a task ResourceActivationStartJob which adds page to the activation start time in-
memory map. Page path is the key and activation start time is the value. Data is later used to record in New Relic time of
activation (time from adding page to the replication queue until when it leaves the replication queue on author instance).
iv. After replication the page status is propagated into external services.
1. Message is send to Pubnub with 'Unpublishing' status using MessagePublisher class
2. Property status is reindexed in ElasticSearch for that page with the value set to 'Unpublishing...' (Using ESSingleRei
ndexService class)
v. As the last processing step, the cq:lastModified property is updated on a page. This triggers change event. Please check steps
2-5 for more details, as this is exactly the same process.
vi. Response is sent back to the user.
b. For Publish requests

i.

513
b.

i. if tmg:updatePublishTime page property is set to true, then publicationDateOverride property is set with the given publication
date. Additionally If the story is not a live article, then tmg:updatePublishTime is set to false.
ii. If the tmg:updatePublishTime property is set to false and the story is a live article, then property is set to true.
iii. Property timeOfSchedule is removed if it is set on a page
iv. If page is in Draft status, and page lives in a date folder structure channel, then the current date is checked. If a page is not
placed in the current date folder, then that page is moved to the current date folder.
v. Next, the page path is added to a in-memory map in ProcessedAgentsStorageService class. This map contains a page
path as a key, and as a value it contains the number of replication agents, based on which we want to calculate the story status.
Number of agents is provided by UsedReplicationAgentsService class
vi. Before the page is replicated, all page references are collected using the ReferenceProvider's classes. What is worth
noting, AEM tags reference provider is excluded from the processing. It means that tags which are not acitvated, but are added
to the page, will not be activated during the publish of that page. When page would be activated through AEM Authoring UI,
then those tags would be replicated.
1. If a story is a Gallery page, then GalleryReferenceProvider class will provide all the Gallery slide pages which
that Gallery has. Also it will check if Gallery slide page is marked as hidden. In that case such gallery slide page
instead of being replicated, it will be removed (slides are usually marked as hidden when someone will remove the
gallery item in Authoring Tool).
vii. All references which are outdated (i.e. they are not published already), are replicated.
viii. In the next step ReplicationOptions object is created and it is used to replicate a page. ReplicationOptions object
contains information if the page is a Live story (in that case, the priority replication agent is used for replication).
ix. When replication is triggered, AEM fires event with topic 'com/day/cq/replication' which is listened by ResourceActivationLi
stener class. This listener executes a task ResourceActivationStartJob which adds page to the activation start time in-
memory map. Page path is the key and activation start time is the value. Data is later used to record in New Relic time of
activation (time from adding page to the replication queue until when it leaves the replication queue on author instance).
x. After replication the page status is propagated.
1. Message is send to Pubnub with 'Publishing' status using MessagePublisher class
2. Property status is reindexed in ElasticSearch for that page with the value set to 'Publishing...' (Using ESSingleReind
exService class)
xi. Response is sent back to the user.
8. When page leaves the queue and is being processed by AEM, AEM triggers event with topic 'org/apache/sling/event/notification/job/START'
which is handled by ResourceReplicationStartListener class. This listener gathers data like page path, replication agent id, current time
and then passes that data to task ResourceReplicationStartJob, which is executed.
The ResourceReplicationStartJob task is similar to ResourceActivationStartJob with that difference that it adds page to a
replication start time in-memory map. Entry is added to a map which is assigned to the replication agent id. Each agent has it's own map. Page
path is the key and replication start time is the value. Data in those maps is used to calculate average replication time for each agent and then it is
send to New Relic.
9. When AEM finish replication on author instance, it triggers event with topic 'org/apache/sling/event/notification/job/FINISHED' and there are two
listeners which are listening on that event:
a. First one is ResourceReplicationFinishListener, which starts ResourceActivationAvgTimeReporterJob passing to job
topic, page path and current time to the constructor (and reference to ActivateTimeStorageService which keeps all the replication
and activation times maps). This task is responsible for calculating how long it took to activate and replicate the page. After that, page is
removed from in-memory activation start time map, and is added into average activation time in-memory ListMultimap, where agent
name is a key, and activation time is the value. It also records in New Relic (as a metric and to New Relic Insights) replication time for
the given replication agent.
b. Second listener is a PageReplicationListener. This listener adds Sling job with topic 'uk/co/telegraph/core/author/pubnub
/publishMessage' which is handled by MessagePublisherJobConsumer. This job consumer is responsible for sending message to Pu
bNub with status 'Published' or 'Unpublished', based on replication action type.
10. When AEM finishes replication, it updates replication properties on a page, and also cq:lastModified property, which triggers reindex in ElasticSear
ch. Please check the steps 2-5 to get more details.

Authoring Schedule Flow


Publishing stories using Schedule feature looks almost the same as the classic Publish action. There are some differences though. In case of schedule,
save is also performed before actual schedule is done, Later on WorkflowManagerService instead of passing data to PublishManagerService it
passes data to ScheduleManagerService. That's the first difference. The second one is of course is obvious. Publish action happens a bit later, which
causes a few additional changes. You can see them on diagram below.

514
Authoring Schedule Flow - Description
Diagram above shows the flow from the point when user clicks the Schedule button until the page leaves the workflow queue. This is important because
after that point, classic steps for AEM publish are executed. those steps were described in the first part of this document, in Authoring Publish Flow. For a
story which is is published through Schedule feature, steps from point number 8 are valid. Here is what happens before page goes into the replication
queue

1. When user clicks Schedule / Unscheddule button, before actual Schedule action ContentManagerService performs Save action and after that
AEM triggers event with topic 'org/apache/sling/api/resource/Resource/CHANGE'.
2. Steps 3-5 are executed in the background, asynchronously, Publish request processing is continued in the same time (go to point number 6, if
you are not interested of processing of Change event).
3. ChangeIndexListener listens on 'org/apache/sling/api/resource/Resource/*' so it catches the event. For authoring articles (those which contain
authoring unique id), job with topic 'uk/co/telegraph/core/elasticsearch/reindex' is added
4. ReindexJobConsumer is responsible for processing jobs with topic 'uk/co/telegraph/core/elasticsearch/reindex' so in the background it builds
page properties and it triggers reindex of the given page in ElasticSearch using ESSingleReindexService class
5. ESSingleReindexService class is responsible for preparing the request to elasticsearch based on provided properties and of course for
sending that request. It can reindex single page or single asset.
6. When save is successful, the actual Schedule request is sent to the backend. At the begining it is processed by WorkflowManagerService whi
ch is not visible on the diagram. This is because this service is responsible for forwarding the request to the aproprierate service based on the
action. Actions are: Publish, Unpublish, Schedule, Unschedule. The first two are handled by PublishManagerService, the latter two are
handled by ScheduledManagerService. The ScheduledManagerService is described in the next few points. ScheduleManagerService will
be described separately.
7. When request hits the ScheduledManagerService then few action are happening:
a. For Unschedule requests:
i. All workflow for the given page are terminated. Please not that workflows for references are not terminated. This is because
other pages may require those assets to be published in some time.
ii. Few properties are updated to it's previous state: headlineAndUrlAreLinked is set to true, publicationDateOverride and premium
ContentOnFirstPublish properties are removed, and cq:lastModified property is updated.
iii. The Page path is removed from two in-memory objects: Schedule Paths list and Active Agents map in ProcessedAgentsStor
ageService class.
iv. Response is sent back to the user.
b. For Schedule requests
i. All workflow for the given page are terminated. Please not that workflows for references are not terminated. This is because
other pages may require those assets to be published in some time..
ii. If page is in Draft status, and page lives in a date folder structure channel, then the schedule date is checked. If a page is not
placed in the scheduled date folder, then that page is moved to the scheduled date folder.
iii. Before the page is scheduled, all page references are collected using the ReferenceProvider's classes. What is worth
noting, AEM tags reference provider is excluded from the processing. It means that tags which are not acitvated, but are added
to the page, will not be activated during the publish of that page. When page would be activated through AEM Authoring UI,
then those tags would be replicated.
1. If a story is a Gallery page, then GalleryReferenceProvider class will provide all the Gallery slide pages which
that Gallery has. Also it will check if Gallery slide page is marked as hidden. In that case such gallery slide page
instead of being scheduled, it will be removed (slides are usually marked as hidden when someone will remove the
gallery item in Authoring Tool).
iv. All references are scheduled.

515
v. Next, the page path is added to a in-memory Page Replication map and into in-memory Scheduled paths List in ProcessedAge
ntsStorageService class. Page Replication map contains a page path as a key, and as a value it contains the number of
replication agents, based on which we want to calculate the story status. Number of agents is provided by UsedReplicationA
gentsService class. Scheduled Paths List is just a simple String list.
vi. Response is sent back to the user.
8. When page leaves the workflow queue (i.e. when page is replicated by AEM because the schedule time has come). and is being processed
by AEM, AEM triggers event with topic 'org/apache/sling/event/notification/job/FINISHED' which is handled by ScheduledActivationEndList
ener class. This listener extracts workflow item path from the workflow id and adds a Sling Job ScheduledActivationEndJobConsumer,
passing as a parameter that path.
9. Sling Job ScheduledActivationEndJobConsumer class is responsible for notyfing the frontend UI that page has left the workflow queue, and
is now in the replication queue. To do that it takes the workflow path and it gets the resource of that workflow item. From the workflow item
payload it gets the page path. Next it tries to retrieve Page resource based on the path in the payload, and if that succeeds, it checks if the page
has authoring unique id.
10. For pages which have authoring unique id page is removed from the Schedule Paths list in ProcessedAgentsStorageService class.
11. Pubnub message is sent with status 'Publishing...' using MessagePublisher class.
12. As the last step, job updates status property is reindexed in ElasticSearch using ESSingleReindexService class.
13. In the next steps AEM replicates the page and all it's references exactly as it was described from point number 8 in the Authoring Publishing Flow
section of this document.

516
Component Publishing Flow

topic pages:

two types of topic pages:


topic page created because of frequent use of tag
topic page created because of primary topic tag presence
all tags are on root level
topic pages are located under /content/telegraph/topics
topic pages can be created also for specific channel /content/telegraph/<channel>/topics

Content API Notifications


List Invalidation
Snippet invalidation
Content prefetch
PageReplicationListener
GalleryReplicationListener

In the future here will be the sequence diagram of publishing article feature.

517
Authoring Technical Debt
Tech Debt Themes for Q2 2016
AEM-5371 Author-Tech-Monitoring / Logging
Making it easier to read logs and ensuring that we collect relevant information in our logs. Goal is to have Authoring platform that is extremely easy to
operate and incident resolution becomes simple and rarely needed.

AEM-5374 Author-Tech-Data validation


Ensure that data stored is correct and reduce changes that it could become corrupt.
Fix known data inconsistency issues.
AEM-5360 Author-Tech-Performance
Implement and improve performance testing in Authoring tool.
Individual stories can have performance testing element in which case they don’t belong under this epic.
AEM-5367 Author-Tech-Code Quality

Ensure code quality is high and remains so. Fix identified issues with it.
AEM-5370 Author-Tech-AEM Upgrade

Tasks required from Authoring team for AEM upgrade to 6.0 SP3, 6.1 and beyond.
AEM-5369 Author-Tech-Collaboration

Coding standards, documentation. Lot of these are shared by all AEM teams and should be in AEM-5346
AEM-5374 Author-Tech-PubNub

Authoring PubNub improvements.


AEM-5350 Author-Bugs
Bugs or suspected bugs. These should take up to 20% of the sprint time in Q2.

518
Authoring tool story statuses
General
This page describes story statuses and their flow in Authoring Tool.

Introduction
Stories in authoring tool currently may have one of the 8 statuses:

Draft
Scheduled
Scheduled Modified
Publishing
Published
Modified
Unpublishing
Unpublished

These statuses can be splitted into three groups.

1. NOT LIVE - contains statuses which are not available on the live site. This group includes status Draft, Scheduled, Scheduled Modified and Un
published.
2. LIVE - contains statuses which are available on the live site, This group includes statuses Published and Modified
3. INTERIM -contains statuses which are partially available/unavailable on the live site. This group includes statuses Publishing and Unpublishing

Status flow
There is a specific flow, which describes the flow of story status.

Draft
From status Draft story can go to:

Publishing status. This is happening when user has pressed Publish button
Scheduled status. This is happening when user has pressed the Schedule button.

Scheduled
From status Scheduled story can go to:

Publishing status. This is happening when AEM starts publication of story which was scheduled for activation
Draft status. This is happening when user has cancelled Schedule.
Scheduled Modified status. This is happening when user has done a modification on Scheduled story.

Scheduled Modified
From status Scheduled Modified story can go to:

Publishing status. This is happening when AEM starts publication of story which was scheduled for activation
Draft status. This is happening when user has cancelled Schedule.
Scheduled status. This is happening when user has Rescheduled a story (previous schedule is cancelled, and story is scheduled again).

Publishing
From status Publishing story can go to:

Published status. This is happening when AEM has finished replication on all used replication agents.

Published
From status Published story can go to:

Unpublishing status. This is happening when user has pressed Unpublish button.
Modified status. This is happening when user has done a change on a published story.

519
Modified
From status Modified story can go to:

Unpublishing status. This is happening when user has pressed Unpublish button.
Publishing status. This is happening when user has pressed Republish button

Unpublishing
From status Unpublishing user can go to:

Unpublished status. This is happening when AEM has finished deactivation on all replication agents.

Unpublished
From status Unpublished user can go to:

Publishing status. This is happening when AEM starts publication of story which was scheduled for activation

Each flow is presented on the image below.

Additional references
https://docs.google.com/presentation/d/1qMK4J5WC-n4XOlWg_4Bm8vs3YBxMyAwSuhQOUyxpcJw/edit#slide=id.p - Presentation about story statuses

520
Authoring Story Statuses - Sequence Diagrams
General
This section contains sequence diagrams for story statuses

521
Story status flow - Publishing

522
General
Sequence diagram for Publishing story status flow. It is valid for Published and Unpublished status. Describes the flow from Draft, Publish or Modified
status (begining state) to the Published status. It is also valid for the flow from status Published or Modified (begning state) to Unpublished.

Please note, that some classes has been omitted, as there wasn't any good reason to put them on a diagram, for example when user sends a publish
request, which goes to WorkflowManagerServlet which delegetes the request to WorkflowManagerService which based on the request data
delegates the request to different service, PublishManagerService in this scenario.

523
Story status flow - Scheduling
General
Sequence diagram for Scheduling story status flow. It is valid for Schedule and Schedule Modified status. Describes the flow from Draft status (begining
state) to the Published/Modified status.

Please note, that some classes has been omitted, as there wasn't any good reason to put them on a diagram, for example when user sends a schedule
request, which goes to WorkflowManagerServlet which delegetes the request to WorkflowManagerService which based on the request data
delegates the request to different service, ScheduleManagerService in this scenario.

524
Authoring tool Story Statuses calculation
General
This page describes story status calculation from technical point of view. Story status is caluclted in class ContentStatusHelper in telegraph-author
repository.

How Draft is calculated


Draft is the default status, and story is in that status only if it didn't match any other status.

How Scheduled status is calculated


Story is in status Scheduled when:

1. It's not in any of the used replication agent queues


2. Last replication action is not Deactivate and it's not Activate
3. Story has no publish date set
4. Last modified date is before the Schedule date
5. Story is in the workflow queue

How Scheduled Modified status is calculated


Story is in status Scheduled when:

1. Story is not in any of the used replication agent queues


2. Last replication action is not Deactivate and it's not Activate
3. Story has no publish date set
4. Last modified date is after the Schedule date
5. Story is in the workflow queue

How Publishing status is calculated


1. Story is in at least one of the used replication agent queues
2. Last replication action was Activate

How Published status is calculated


1. Story is not in any of the used replication agent queues
2. Last replication action is not Deactivate
3. Last modified date is before the publish date
4. Last replication action is Activate

How Modified status is calculated


1. Story is not in any of the used replication agent queues
2. Last replication action is not Deactivate
3. Last modified date is after the publish date
4. Last replication action is Activate

How Unpublished status is calculated


1. Story is not in any of the used replication agent queues
2. Last replication action is Deactivate

How Unpublishing status is calculated


1. Story is in at least one of the used replication agent queues
2. Last replication action was Deactivate

525
CK Editor Notes for Authoring
Installation AEM-159 - Rich text formatting in Article Body RELEASED

In my opinion, the correct way to install CK editor is via the Bower package manager. This allows us to easily upgrade the editor in the future, and makes it
much easier to distinguish the vanilla editor from our own additions (of which there will be quite a few).

bower install ckeditor --save

In the simplest case CKEditor can then be included in the project as follows:

<script src="bower_components/ckeditor/ckeditor.js"></script>

This exposes ckeditor as window.CKEDITOR

It may be possible to load CKEditor using Require JS, although the configuration and paths might be quite difficult - they already require a bit of work to get
right (see below). I’d recommend reading this whole document then deciding whether you want to extend it further.

In the prototype, I have put all authoring's additional code relating to the CK editor into its own folder:

https://stash.aws.telegraph.co.uk/projects/UXP/repos/cms-prototype/browse/app/ckeditor

Customisations include:

Our custom config


Plugins (for embeds, toolbars, paste behaviour etc)
A non-standard skin

Registering Plugins
CKEditor has its own plugin system. Many are built into the standard build; others are loaded depending on your configuration. The standard plugins sit in
a folder relative to the main ckeditor path at bower_components/ckeditor/plugins

However, since CKEditor is installed by bower, our plugins need to live in a location outside of bower_components, so some glue is required to use both
the standard plugins and our custom ones.

This is found in /app/ckeditor/plugins.js:

CKEDITOR.plugins.addExternal('embedhelper', '/ckeditor/plugins/embedhelper/');
CKEDITOR.plugins.addExternal('instagram', '/ckeditor/plugins/instagram/');
CKEDITOR.plugins.addExternal('mediabrowser', '/ckeditor/plugins/mediabrowser/');

I have included this script immediately after the main ckeditor script.

Note: The above does not add plugins to the editor directly- it only makes them available for use. To do that we need to define our config.

Configuring Editors
This is relatively straightforward, with the only complexity arising from having two separate types of editor. There is one config with settings for each of:

Gallery Caption (basic tags, no embeds)


Article body (more available tags, and embeds)
(And possibly other ones in the future)

Both these configs have things common to both of them, which ideally comes from a single source of truth.

https://stash.aws.telegraph.co.uk/projects/UXP/repos/cms-prototype/browse/app/ckeditor/config.js

And to check it works:

https://stash.aws.telegraph.co.uk/projects/UXP/repos/cms-prototype/browse/test/unit-tests/ckeditor/config.test.js

You can then use the appropriate config to boot up a CKEditor instance:

526
instance = CKEDITOR.inline(el, config.body);
// or
instance = CKEDITOR.inline(el, config.inline);

Styling the Editor


The editor styles are based on a freely available skin called minimalist. It is not available through bower, unfortunately, so it has to be added to the /app
/ckeditor/skins/minimalist folder

The following config property is required to use the skin instead of the default:

skin: 'minimalist,/ckeditor/skins/minimalist/'

Skin
To prevent incompatibility with future updates to minimalist, the authoring styles are applied in a separate file, which are applied on top:

https://stash.aws.telegraph.co.uk/projects/UXP/repos/cms-prototype/browse/app/static/scss/features/_ckeditor.scss

Content
Finally, the content of the ckeditor is styled in a separate file

https://stash.aws.telegraph.co.uk/projects/UXP/repos/cms-prototype/browse/app/static/scss/components/_bodytext.scss

Creating Plugins
See the contents of ckeditor/plugins for the plugins we have created so far.

They include

mediaBrowser - for inserting images from the media browser dialog


embedHelper - for providing a medium-style widget to allow you to insert embeds
instagram - for providing full inline instagram embeds
toolbarPosition - for placing the toolbar in a suitable location
pastestripper - for stripping HTML content according to our rules (see below)

Note: Plugins and the Advanced Content Filter


The advanced content filter is a handy feature in CKEditor, which allows us to control the HTML that the editor produces, generaly keeping it clean and
nice.

By default the advanced content filter works automatically (although it is fully configurable)

You need to be aware of it when you start to create plugins that insert special content into the page, such as embeds.

It is important to register all the tags that a plugin wants - otherwise the filter will strip them out.

So, if a plugin wants to use the <figure> element, you need to include with its definition the following:

allowedContent: 'figure'

527
By adding these content rules at the plugin level, rather than the global level, the editor adjusts the filtering rules only if the plugin is used in a particular
configuration.

Paste Filtering
AEM-152 - Remove formatting when pasting text into Article Body
RELEASED

There is a requirement that content pasted from outside of CK should include only bold/strong tags, and a links (which is a subset of the rules allowed by
the Advanced Content Filter)

The pasteFilter config option is intended to provide custom rules just for pasting.

pasteFilter: 'b strong; a[!href]'

Unfortunately, in CKEditor (4.4.7 at time of writing) I cannot get this to work - it allows anything that is permitted by the advanced content filter - including
bullets and images.

However, there is another way: it is possible to write a custom plugin to do the filtering before it gets passed to the advanced content filter.

Example code for such a plugin is here:

https://stash.aws.telegraph.co.uk/projects/UXP/repos/cms-prototype/browse/app/ckeditor/plugins/pastestripper/plugin.js

And the test cases:

https://stash.aws.telegraph.co.uk/projects/UXP/repos/cms-prototype/browse/test/unit-tests/ckeditor/pastestripper.test.js

528
Elasticsearch
General
This section contains information about integration with Elasticsearch.

Elasticsearch DEV/TEST/DEMO server configuration


ElasticSearch Endpoints
ElasticSearch Troubleshooting
Reindex content in ElasticSearch
Remove index from ElasticSearch
Setup ElasticSearch

Environment Clustering Approach


Production

One 3 server ElasticSearch load balanced cluster


spread across 3 AZs
autoscaling within AZ as min=1, max=1

Pre-production environments (Dev, Test, Demo etc)

One 3 server ElasticSearch load balanced cluster shared by all


AZ and autoscaling as above
indices should be named with environment name to avoid clashing
index names in OSGi config to be set by Chef script when a new environment is created
host name in OSGI config to be set by Chef script when a new environment is created

Performance testing environment

One 3 server ElasticSearch load balanced cluster


AZ and autoscaling as above
spun up and down as required

529
Elasticsearch DEV/TEST/DEMO server configuration
Note

This should take place automatically but it doesn't seem to happen after
WS-3261 - Add elasticsearch OSGI configuration to preprod yaml files CLOSED

This can be cause if Authoring isn't working or CI for Authoring is failing with c. 45 broken tests.

1. Open OSGi configuration page, e.g. http://cms1.aem-dev6.awspreprod.telegraph.co.uk:4502/system/console/configMgr


2. Search for "Elastic Search" (including the space: leaving the space out will find different configuration entries but not the correct one) - you'll find
"Elastic Search Transport Client Provider"
3. Click to open dialog
4. Set 'address1.name' to elasticsearch-preprod.api-platforms-preprod.telegraph.co.uk
5. Set 'storiesIndexName.name to 'tmg_stories_[env]'. e.g. 'tmg_stories_dev6'
6. Set 'assetsIndexName.name to 'tmg_assets_[env]'. e.g. 'tmg_assets_dev6'
7. Save and wait few seconds
8. Verify with Authoring monitoring, e.g. http://cms1.aem-dev6.awspreprod.telegraph.co.uk:4502/bin/telegraph/author/monitoring

530
ElasticSearch Endpoints
General
Under this section you can find information about ElasticSearch endpoints available in AEM.

531
ElasticSearchSearchServlet
General
Servlet responsible for handling search requests.

Servlet handles only GET requests.

Servlet path
/bin/telegraph/core/elasticsearch/search

GET requests
Structure of get requests will be provided when first search story will be implemented (namely:
AEM-189 - Search for stories using Headline RELEASED )

532
TmgPageReindexContentServlet
General
Servlet responsible for handling re-index requests.

It handles only GET requests

Servlet path
/bin/telegraph/core/elasticsearch/reindex

GET request:
Servlet can re-index content based on path, or based on path AND resource type (template renderer).

Request
Get request must have atleast path, and request should look like that:

For pages:

{
"path":"/content/telegraph",
"type":"PAGE"
}

For assets:

{
"path":"/content/dam",
"type":"ASSET"
}

Response
Valid response looks like that:

{
"status":"OK"
}

Response, when something has failed:

{
"status":"ERROR",
"errorMessage":"Error message text."
}

Where error message differs, based on the error which has occured.

533
ElasticSearch Troubleshooting
General
This page contains basic ElasticSearch troubleshooting.

Page cannot be found in the index


This may happen when AEM will fail with indexing of that page. Page is indexed when it's created, modified or deleted, so it should not happen often.

If this will happen, content should be reindexed manually.

Description how to do that is here: How to reindex content in ElasticSearch

Page can be found in index, but it's not in the AEM


This may happen when AEM will fail with indexing of that page, when this page was removed. Page is indexed when it's created, modified or deleted, so it
should not happen often.

If this will happen, content should be reindexed manually.

Description how to do that is here: How to reindex content in ElasticSearch

Index has not been created


Index is not created when Elastic Search Transport Client Provider has wrong configuration. To check that, on AEM Author instance please go to

/system/console/configMgr

Search for Elastic Search Transport Client Provider and edit it configuration.

Please verify, that

1. address1.name has valid address (it shouldn't contain any protocol prefix, just domain name without slash at the end)
2. transport.port1.name has valid port number (it should be a transport port, not the http port)
3. indexName.name property has the valid index name set (it should have lowercased name, convention is to use _ instead of spaces.)
4. numberOfShards.name should be set to 4 (or more)
5. numberOfReplicas.name should be set to 2

NOTE: Please remembder that name given in this configuration is just a ALIAS. The real index name contains
_NUMBER suffix, for example: tmg_stories_dev_467. Requests can be sent to the index alias name and index original
name.

Index has been created but alias wasn't attached


This issue can be fixed in the two ways:

1. Remove index without alias, and create a new one


a. To do that go to /system/console/bundles
b. Search for telegraph-elasticsearch-core bundle
c. Stop it
d. Turn it on
This should create a new index with alias which you specified in configuration
2. Add alias to the index
a. Send a POST request to elasticsearch and add new index
b. Post request should look like this:

curl -XPOST 'http://elasticSearchDomainName:9200/_aliases' -d '{ "actions" : [ { "add" : { "index"


: "indexOriginalName", "alias" : "indexAliasName" } } ] }'

ElasticSearch is not responding


If when requesting

http://author.local.telegraph.co.uk:9200/

534
the response is not there, expected response:

{
"status" : 200,
"name" : "telegraph_local",
"cluster_name" : "tmg_stories_dev",
"version" : {
"number" : "1.7.2",
"build_hash" : "e43676b1385b8125d647f593f7202acbd816e8ec",
"build_timestamp" : "2015-09-14T09:49:53Z",
"build_snapshot" : false,
"lucene_version" : "4.10.4"
},
"tagline" : "You Know, for Search"
}

Then try restarting elastic search.

Find the elasticsearch process

ps aux | grep elastic

Kill found process if there is one

sudo kill -9 6466

And restart elasticsearch

sudo /etc/rc.d/init.d/elasticsearch start

535
Reindex content in ElasticSearch
General
Reindex content
Reindex endpoint
Reindex request

General
This page descibe the way, how content in ElasticSearch can be reindexed

Reindex content
Reindex endpoint
On AEM Author instance there is a servlet which is responsible for reindex content.

It's available under path:

/bin/telegraph/core/elasticsearch/reindex

Reindex request
To reindex content, a get request to that endpoint must be sent, and path paramter must be passed. Every page which contains authoringUniqueId
property on a Page will be reindexed.

For example, curl Request for CMS A instance should look like this:

1. curl -XGET -i -u admin:cmsa_prod_admin_password http://localhost:4502/bin/telegraph/core/elasticsearch


/reindex -H "Content-Type: text/json" -d '{"path":"/content/telegraph", "type":"PAGE"}'
2. curl -XGET -i -u admin:cmsa_prod_admin_password http://localhost:4502/bin/telegraph/core/elasticsearch
/reindex -H "Content-Type: text/json" -d '{"path":"/content/dam", "type":"ASSET"}'

Success response looks like that:

{ "errorMessages":"", "status":"OK"}

If nothing will be returned, or you wil see a stack trace, then it means that something went wrong, and indexing wasn't done.

This will reindex every page which contains authoringUniqueId under /content/telegraph path

536
Remove index from ElasticSearch
General
This page describes a way how indicies can be removed from ElasticSearch

Remove single index


To remove single index, a DELETE request to elasticsearch must be sent. Curl command look like this:

curl -XDELETE http://elasticSearchDomain:9200/indexName

So this command will remove index called "indexName".

Remove all indicies


To remove all indicies a DELETE request must be sent to elasticsearch, but instead of passing the inde name, we pass _all. So the request will look like
this:

curl -XDELETE http://elasticSearchDomain:9200/_all

This will remove all indicies created by the user.

537
Setup ElasticSearch
General
Running ElasticSearch
To run elastic search please follow these steps:
Install Elastic Search using script on vagrant
Install Elastic Search manually
Unpack Elastic search
Running ElasticSearch instance on local machine
Optional Configuration
Installing the telegraph-elasticsearch package (on author instance only):
Troubleshooting

General
This page contains information how to setup ElasticSearch on local instance.

Running ElasticSearch

To run elastic search please follow these steps:

Install Elastic Search using script on vagrant


Installation script configures everything and installs elastic search 1.7.1 on vagrant machine.

Script should be downloaded from here: elasticsearch-1.7.1

It should be uploaded to Vagrant Author machine (use win scp or any other client) (If you don't know how to do that, please follow this instructions: How to
upload files to vagrant virtual machine )

Now login in to vagrant author instance by typing

vagrant ssh author

from aws repository root level

Now go to the directory, where you uploaded the script.

Fire the scirpt by typing:

sudo su
chmod 777 elasticsearch_install.sh
./elasticsearch_install.sh telegraph_local tmg_stories_dev 127.0.0.1

Elastic search will be installed under

/etc/rc.d/init.d/elasticsearch

Install Elastic Search manually

Unpack Elastic search

Unpack somewhere the elasticsearch package which you have downloaded previously. This will be your ElasticSearch installation directory.

Running ElasticSearch instance on local machine


1. Open command line
2. Go to ElasticSearch installation directory (place, where you have unpacked the elasticsearch package)
3.

538
3. Go to bin directory
4. Run:
a. on Winodws systems

elasticsearch.bat

b. On Unix systems

elasticsearch

5. Verify your installation by opening in the browser:

http://localhost:9200 (or author.local.telegraph.co.uk:9200 for vagrant installation)

6. You should see something similar to:

{
"status" : 200,
"name" : "Neptune",
"cluster_name" : "your_cluster_name",
"version" : {
"number" : "1.7.1",
"build_hash" : "cdd3ac4dde4f69524ec0a14de3828cb95bbb86d0",
"build_timestamp" : "2015-06-09T13:36:34Z",
"build_snapshot" : false,
"lucene_version" : "4.10.4"
},
"tagline" : "You Know, for Search"
}

Optional Configuration
ElasticSearch doesn't need any special configuration, It can be just started from the the startup script and it should be enough. There are few things which
may be configure, but it don't have to be. To do confgiure ES:

1. Go to ElasticSearch installation directory


2. open file: config/elasticsearch.yml
3. If you want to change cluster name: Find Section: Cluster
4. Add:

cluster.name: your_cluster_name

5. If you want to change node name: Find Section: Node


6. Add:

node.name: your_node_name

7. If you want to change port number (by default 9200 for http, 9300 for tcp): Find Section: Network And HTTP
8. Add

transport.tcp.port: 9300

http.port: 9200

9. Add at the end of file:

action.auto_create_index: false

Installing the telegraph-elasticsearch package (on author instance only):

539
telegraph-elasticsearch was moved to telegraph-author now.

1. Go to the telegraph-elasticsearch directory


2. Run build command:

mvn clean install

mvn crx:install -Dinstance.url=http://author.local.telegraph.co.uk:4502 -Dinstance.password=vagrant

3. If ElasticSearch was installed in the main system (not in the vagrant virtual machine) and AEM is running on Vagrant then configuration of
ElasticSearch service has to be updated. If ElasticSearch was installed on vagrant, then proceed to step number 13
4. To update configuration in AEM go to

/system/console/configMgr

5. Search for: Elastic Search Transport Client Provider


6. Press edit button:

7. In the localhost1.name field type: 192.168.56.1 (this is default address ip, to which vagrant have access)
8. the rest of the field can be left as it is.
9. Click save

10. Go to

/system/console/bundles

11. Search for telegraph-elasticsearch and restart it by pressing stop icon:

12. And then click the play icon:


13. Verify if default index has been created in vagrant has created the default index for tmg pages by opening in the browser:

http://localhost:9200/tmg_stories_dev/_search/?size=1000&pretty=1 (or http://author.local.telegraph.co.


uk:9200/tmg_stories_dev/_search/?size=1000&pretty=1 for vagrant installation)

You should see something similar to:

{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 0,
"max_score" : null,
"hits" : [ ]
}
}

540
14. Verify listeners are working correctly. Create an Article, Gallery or Authoring Article page somewhere under /content/telegraph. Check if the index
was updated:

http://localhost:9200/tmg_stories_dev/_search/?size=1000&pretty=1 (or http://author.local.telegraph.co.


uk:9200/tmg_stories_dev/_search/?size=1000&pretty=1 for vagrant installation)

You should see something similar to:

{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 5,
"successful" : 5,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 1.0,
"hits" : [ {
"_index" : "tmg_stories_dev_223",
"_type" : "tmg_page",
"_id" : "/content/telegraph/film/test-gallery",
"_score" : 1.0,
"_source":{"pageId":"/content/telegraph/film/test-gallery","headline":"","title":"test gallery","
lastModified":"2015/07/27 08:06:11","url":"/content/telegraph/film/test-gallery.html","tags":[]}
} ]
}
}

Troubleshooting
If you the results from point 13 contains 404 information, then probably vagrant cannot reach your elasticsearch instance. Please verify by typing in the
command line:

On Windows

ipconfig

On linux:

ifconfig

if the Ethernet adapter VirtualBox Host-Only Network has the ip number of

(lik
e on the screenshot below):

If the IpV4 Address is different, then you will have to update your Elastic Search Transport Client Provider (already described in section: Inst
alling the telegraph-elasticsearch package )
If IP address is correct then try restarting CQ author instance.

541
Front end frameworks for Authoring UI
The proposed front end frameworks to be used for the Authoring UI are:

Framework Purpose

SASS Sass (Syntactically Awesome Stylesheets) is a stylesheet language

Bootstrap HTML, CSS and JavaScript framework for responsive sites

Handlebars Templating language/compiler

JQuery JavaScript library

Bower Package management

Backbone.js JavaScript library

Lodash JavaScript utility library

Require.js JavaScript file and module AMD loader

Jasmine Behaviour Driven Development testing framework for JavaScript

Maven Build automation tool

CKEditor RTE

Grunt Front-end build tooling

542
Gitflow branching model
Authoring team uses slightly different branching model than other AEM teams because we don't need to worry about cross team issues.

Original at https://www.lucidchart.com/documents/edit/0d9e0cff-5857-45af-aa4a-5e5b3e7bfbc2/1

543
JSON Communication Structure
In this section you can find information about JSON structures supported by Authoring front-end and back-end API.

General json structure:

Request:
// to be updated

Response:
{

"status": {
"statusCode": (eg. 200),
"message": ""
},
"content": {
....
}
}

Response json consists of:

"status" object, providing action execution status.


statusCode - field providing numerical representation of status.
message - field providing human readable description of status.
"content" object, providing actual response object, its content will vary regarding which action will be requested.

544
Assets Manager Servlet (AUT-34)
General
This page describes Assets Manager Servlet. Servlet will be called by frontend to get paths to images, in descending order and to upload new images

Related JIRA Issue: AUT-34 - Display Images in Assets Dialog RELEASED

Methods:
This servlet accepts GET and POST request. Get request must have path to section and subsection.

It is available under the following path:

/bin/telegraph/author/cms/assetmanager

GET request
GET Request:
Supported sections will be pulled from Feature Settings.

For example:

{
"from":"0",
"size":"50",
"sectionPath":"/content/telegraph/lifestyle",
"subsectionPath":"/content/telegraph/lifestyle/fashion",
"searchConstraints":{"channels":[""]}
}

This should be sent as query string parameter (encoded)

From / size parameters should be sent for pagination - they are mandatory.

GET Response:
As a response the servlet will return json with following format:

{
"status":{
"statusCode":200,
"message":""
},
"content":[
{
"created": 1423664847323,
"lastModified": 1423665139888,
"folder": "/content/dam/lifestyle/fashion",
"name": "test1",
"extension": "jpg",
"width": 1020,
"height": 576,
"metadata": {
"defaultFilename":"fileName.png",
"defaultCaptionText":["captionText"],
"defaultCreditText":["creditText"],
"defaultImageTitleText":["titleText"],
"defaultSourceText":["sourceText"]
}
},
{

545
"created": 1423664456788,
"lastModified": 142366596435,
"folder": "/content/dam/lifestyle/fashion",
"name": "test2",
"extension": "png",
"width": 1000,
"height": 420,
"metadata": {
"defaultFilename":"fileName.png",
"defaultCaptionText":["captionText"],
"defaultCreditText":["creditText"],
"defaultImageTitleText":["titleText"],
"defaultSourceText":["sourceText"]

}
}
]
}

Please note that metadata section is optional, and may be empty.

POST REQUEST
Post request handled uploading of the images. In one request there might be many images. Content type is multipart/form-data.

For each image there should be two parts:

1. File part - with the image (String base64)


2. Data part - with data about image.

Part with data contains json with information about image. It's format looks like this:

{
"name":"9.png",
"size":88056,
"type":"image/png"
}

The service also accepts pageId query string parameter, and if provided uploads images the DAM folder that corresponds to page channel. If parameter is
not provided, images are uploaded in the common authoring directory.

POST RESPONSE
Response which comes from backend looks like this:

{
"status":{
"statusCode":200,
"message":""
},
"content":{
"success":["/content/dam/authoring/9.png", "/content/dam/authoring/8.
png"],
"failure":["1.png", "2.png"],
"renamed":{
"HD.jpg":"/content/dam/authoring/HD_1.jpg",
"test.jpg":"/content/dam/authoring/test_1.jpg"
}
}
}

Content object contains three collections:

1. Success is an array which contains file paths which were successfully uploaded.

2.

546
2. Failure is an arrray which contains file names which couldn't be uploaded because of some reason
3. Renamed is a map, where key is original file name, and value is the file path under which image was uploaded. Name is renamed only, when
image with that name is already in AEM in assigned folder.

547
Author Autocomplete Servlet (AEM-401)
General
This page describes Author Autocomplete Servlet. Servlet will be called by byline component in new
authoring.
Servlet is responsible for providing list of authors which will be displayed as autocomplete to user for Byline component

Related JIRA Story: AEM-401 - Add Authors, Role and Location to Article RELEASED

Servlet path
Servlet is available at path:

/bin/telegraph/author/cms/autocomplete/authors

Get data for autocomplete


To get data for autocomplete GET request must be sent

Request
To fetch authors from AEM, empty POST request should be sent

Response
Response returns list of objects which starts from given text value

{
"status": {
"statusCode": 200,
"message": ""
},
"content": {
[
{
"id":"/content/telegraph/cars/simone_jones"
"name": "Simone Jones",
"role": "Director",
"location":""
},
{
"id":"/content/telegraph/cars/morsim_wright"
"name": "Morsim Wright",
"role": "",
"location":""
},
{
"id":"/content/telegraph/cars/mark_simply"
"name": "Mark Simply",
"role": "",
"location":""
}
]
}
}

548
Component properties.json structure
General
Structure of properties.json
Single Component without dialog
Image Component with dialog:
Structure description
Structure of mappings.json

Warning!

This page is outdated. New component json structure is available here: Components Json v2

General
This page describes structure of component properties.json and mappings.json. Both of them will be attached to every component in AEM as component
descriptor.

Properties.json contains alternative authoring dialog component definition.

Mappings.json is used only by backend to map fields from properties.json to path in CRX

Structure of properties.json

Single Component without dialog

{
"type":"HEADLINE",
"properties":{
"propertiesGroup":[
{
"groupTitle":"Headline Section",
"groupId":"headlineSection",
"fields":[
{
"id":"headline",
"type":"text",
"validators":[

"method": "required",

"constraints": []

],
"readonly":"
false",
"content":"
Headline text"

}
]
}
],
"edit": {
"inplace":[
{
"group":"
properties",
"field":"

549
somePropetyForImage"
}
],
"dialog":[]
}
}
}

Image Component with dialog:

{
"type":"IMAGE"
"properties":{
"propertiesGroup":[{
"groupTitle":"Image properties",
"groupId":"properties",
"fields":[
{
"id":"
somePropetyForImage",
"type":"
richtext",
"validators":[

"method": "required",

"constraints": []

]
"readonly:"
true",
"content":"
Source value"

}
]
},
{
"groupTitle":"Metadata",
"groupId":"metadataProperties",
"fields":[
{
"id":"
captionMetadata",
"type":"text",
"validators":[

"method": "required",

"constraints": []

]
"readonly:"
false",
"content":"
CaptionValue"
},
{

550
"id":"
otherMetadata",
"type":"
richtext",
"validators":[]
"readonly:"
true",
"content":"
Source value"

}
]
},
{
"groupTitle":"Image",
"groupId":"imageProperties",
"fields":[
{
"id":"
imageTitle",
"type":"text",
"validators":[]
"readonly:"
false",
"content":"
Image title"
},
{
"id":"altText",
"type":"text",
"validators":[

"method": "required",

"constraints": []

]
"readonly:"
false",
"content":"Some
val"
},
{
"id":"
imagePath",
"type":"text",
"validators":[]
"readonly:"
false",
"content":"
/content/path/to/image/in/dam"
},
{
"id":"
cropImage",
"type":"
cropOptions",
"validators":[]
"readonly:"
false",
"content":[

"width":"640",

"height":"480"

551
},

"width":"800",

"height":"600"

]
}
]
}
],
"edit": {
"inplace": [

"group":"properties",

"field":"somePropetyForImage"

},

"group":"imageProperties",

"field":"imageTitle"

},

"group":"imageProperties",

"field":"altText"

},
],
"dialog":[

"group":"metadataProperties",

"field":"captionMetadata"

},

"group":"metadataProperties",

"field":"otherMetadata"

},

"group":"imageProperties",

"field":"imageTitle"

},

552
"group":"imageProperties",

"field":"altText"

},

"group":"imageProperties",

"field":"imagePath"

},

"group":"imageProperties",

"field":"cropImage"

}
]
}
}
}

Structure description
Each component properties.json will be build from:

type - this will tell to frontend application, which component it should place in the page content.
properties - this object will contain properties about which fields are required, which fields are configurable in dialog and which are not, id of the
field to match it with CMS component, values of the fields.
Properties object will contain:

propertiesGroup - components will be splitted into some parts, they might be only a section in dialog, for example metadata section, or
they might be different tab in the dialog.

Each propertiesGroup element contains:


groupTitle- name of section / tab
groupId - section id
fields - list of fields in given section
Field can contain:
id - CMS component id
type - frontend type, for example text, richtext, image etc. Defines how property should be displayed in frontend
application
readonly - specifies if field is read only
validators - contains list of validators object for given field
Each validator has following structure:
method - contains name of validator
constratints - array of constraint. It should always be an array, even if there is one value.
content - value of the property.
edit - order in which properties should be displayed. It has two objects:
inplace - contains order of properties for inplace editing
dialog - contains order of properties in the dialog
Dialog and inplace contains array of objects, which has structure:
groupId - id of properties group
field - id of field (in properties group)

Structure of mappings.json
Structure is simple object with key-value pairs. Key is the component id from Properties.json, and value is a path in CRX to this field.

{
"mappings": {
"standfirst": "./standfirstText"
}
}

553
554
Content Manager Servlet (AUT-25)
General
This page describes Page Manager Servlet. Servlet will be called by frontend to create or save page in
AEM
Servlet is responsible for creating and updating pages in AEM and later on for retrieving content of those pages and sending it back to frontend

Related JIRA Story: AUT-25 - Create new Article RELEASED

Servlet path
Servlet is available at path:

/bin/telegraph/author/cms/contentmanager

Creation of the page in AEM


To create a page POST request must be sent.

Request and response differs a bit between actions.

To create a new page following information must be sent from frontend to backend:

Request:

{
"contentType": {
"id": "TYPE_ARTICLE",
"label": "Article"
},
"storyStatus": {
"id": 1,
"label: "Draft"
},
"storyType": {
"id": "guide",
"label: "Guide"
},
"commentingStatus":false,
"publishTime":null,
"live":false,
"dontSyndicate":false,
"updatePublishTime":false,
"section":{
"label":"Art",
"id":"/content/telegraph/lifestyle",
"structureTags":[

],
"children":[

]
},
"subsection":{
"label":"Artists",
"id":"/content/telegraph/art/fashion",
"structureTags":[

],
"children":[

555
},
"pageId":"3732b8ad-b1e8-11e8-a73f-0242ac1f0104",
"pageTitle":"ertertrer",
"pageUrl":"/art/artists/ertertrer",
"headlineAndUrlAreLinked":true,
"components": [
{
"type": "HEADLINE",
"componentId": "",
"fields": [
{
"id": "headlineText",
"type": "text",
"validators": [

"method": "required",

"constraints": []

}
],
"data": {

"value": "test",

"readonly": false
}
}
],
"components": []
}
],
"holdStatus":false,
"notes":null,
"premiumContent":false,
"premiumStatusOverride":false,
}

Response
Response which is returned by backend, when page is created. It contains all information about the story: story id, story status, section path,
subsection path, page path (which may be different than it was before sending the request), page title, and content of all components.

{"status": {
"statusCode": 200,
"message": ""
}, "content": {
"storyType":{
"id":"guide",
"label":"Guide",
"selected":false
},
"contentType": {
"id": "TYPE_FASHION_STORY",
"label": "Fashion"
},
"storyStatus": {
"id":1,
"label":"Draft"
},
"section":{
"label":"Lifestyle",
"id":"/content/telegraph/lifestyle",
"structureTags":[

],
"children":[

556
]
},
"subsection":{
"label":"Fashion",
"id":"/content/telegraph/art/artists",
"structureTags":[

],
"children":[

]
},
"pageId": "/content/telegraph/lifestyle/fashion/headline_text",
"pageTitle": "Headline text",
"pageUrl":"/art/artists/ertertrer",
"headlineAndUrlAreLinked":true,
"componentsContent": [
{
"type": "",
"componentId": "",
"fields": {
{
"id":"",
"type":null,
"validators":[

],
"data":{
"value":""
}
},
}
}
]
}}

Retrieve a page
To retrieve a page GET request must be sent.

Request
To retrieve a page frontend must sent GET request with query parameter:

pageId=88afde61-ad3e-4026-af72-1382059b388b

The id is the authoringUniqueId which can be found in page properties on authoring tab

Response
Response returns basic information about a page: page title, page path, and components with it's content which are on the page.

{"storyType": {
"id": "TYPE_GALLERY",
"label": "Gallery"
}, "storyStatus": {
"id": 1,
"label": "Draft"
}, "sectionPath": "/content/telegraph/lifestyle", "subsectionPath": "/content/telegraph/lifestyle/fashion",
"pageId": "88afde61-ad3e-4026-af72-1382059b388b", "pageTitle": "gallery_2355500", "components": [
{
"type": "HEADLINE",
"componentId": "/content/telegraph/lifestyle/fashion/gallery_2355500/jcr:content/headline",
"fields": [
{
"id": "headlineText",

557
"type": "text",
"validators": [
{
"method": "required",
"constraints": []
}
],
"data": {
"value": "gallery_2355500",
"readonly": false
}
},
{
"id": "uniqueId",
"type": "hidden",
"validators": [],
"data": {
"value": "TMG-ID-Headline",
"readonly": true
}
}
],
"components": []
},
{
"type": "GALLERY",
"componentId": "/content/telegraph/lifestyle/fashion/gallery_2355500/jcr:content/gallery",
"fields": [],
"components": [
{
"type": "GALLERY_ITEM",
"componentId": "/content/telegraph/lifestyle/fashion/gallery_2355500
/alt_text_for_image_one/jcr:content/galleryItem",
"fields": [
{
"id": "imagePath",
"type": "image",
"validators": [
{
"method": "required",
"constraints": []
}
],
"data": {
"value": "/content/dam/authoring/image_one.png",
"readonly": false
}
},
{
"id": "cropping",
"type": "cropping",
"validators": [],
"data": {
"readonly": false,
"selected": "landscape",
"crops": {
"square": {
"height": "2000",
"width": "2000",
"y": "500",
"x": "500"
},
"landscape": {
"height": "5000",
"width": "1000",
"y": "0",
"x": "1000"
},
"portrait": {
"height": "1000",
"width": "5000",

558
"y": "1000",
"x": "0"
}
}
}
},
{
"id": "captionText",
"type": "text",
"validators": [],
"data": {
"value": "",
"readonly": false
}
},
{
"id": "altText",
"type": "text",
"validators": [],
"data": {
"value": "alt_text_for_image_one",
"readonly": false
}
},
{
"id": "sourceText",
"type": "text",
"validators": [],
"data": {
"value": "",
"readonly": false
}
},
{
"id": "creditText",
"type": "text",
"validators": [],
"data": {
"value": "",
"readonly": false
}
},
{
"id": "defaultCaptionText",
"type": "text",
"validators": [],
"data": {
"value": ["Gallery test file Steven DAM
Description"],
"readonly": true
}
},
{
"id": "defaultImageTitleText",
"type": "text",
"validators": [],
"data": {
"value": ["Gallery test file Steven DAM Title"],
"readonly": true
}
},
{
"id": "defaultCreditText",
"type": "text",
"validators": [],
"data": {
"value": ["Gallery test file Steven DAM Creator"],
"readonly": true
}
},
{

559
"id": "defaultSourceText",
"type": "text",
"validators": [],
"data": {
"value": ["Gallery test file Steven DAM Copyright"],
"readonly": true
}
},
{
"id": "defaultFilename",
"type": "text",
"validators": [],
"data": {
"value": "image_one.png",
"readonly": true
}
},
{
"id": "defaultOrientation",
"type": "text",
"validators": [],
"data": {
"value": "",
"readonly": true
}
}
],
"components": []
}
]
},
{
"type": "KEYWORDS",
"componentId": "",
"fields": [
{
"id": "",
"type": "",
"validators": [],
"data": {
"tags": [
{
"tagID": "lifestyle:fashion/cool",
"titlePath": "Lifestyle : Fashion / cool"
}
]
}
}
],
"components": []
}
]}

Edit page
To edit page (add, edit,delete components) PUT request must be sent.

One request per added/edited/deleted component.

Request

{"storyType": {
"id": "TYPE_ARTICLE",
"label": "Article"
}, "storyStatus": {
"id": 1,
"label": "Draft"
}, "sectionPath": "/content/telegraph/lifestyle", "subsectionPath": "/content/telegraph/lifestyle/fashion",

560
"pageId": "6140f1a0-3a32-11e5-9b44-080027692dbf", "pageTitle": "test", "components": [
{
"type": "HEADLINE",
"componentId": "/content/telegraph/lifestyle/fashion/test5/jcr:content/content/headline",
"fields": [
{
"id": "headlineText",
"type": null,
"validators": [],
"data": {
"value": "testtestst"
}
}
],
"components": []
},
{
"type": "STANDFIRST",
"componentId": "/content/telegraph/lifestyle/fashion/test5/jcr:content/content/standfirst",
"fields": [
{
"id": "standfirstText",
"type": null,
"validators": [],
"data": {
"value": "estestest"
}
}
],
"components": []
},
{
"type": "LEAD_ASSET",
"componentId": "/content/telegraph/lifestyle/fashion/test5/jcr:content/content/leadAsset",
"fields": [
{
"id": "imagePath",
"type": null,
"validators": [],
"data": {
"value": "/content/dam/authoring/no_caption.png"
}
},
{
"id": "captionText",
"type": null,
"validators": [],
"data": {
"value": "tset"
}
},
{
"id": "altText",
"type": null,
"validators": [],
"data": {
"value": "estes"
}
},
{
"id": "sourceText",
"type": null,
"validators": [],
"data": {
"value": "tsets"
}
},
{
"id": "creditText",
"type": null,
"validators": [],

561
"data": {
"value": "etest"
}
},
{
"id": "cropping",
"type": null,
"validators": [],
"data": {
"selected": "square",
"crops": {
"landscape": {
"x": 0,
"y": 1875,
"width": 10000,
"height": 6250
},
"portrait": {
"x": 1875,
"y": 0,
"width": 6250,
"height": 10000
},
"square": {
"x": 0,
"y": 0,
"width": 10000,
"height": 10000
}
}
}
}
],
"components": []
},
{
"type": "BODY",
"componentId": "/content/telegraph/lifestyle/fashion/test5/jcr:content/content/paragraph",
"fields": [],
"components": [
{
"type": "BODY_TEXT",
"componentId": "",
"fields": [
{
"id": "bodyText",
"type": null,
"validators": [],
"data": {
"value": "<p>testest</p>\n<p>&nbsp;</p>\n"
}
}
],
"components": []
},
{
"type": "HTML_EMBED",
"componentId": "",
"fields": [
{
"id": "htmlEmbed",
"type": null,
"validators": [],
"data": {
"value": "<b>Test</b>"
}
}
],
"components": []
},
{

562
"type": "BODY_TEXT",
"componentId": "",
"fields": [
{
"id": "bodyText",
"type": null,
"validators": [],
"data": {
"value": "<p>&nbsp;</p>\n<p>asfasdf</p>\n"
}
}
],
"components": []
}
]
},
{
"type": "KEYWORDS",
"componentId": "",
"fields": [
{
"id": null,
"type": null,
"validators": [],
"data": {
"tags": [
{
"tagID": "lifestyle:fashion",
"titlePath": "Lifestyle : Fashion"
}
]
}
}
],
"components": []
}
]}

Response

{"status": {
"statusCode": 200,
"message": ""
}, "content": {
"storyType": {
"id": "TYPE_ARTICLE",
"label": "Article"
},
"storyStatus": {
"id": 1,
"label": "Draft"
},
"sectionPath": "/content/telegraph/lifestyle",
"subsectionPath": "/content/telegraph/lifestyle/fashion",
"pageId": "6140f1a0-3a32-11e5-9b44-080027692dbf",
"pageTitle": "test",
"components": [
{
"type": "HEADLINE",
"componentId": "/content/telegraph/lifestyle/fashion/test5/jcr:content/content
/headline",
"fields": [
{
"id": "headlineText",
"type": null,
"validators": [],
"data": {

563
"value": "testtestst"
}
}
],
"components": []
},
{
"type": "STANDFIRST",
"componentId": "/content/telegraph/lifestyle/fashion/test5/jcr:content/content
/standfirst",
"fields": [
{
"id": "standfirstText",
"type": null,
"validators": [],
"data": {
"value": "estestest"
}
}
],
"components": []
},
{
"type": "LEAD_ASSET",
"componentId": "/content/telegraph/lifestyle/fashion/test5/jcr:content/content
/leadAsset",
"fields": [
{
"id": "imagePath",
"type": null,
"validators": [],
"data": {
"value": "/content/dam/authoring/no_caption.png"
}
},
{
"id": "captionText",
"type": null,
"validators": [],
"data": {
"value": "tset"
}
},
{
"id": "altText",
"type": null,
"validators": [],
"data": {
"value": "estes"
}
},
{
"id": "sourceText",
"type": null,
"validators": [],
"data": {
"value": "tsets"
}
},
{
"id": "creditText",
"type": null,
"validators": [],
"data": {
"value": "etest"
}
},
{
"id": "cropping",
"type": null,
"validators": [],

564
"data": {
"selected": "square",
"crops": {
"landscape": {
"x": 0,
"y": 1875,
"width": 10000,
"height": 6250
},
"portrait": {
"x": 1875,
"y": 0,
"width": 6250,
"height": 10000
},
"square": {
"x": 0,
"y": 0,
"width": 10000,
"height": 10000
}
}
}
}
],
"components": []
},
{
"type": "BODY",
"componentId": "/content/telegraph/lifestyle/fashion/test5/jcr:content/content
/paragraph",
"fields": [],
"components": [
{
"type": "BODY_TEXT",
"componentId": "/content/telegraph/lifestyle/fashion/test5/jcr:
content/content/paragraph/par/component",
"fields": [
{
"id": "bodyText",
"type": null,
"validators": [],
"data": {
"value": "\u003Cp\u003Etestest\u003C
/p\u003E\n\u003Cp\u003E\u0026nbsp;\u003C/p\u003E\n"
}
}
],
"components": []
},
{
"type": "HTML_EMBED",
"componentId": "/content/telegraph/lifestyle/fashion/test5/jcr:
content/content/paragraph/par/component0",
"fields": [
{
"id": "htmlEmbed",
"type": null,
"validators": [],
"data": {
"value": "\u003Cb\u003ETest\u003C/b\u003E"
}
}
],
"components": []
},
{
"type": "BODY_TEXT",
"componentId": "/content/telegraph/lifestyle/fashion/test5/jcr:
content/content/paragraph/par/component1",
"fields": [

565
{
"id": "bodyText",
"type": null,
"validators": [],
"data": {
"value": "\u003Cp\u003E\u0026nbsp;\u003C
/p\u003E\n\u003Cp\u003Easfasdf\u003C/p\u003E\n"
}
}
],
"components": []
}
]
},
{
"type": "KEYWORDS",
"componentId": "",
"fields": [
{
"id": null,
"type": null,
"validators": [],
"data": {
"tags": [
{
"tagID": "lifestyle:fashion",
"titlePath": "Lifestyle : Fashion"
}
]
}
}
],
"components": []
}
]
}}

566
Components Json v2
Reasons
After further discussion around project architecture properties group gives us no benefits and they only introduce unnecessary complexity.

What's more "content" property is not enough to express content of the field. We would like to propose introducing "data" instead.

Structure
{
"status":{
"statusCode":200,
"message":""
},
"content":{
"storyType":{
"id":"TYPE_FASHION_STORY",
"label":"Fashion"
},
"storyStatus": "DRAFT",
"sectionPath": "/content/telegraph/lifestyle",
"subsectionPath": "/content/telegraph/lifestyle/beauty",
"pageId": "/content/telegraph/lifestyle/fashion/headline-text1",
"pageTitle": "Cool Page Title",
"components": []
}
}

Example components

{
"type":"HEADLINE",
"fields":[
{
"id": "headlineText",
"type": "text",
"validators": [
{
"method": "required",
"constraints": []
}
],
"data": {
"value": "standfirst test",
"readonly":false
}
}
],
"components": []
}

{
"type":"STANDFIRST",
"fields": [
{
"id": "standfirstText",
"type": "text",
"validators": [
{
"method": "required",
"constraints": []
}
],

567
"data": {
"value": "standfirst test",
"readonly":false
}
}
],
"components": []
}

{
"type":"GALLERY",
"componentId":"",
"fields":[],
"components":[]
}

{
"type":"GALLERY_ITEM",
"fields":[
{
"id":"galleryImagePath",
"type":"image",
"validators":[
{
"method":"required",
"constraints":[]
}
],
"data": {
"value": "/content/dam/image.png",
"readonly": false
}
},
{
"id":"cropping",
"type":"cropping",
"validators": [],
"data": {
"selected": "landscape",
"readonly": false,
"crops":{
"landscape":{
"x":0,
"y":0,
"width":0,
"height":0
},
"portrait":{
"x":0,
"y":0,
"width":0,
"height":0
},
"square":{
"x":0,
"y":0,
"width":0,
"height":0
}
}
}
}
],
"components": []
}

568
{
"type":"BODY",
"fields":[],
"components":[]
}

{
"type":"BODY_TEXT",
"fields":[
{
"id":"bodyText",
"type":"text",
"validators":[
{
"method":"required",
"constraints":[]
}
],
"data":
{
"value":"some text value",
"readonly":false
}
}
],
"components":[]
}

next step is to replace "content" with "data". "data" will differ depending on the field type.

"data": {
"value": "standfirst test",
"placeholder": "standfirst placeholder",
"readonly": false
}

569
Content Types Provider Servlet (AUT-7)
General
This page describes Content Types Provider Servlet. Servlet will be called by frontend to get list of items which will be display in Create menu.

Related JIRA Story: AUT-7 - View available article Templates on Dashboard RELEASED

Request:
This servlet accepts empty GET request under the following path:

/bin/telegraph/author/cms/contenttypes

Response
As a response the servlet will return JSON with following format:

{
"status":{
"statusCode":200,
"message":""
},
"content":[
{
"id":"TYPE_ARTICLE",
"label":"Article"
},
{
"id":"TYPE_GALLERY",
"label":"Gallery"
},
{
"id":"TYPE_LIVE_ARTICLE",
"label":"Live Article"
}
]
}

570
Environment Configuration Servlet (AEM-1741, AEM-444)
General
This page describes Environment Configuration Servlet. Servlet will be called by frontend to get any environment configuration values that may vary for
each environment.

Related JIRA Issue: AEM-1741 - Story status automatically updates on Publish/Unpublish RELEASED

AEM-444 - Suggest Topic Tags for an Article based on the Headline and Article Body RELEASED

Request:
This servlet accepts empty GET request. under the following path:

/bin/telegraph/author/cms/config

Response:
As a response the servlet will return JSON with following format:

{
"status": {
"statusCode": 200,
"message": ""
},
"content": {
"pubnub": {
"pubNubChannelPrefix": "NONPROD",
"pubNubPublishKey": "pub-c-320254b6-abef-495a-a22c-b63b31956b60",
"pubNubSubscribeKey": "sub-c-40a23000-2a3b-11e5-b9fb-02ee2ddab7fe"
},
"autosuggestAPI": "http://tag-rules-api-preprod.eip.telegraph.co.uk/",
"newRelic": {
"applicationId": "17657042",
"licenseKey": "56c59e3a09"
},
"featureFlags": {
"openPremiumEnabled": false
},
"ooyalaBrowserUrl": "http://videobrowser.awspreprod.telegraph.co.uk/search"
}
}

571
Finder Search Servlet (AEM-189)
General
Servlet responsible for handling search request on Finder. Used by the client to retrieve and filter articles by various attributes.

Accepted methods: GET

Servlet path
Servlet is available at path:

/bin/telegraph/author/cms/finder/search

Search Request

Request
Search request is a GET request which contains one parameter called query which has as value json in such structure:

{
"searchFields":{
"headline":[
"example"
],
"status":[
"Scheduled"
],
"channels":[
"Lifestyle"
],
"contentType":[
"TYPE_ARTICLE"
]
}
}

Response

{"status": {
"statusCode": 200,
"message": ""
}, "content": [
{
"pageId": "/content/telegraph/lifestyle/fashion/article_75463",
"headline": "article_75463",
"channel": "Lifestyle",
"section": "Fashion",
"type": {
"id": "TYPE_ARTICLE",
"label": "Article"
},
"lastModified": 1438210510000,
"live": false,
"holdStatus":false,
"publishTime": 0,
"authors": [],
"tags": [],
"status": {
"id": 1,

572
"label": "Draft"
}
},
{
"pageId": "/content/telegraph/lifestyle/fashion/article_21257",
"headline": "article_21257",
"channel": "Lifestyle",
"section": "Fashion",
"type": {
"id": "TYPE_ARTICLE",
"label": "Article"
},
"lastModified": 1658210510000,
"live": false,
"holdStatus":false,
"publishTime": 0,
"authors": [],
"tags": [],
"status": {
"id": 1,
"label": "Draft"
}
}
]}

573
Finder Servlet (AUT-88)
General
This page describes Finder Servlet. Servlet is responsible for providing pages created with M&M to dashboard.

Related JIRA Issue: AUT-88 - Display all Stories on Finder (Dashboard) RELEASED

Request:
This servlet accepts empty GET request. under the following path:

/bin/telegraph/author/cms/finder

Response:
As a response the servlet provides json with following structure:

{"status": {
"statusCode": 200,
"message": ""
}, "content": [
{
"pageId": "f7814256-2bb0-11e5-bb68-063dfce7e91f",
"headline": "article_91895",
"channel": "Lifestyle",
"section": "Fashion",
"type": {
"id": "TYPE_ARTICLE",
"label": "Article"
},
"status": {
"id": 1,
"label": "Draft"
},
"lastModified":123123123,
"publishTime":1231231
},
{
"pageId": "c94cb3de-2ac1-11e5-8c65-063dfce7e91f",
"headline": "Checking the date",
"channel": "Authoring Test",
"section": "Test section",
"type": {
"id": "TYPE_AUTHORING_ARTICLE",
"label": "Authoring_Article"
},
"status": {
"id": 1,
"label": "Draft"
},
"lastModified":123123123,
"publishTime":1231231
},
{
"pageId": "c8a56c9b-2af0-11e5-9cae-063dfce7e91f",
"headline": "headline_text82819",
"channel": "Lifestyle",
"section": "Fashion",
"type": {
"id": "TYPE_GALLERY",
"label": "Gallery"

574
},
"status": {
"id": 2,
"label": "Published"
},
"lastModified":123123123,
"publishTime":1231231
}
]}

575
Keyword Search Servlet (AEM-1557)
General
Endpoint responsible for searching of keywords. It performs search in three namespaces: Authors (/etc/tags/editors), Topics (/etc/tags/topics) and
Structure (/etc/tags/structure).

It returns only activated keywords

Related JIRA Story: AEM-1557

Request:
This servlet accepts GET request with query string parametr::

/bin/telegraph/author/cms/search/keyword?suggestByTitle=keywordNameFragment

All keywords that contain given phrase are returned. So if "any" is used as the query strirng, then tags "Any tag", "Many tags" are returned.

Response
As a response the servlet will return json with following format:

{"status": {
"statusCode": 200,
"message": ""
}, "content": [
{
"label": "Politics",
"disambiguator": "Things",
"path": "/etc/tags/topics/things/politics",
"tagID": "topics:things/politics"
},
{
"label": "David Cameron",
"disambiguator": "People",
"path": "/etc/tags/topics/people/david-cameron",
"tagID": "topics:people/david-cameron"
}
]}

Short description:
label - tag label
disambiguator - parent namespace or parent tag name
path - path to the tag in AEM
tagID - tagID in AEM

576
Open Premium Mock API (AEM-5962)
General
This page contains specification of Mock API for rules engine.

Mock API Endpoint will use the RulesEngineClientService. Which implementation will it use depends on the configuration. To use the Mock API, property
in configuration (exact name of the service with configuration will be provided later) needs to be set to MOCK

Request and response will look exactly the same for Mock API and for Real API.

URL
Url is the same for Mock API and for Real API. Request method should be POST

/bin/telegraph/author/openpremium

Configuration
To use Mock API for Open Premium feature, the configuration in OSGI needs to change.

Name of the service will be provided after the implementation. It will be a service with single property which will accept two values: REAL or MOCK

Request
This is the POST request with random data, it will always return status OPEN. List of available requests is available here: Authoring Open Premium Mock
API Requests:

{
"channelTagId": ["structure:sport"],
"sectionTagId": ["structure:sport/basketball"],
"author": ["John Tubylem"],
"storyType": "standard"
}

Response

Premium status:

{
"status": {
"statusCode": "200",
"message": ""
},
"content": {
"status": "premium",
"message": ""
}
}

Open status:

{
"status": {
"statusCode": "200",
"message": ""
},
"content": {
"status": "open",

577
"message": ""
}
}

Unexpected error occured (also valid for Timeouts and other API-related errors, status default - open):

{
"status": {
"statusCode": "205",
"message": "Business Rules API Client is not available."
},
"content": {
"status": "open",
"message": ""
}
}

578
Authoring Open Premium Mock API Requests
General
This page contains list of requests which are handled by Authoring Mock API of Open Premium. Any other request will return status OPEN.

Structure tag with which all stories are Open.. Returns Open.
Required data:

Structure tag: News

Example request:

{
"channelTagId": ["structure:news"],
"sectionTagId": [],
"author": [],
"storyType": "standard"
}

Structure tag with which all stories are Premium. Returns Premium.
Required data:

Structure tag: Business

Example request:

{
"channelTagId": ["structure:business"],
"sectionTagId": [],
"author": [],
"storyType": "standard"
}

Author which stories are always premium. Returns Premium.


Required data:

Author: Boris Johnson,


Structure tag: Must be other than "Technology"

Example request:

{
"channelTagId": ["structure:football"],
"sectionTagId": [],
"author": ["Boris Johnson"],
"storyType": "comment"
}

Premium author which stories are always premium, unless stories have Open Structure tag. Returns
Open.
Required data:

Structure tag: Technology


Author: Boris Johnson

Example request:

579
{
"channelTagId": ["structure:technology"],
"sectionTagId": [],
"author": ["Boris Johnson"],
"storyType": "standard"
}

Always Premium Story type (even if stories contains Structure tag which says 'always open'). Returns
Premium .
Required data:

Story type: Comment


Structure tag: Technology

Example request:

{
"channelTagId": ["structure:technology"],
"sectionTagId": [],
"author": ["Jane Author"],
"storyType": "comment"
}

Premium Story type. Returns Premium.


Required data:

Story type: Comment


Author: Jane Author
Content type: Article
Structure tag: Fashion

Example request:

{
"channelTagId": ["structure:fashion"],
"sectionTagId": [],
"author": ["Jane Author"],
"storyType": "comment"
}

Stories with given story type are always Open. Return Open.
Required data:

Story type: Recipe

Example request:

{
"channelTagId": ["structure:books"],
"sectionTagId": [],
"author": ["Ann De la Tho"],
"storyType": "recipe"
}

Invalid response: Freemium. Return Open.


Required data:

580
Structure tag: Art
content type: Article
Author: Jane Author

Example request:

{
"channelTagId": ["structure:art"],
"sectionTagId": [],
"author": ["Paul InvalidResponse"],
"storyType": "standard"
}

Timeout. Return Open.


Required data:

Structure tag: Art


content type: Gallery

Example request:

{
"channelTagId": ["structure:art"],
"sectionTagId": [],
"author": ["Andrew Timeout"],
"storyType": "standard"
}

Unexpected error. Return Open.


Required data:

Structure tag: Art


content type: Live Article
Author: Jane Author

Example request:

{
"channelTagId": ["structure:art"],
"sectionTagId": [],
"author": ["Tom Unexpected"],
"storyType": "standard"
}

Hint
To send those requests directly to the api you can use CURL. Here is the commad:

curl -XPOST -u admin:vagrant http://author.local.telegraph.co.uk:4502/bin/telegraph/author/openpremium -H


"Content-Type: text/json" -d '
PUT JSON HERE
'

581
The only thing which needs to be done is to replace "PUT JSON HERE" with proper request. Also credentials and URL should be replaced if requests
should go to different environment than local environment.

582
Preview Servlet (AUT-18)
General
This page describes Preview. Servlet will be called by frontend get preview link for page created in M&Ms

Related JIRA Issue: AUT-18 - Preview article in Mobile view RELEASED

Request:
This servlet accepts GET request. under the following path:

/bin/telegraph/author/cms/preview

with following json in query string:

{
"pageId":"content/telegraph/somepage"
}

Response:
As a response the servlet redirect user preview of his page in mobile view.

583
Sections Feed Servlet (AUT-8)
General
This page describes Sections Feed Servlet. Servlet will be called by frontend to get available section paths for Page creation process.

Related JIRA Issue: AUT-8 - Set Headline and Section for new Page RELEASED

Request:
This servlet accepts empty GET request. under the following path:

/bin/telegraph/author/cms/sections

Response:
As a response the servlet will return json with following format:

{
"status": {
"statusCode": 200,
"message": ""
},
"content": [
{
"label": "Lifestyle",
"id": "/content/telegraph/lifestyle",
"structureTags": [
{
"label": "Beauty insiders",
"disambiguator": "Beauty",
"path": "/etc/tags/structure/beauty/beauty-insiders",
"tagID": "structure:beauty/beauty-insiders"
},
{
"label": "Fashion",
"disambiguator": "Structure",
"path": "/etc/tags/structure/fashion",
"tagID": "structure:fashion"
},
{
"label": "Awards season style",
"disambiguator": "Fashion",
"path": "/etc/tags/structure/fashion/awards-season-style",
"tagID": "structure:fashion/awards-season-style"
}
],
"children": [
{
"label": "fashion",
"id": "/content/telegraph/lifestyle/fashion",
"children": []
}
]
}.
{
"label": "Test Channel",
"id": "/content/telegraph/test-channel",
"structureTags": [],
"children": [
{
"label": "Section",
"id": "/content/telegraph/test-channel/section",
"structureTags": [],

584
"children": []
}
]
},
]
}

585
Server Time Servlet (AEM-4325)
General
This page describes Server Time Servlet. Servlet will be called by frontend to get current server time (used for validation of publication schedule time).

Related JIRA Issue: AEM-4325 - Schedule an article/gallery to be published and cancel the schedule RELEASED

Request:
This servlet accepts empty GET request. under the following path:

/bin/telegraph/author/cms/serverTime

with following json in query string:

{
"pageId":"content/telegraph/somepage"
}

Response:
Response has the following format:

{
"status": {
"statusCode": 200,
"message":""
},
"content": 123123123
}

586
Status codes
In this section you can find all status codes supported by Authoring front-end and back-end api.

NOTE: Please remember that following codes does not map to standard HTTP status codes.

Correct responses:

Codes 200-299:

Response code Message Caused by

200 - Everything was fine.

201 - Content was successfully published.

Codes 300-399:

Response code Message Caused by

301 - Redirection required, redirection URL provided in response content

Error Codes:

Communication error codes 400-499:

Error code Message Caused by

405 Method not supported. Request method is not handled by webapp

CQ/server error codes 520-599:

Error Message Caused by


code

520 Repository Exception.

521 Parsing JSON with components content failed. User tried to create new page, but request data was invalid.

522 Error occurred during page creation in AEM Internal error occured when page was being created in AEM.

523 Parent page does not exists. Page creation has failed User tried to create page under section which doesn't exists in AEM

524 Page has been created but content wasn't saved. Page has been created, but Headline component content wasn't saved due to
internal error

525 Page title was empty Page title wasn't provided. Page has not been created.

526 Page data was incomplete. Cannot retrieve Request for edit page contained invalid data.
requested page.

527 Page cannot be found. User tried to edit page which doesn't exist in AEM

528 Cannot get properties for one of the components. JCR problem occurred while reading components form page.

529 Requested page does not exists. User tried to read/edit/publish page that no longer exists in CQ.

530 Publish process can not be complited. Replication problem occurred while performing publish process.

531 Assets cannot be retrieved. Error occured when tried to retrieve AEM Assets.

532 Workflow action not supported. Invalid request to Workflow Manager servlet.

587
Story Copy Servlet (AEM-3367)
General
This page describes Page Copy Servlet. Servlet will be called by frontend to copy an existing story.

Related JIRA Story:


AEM-3367 - Create a copy of a story from within Authoring RELEASED

Servlet path
Servlet is available at path:

/bin/telegraph/author/cms/copy-story

Copy an existing page


To copy an existing page, POST request must be sent.

Request
To copy an existing page frontend must sent POST request with query parameter:

pageId=88afde61-ad3e-4026-af72-1382059b388b

The id is the authoringUniqueId which can be found in page properties on authoring tab

Response
Response contains page id of new page, which is a copy of the original one (without publication properties, different authoringUniqueId and pageId)

{
"status": {
"statusCode": 200,
"message": ""
},
"content": "87fe7e18-fa6d-11e5-a920-080027f54967"
}

588
User Information Servlet (AUT-5)
General
This page describes User Information Servlet. Servlet will be called by frontend to get information about User. Information will be displayed in toolbar in the
top right corner

Related JIRA Issue: AUT-5 - Display logged in users name in toolbar RELEASED

Request:
This servlet accepts empty GET request. under the following path:

/bin/telegraph/author/auth/userinfo

Response:
As a response the servlet will return json with following format:

{
"status":{
"statusCode":200,
"message":""
},
"content":{
"fullName":"John"
"givenName":"",
"familyName":"Smith",
"id":"johnsmith",
}
}

589
User Logout Servlet (AUT-4)
General
This page describes User Logout Servlet. Servlet will be called by frontend to log out user from system.

Related JIRA Issue: AUT-4 - Logout of M&Ms Author Tool RELEASED

Request:
This servlet accepts empty POST request. under the following path:

/bin/telegraph/author/auth/logout

Response:
As a response the servlet redirect user to AEM login page.

590
Workflow Manager Servlet
General
This page describes Workflow Manager Servlet. Servlet will be called by frontend to perform workflow actions on pages created with M&& tools.

Related JIRA Issue: AUT-20 - Publish Article from Edit Page RELEASED

AEM-4325 - Schedule an article/gallery to be published and cancel the schedule RELEASED

Request:
This servlet accepts POST request. under the following path:

/bin/telegraph/author/cms/workflowmanager

The request body should contain json with following structure:

{"pageId": "20dbd8e1-3a33-11e5-9b44-080027692dbf", "action": "PUBLISH"}

PageId can be found in page properties on Authoring tab

Response
For publish:

{
"status":
{
"statusCode": 201,
"message": ""
},
properties: {
"updatePublishTime":false
}
}

For unpublish:

{
"status":
{
"statusCode": 202,
"message": ""
},
properties: {}
}

For schedule:

{
"status":
{
"statusCode": 201,
"message": ""
},
properties: {}
}

For unschedule:

591
{
"status":
{
"statusCode": 202,
"message": ""
},
properties: {}
}

Possible actions

Action Description

publish Publish content specified by pageId

unpublish Unpublish content specified by pageid

schedule Schedule page to be activated later (removes previous schedules)

unschedule Unschedule page activation

Response:
As a response the servlet will return json with following format:

{
"status": {
"statusCode": statusCode,
"message": ""
},
"content": ""
}

592
Publish Action (AUT-20)
Action called to publish page created with M&Ms tool.

Request:
{
"action":"PUBLISH"
"pageId":"/content/telegraph/lifestyle/fashion/testarticle"
}

Response:
As a response the servlet will return json with following format:

{
"status": {
"statusCode": 201,
"message": ""
},
"content": ""
}

593
Logging with New Relic and ELK
Summary
TMG technology department is using both New Relic and ELK (Elasticsearch, Logstash & Kibana) for purposes of monitoring and incident resolution. This
document describes use cases for both of these tools. Nagios is also used by Web Support team.

New Relic
Strengths

Out of the box solution


Integration into application platform requires very little effort
Can capture JVM stacktraces automatically and on demand.

Weaknesses

Heavy customisation not possible


Slightly complicated licensing model - lot of separate products with different levels

ELK
ELK refers to combination of Elasticsearch, Logstash and Kibana which together provide nice stack for analysing log files and other events.

Strengths

Open Source and free


Very configurable; can produce variety of reports and dashboards

Weaknesses

Requires significant configuration to be useful (e.g. properly filter log level data)
Focused on log files - doesn’t collect anything just because it’s installed

Use in Authoring

New Relic
Monitoring performance
Monitoring NFRs / SLAs
Monitoring errors in front end code
Alerting for slow performance
Acquiring Java stack traces

ELK
Storing log files in easy to access format
Monitoring number of errors in server logs
Incident resolution
Alerting for anomalies (e.g. large number of errors)

Log Levels
It's important to choose log level that is relevant for the information being logged. Here's good guidelines for choosing them - more ideas can be found from
the original article.

Level Description

594
ERROR Something terribly wrong had happened, that must be investigated immediately. No system can tolerate items logged on this level. Example:
NPE, database unavailable, mission critical use case cannot be continued.

WARN The process might be continued, but take extra caution. Actually I always wanted to have two levels here: one for obvious problems where
work-around exists (for example: “Current data unavailable, using cached values”) and second (name it: ATTENTION) for potential problems
and suggestions. Example: “Application running in development mode” or “Administration console is not secured with a password”. The
application can tolerate warning messages, but they should always be justified and examined.

INFO Important business process has finished. In ideal world, administrator or advanced user should be able to understand INFO messages and
quickly find out what the application is doing. For example if an application is all about booking airplane tickets, there should be only one INFO
statement per each ticket saying “[Who] booked ticket from [Where] to [Where]“. Other definition of INFO message: each action that changes
the state of the application significantly (database update, external system request).

DEBUG Developers stuff. I will discuss later what sort of information deserves to be logged.

TRACE Very detailed information, intended only for development. You might keep trace messages for a short period of time after deployment on
production environment, but treat these log statements as temporary, that should or might be turned-off eventually. The distinction between
DEBUG and TRACE is the most difficult, but if you put logging statement and remove it after the feature has been developed and tested, it
should probably be on TRACE level.

595
NFRs - Non-functional requirements
Note: These NFRs are currently being refined.
Functionality
Capability (Size & Generality of Feature Set), Reusability (Compatibility, Interoperability, Portability), Security (Safety & Exploitability)

Name Description Mandatory?

Remote access Service must be available via remote access for 500 users Yes

On-site access Service must be available for 500 users using it on-site. Yes

Security Service and data must be secured from access by unauthorised parties Yes

Usability (UX)
Human Factors, Aesthetics, Consistency, Documentation, Responsiveness

Name Description Mandatory?

Screen size Yes

Browser Google Chrome 35. Will change when VDI default browser changes. Yes

ATAG 2.0 Meets ATAG 2.0 guidelines No

Notifications User is provided notification or progress indicator for actions longer than 1 second Yes

Colour pairing Colours are suitable for colour blind users and have sufficient contrast Yes

Font sizes It's possible to adjust font sizes Yes

Non mouse based interactions Users must be provided with non mouse based interactions where appropriate. No

Field tab order Human sensible tabbing order trough input fields. No

Error messaging Users must be provided with clear, actionable error messages if / when any network delays occur Yes

Reliability
Availability (Failure Frequency (Robustness/Durability/Resilience), Failure Extent & Time-Length (Recoverability/Survivability)), Predictability (Stability),
Accuracy (Frequency/Severity of Error)

Name Description Mandatory?

Availability 99.99% availability excluding agreed maintenance windows Yes

Support (one in spreadsheet is 6am to midnight; this needs to be agreed because it's not even close to that)

Outage recovery

No data loss

Performance
Speed, Efficiency, Resource Consumption (power, ram, cache, etc.), Throughput, Capacity, Scalability

Name Description Mandatory?

Open application Finder screen Opens in 1 second Yes

Search in Finder < 250ms Yes

596
Create story (article, gallery) Created in 1 second Yes

Open story (article, gallery) Opens in 1 second Yes

Save story Saves in 1 second Yes

Publish story - started < 1 second Yes

Publish story - replication completed < 5 seconds Yes

Search for author < 250ms Yes

Search for keyword / tag < 250ms Yes

5MB image upload Upload completed in 5 seconds Yes

25MB image upload Upload completed in 10 seconds Yes

5MB image available in preview Renditions for uploaded image available in x seconds Yes

25MB image available in preview Renditions for uploaded image available in x seconds Yes

Supportability
(Serviceability, Maintainability, Sustainability, Repair Speed) - Testability, Flexibility (Modifiability, Configurability, Adaptability, Extensibility, Modularity),
Installability, Localizability

Name Description Mandatory?

597
Open Premium API
General
This section describes the real and mock API which is used to determine if the story status is free or premium.

598
Solution Architecture
Telegraph Authoring is a custom built UI for journalist to create and manage web content. It's currently built for AEM platform but key design criteria is to
separate implementation well enough from AEM to allow it to be used with different CMS platforms if that will be required.

01 Business Architecture
02 Application Architecture
03 Business continuity plan / Disaster Recover

599
01 Business Architecture
Capabilities

600
02 Application Architecture
System purpose
One of the key points that has come out of analysis of the existing editorial systems is that they are complicated and difficult to use, causing inefficiencies
in the creation of content and management of the website.

Additionally there is a move to enable Editors to create Content rather than just Web pages as TMG needs to be able to produce content for multiple
platforms and respond to new platforms as they develop.

To address these issues TMG are building a bespoke Editorial interface for creating content. This will give control and ownership of the tools that Editors
use back to TMG where in the past we have been reliant on out of the box CMS interface solutions.

High Level description of approach


The approach is to write a custom web application for the Authoring interface that will interface with AEM through its RESTful APIs in order to create the
pages using the existing developed templates and components that are required for each page.

This application becomes a layer on top of the AEM product that will simplify and standardise the editorial experience, and as far as possible remain a
consistent experience regardless of the underlying technology used to deliver the site. In practice there will be some tight coupling between TMG
Authoring and AEM but it should be possible with some work to decouple and replace AEM with another delivery platform.

Constraints
AEM is to be the system that TMG Authoring will create content within
AEM APIs are to be used
TMG Authoring is restricted to create content in the format that the existing Templates and Components are expecting it

Non Functional Requirements


These are defined here:

https://docs.google.com/spreadsheets/d/12rXfNJ7V2mnOMpm2BkwpCTs4hkpqg5k7tfsEo-6Qsg0/edit

Overall architecture
The TMG Authoring application will run on the existing AEM Author instances, so the network diagram would be very the same as for AEM. See below:

https://www.lucidchart.com/documents/edit/8c0c90af-30c3-4ed5-8cf8-e9c34367b872

In addition there are 2 other new services

1. Asynchronous messaging is provided by PubNub at the moment but is designed to be easy to switch if there is need to do that.
2. Elasticsearch is used to index content and assets for fast retrieval.

Front end application is written in HTML/JS/CSS using a number of frameworks and libraries. It's designed to be as portable as possible but it deployed
into AEM Authoring servers.

Back end application provides a number of RESTful web services and is tightly coupled into AEM platform.

601
Authentication and authorisation
Authentication is based on AEM platform authentication. Users of Telegraph Authoring are added to group 'authoring-ui'

In the future additional groups can be defined to have more fine grained control.

Sequence diagram for article creation


This is a sequence diagram for basic article creation. It should be used to get an idea how every part of the workflow is typically done. Any other workflows
are easily understood by inspecting network requests made during the operation and no effort will be made to provide complete UML diagrams for each of
them.

602
Front End architecture
Diagrams below describe "how things fit together" in front end application.

UI composition diagram

603
UI Data Flow Diagram

604
Prototype (constantly evolving)
This is available here: http://telegraph-cms.appspot.com/

More information about the prototype.

605
Page Status

606
03 Business continuity plan / Disaster Recover
Authoring relies on BCP / DR procedures and practices of AEM platform.

AEM-2018 - Resilience under failover conditions (NFR) CLOSED identified that currently failing over to backup server instance will show unhelpful
message to the user which is likely to cause data loss.

607
Tagging - AEM and Semantic
Overview:
Inital Requirements captured verbatim from Malcolm - Unknown User (smithg) Unknown User (haydenr) are ratifying. Platform team JIRA story.

1. Known versus new tags


a. Are we only expected to suggest tags that are already approved
b. Or do you expect the system to suggest people, places ...etc that are not yet in the approved tag list and then
trigger an approval workflow?

Journos can use unapproved ones but they are only auto suggested once they are added to approval list.

1. Simple versus intelligent matching


a. Relatively simple matching involves
i. Matching only terms that are directly represented in the text
ii. Matching aliases e.g. this would return the approved term "Manchester United Football Club" when "Man
U", "MUFC", "Manchester United" or "Manchester United Football Club" was found in the text
iii. Applying very basic context, for example if AEM authoring passes something like article_type = football,
thetagging solution would only suggest tags from the approved tags for football (so "James Brown" in the
text might result in the suggestion "James Brown Whitby Town FC" not "James Joseph Brown Singer")
iv. Applying simple rules about the number of occurrences of a term in the text

I think we'd want 1, 2 and ideally 4. Can live without 3.

1. intelligent matching involves some combination of


a. Fuzzy matching e.g. spelling mistakes that may not be picked up by spell checkers e.g. "Ford Mondoe" would
match "Ford Mondeo"
b. Statistical classification which involves things like collecting a lot of news stories about natural disasters and
training the system to tag similar articles "Natural disaster" even though the term or an alias does not actually
occur in the text. It can also be used to disambiguate "Oak" the insurance company from "Oak" the tree which
happens to be at the beginning of a sentence and is also capitalized
c. Non machine learning based inference which involves inferring something that isn't in the text by rules or other
means e.g. If a Hilton hotel is mentioned in the same sentence as Edgeware Road, return the suggested tag"Hilton
London Metropole Hotel". This also includes things like the example you mentioned of assuming Arsenal means
weapons arsenal when it occurs in an article that mentions Libya a lot.

Not needed for launch.

1. Human versus machine moderation


a. Human moderation: in the presence of ambiguities, a person resolves them by explicitly selecting or deselecting
suggested tags e.g. if Paris turns up in an article it might result in the suggestions "Paris France" and "Paris
Texas" and a person would have to remove one (or more)
b. Machine moderation, people still review suggestions, however the system learns from their selections over time
and improves suggestions accordingly (among other machine driven options)

1.1 is fine for launch.

1. For sports (or any other domain where we may have a feed of 3rd party data), do you want to
a. manually enter all teams, players, fixtures ...etc.
b. get them from Opta and add some telegraph specifics

Dont' really understand, but we should start with some one else's database that we add to.

608
Background
As part of Q2 PI the Authoring team integrated with AEM to allow users to add existing AEM Tags to Articles and Stories. Q3 requirements cover the
creation of new tags from within the Authoring tool that are then available from AEM. Q4 will see the integration with semantic tagging to allow for auto-
suggest functionality where tags will be suggested based on the article content.

During Q3 planning conversations were held with Malcolm Coles and Graham Smith around the requirements and solution for the Auto-Tagging element of
this work. This page records the assumptions made and should serve as a strawman for further conversations.

Requirements are split in 2. The first covers the AEM centric creation of Tags from within the Authoring Tool. The second covers the integration with
semantic tagging to provide auto-suggest of tags based on content. It is likely that the implementation of the first, in Q3, will have implications for Q4 and
subsequent work hence they are being covered together.

NB The terms "Semantic Tagging" and "Semantic Tags" refers to the non-AEM tagging solution currently being explored by Architecture and are very
much placeholders until a more specific name can be used. The primary use of these terms is to differentiate from the AEM tags already in use.

Creating new Tags in Authoring

AEM-1008 - Add new keywords to a story CLOSED

An Authoring User, with the correct AEM permissions, may add a non-existent keyword to the Tags on a story. On save this will add that tag to the
Standard folder in AEM Tagging. A manual process will then take place to move the newly created tag to the correct namespace in AEM.

Assumptions
1. New tags are created in the Standard folder in AEM on save of story in Authoring
a. We should be clear, this is just to inform context (aka namespace - e.g. cars). This is to limit the search for content with tags outside that
structure
2. Users without the required AEM permissions will not be able to create new tags in Authoring
a. Is this the ability to propose new tags or suggest new tags ? See Malcom's note above.
3. A manual process, inside AEM, will ensure newly created tags are placed in the correct namespace
a. Is the interface to add tags is in scope?
4. De-duplication/merging of incorrectly created tags will be handled manually within AEM
a. This will have to be via a UI, as per above
5. Any requirements to create AEM tags in the semantic world will be handled outside of Authoring
6. Existing AEM components won't require any changes to continue working as intended

User flow in Authoring


1. User adds a new tag in Authoring
2. User saves/publishes the Article

Auto-Tagging content in Authoring


AEM-444 - Suggest Topic Tags for an Article based on the Headline and Article Body RELEASED

An Authoring User will be able to "auto-tag" their article. This will involve the article body being interrogated and tags suggested based on it's content.

Assumptions
1. An API will be made available that the Authoring tool will push content to and receive back the keywords that have been identified within the
text
a. In step 1, why not type these into a 'tag' box?
2. Only article body text will be used to derive tags, not image information or other user entered data, including manually added tags on the article
3. Tags tags returned from Semantic tagging that do not exist in AEM will be automatically created in the Standard folder before being passed to
the Authoring tool
4. AEM tags will be added to AEM pages, not semantic tags
a. These are just keywords submitted to a search function (either in AEM or external, it will work the same way)
5. Manual keyword addition to stories by the Authoring user will continue to use AEM Tags
6. API call from Authoring will be synchronous, at least for first implementation
7. Authoring User can remove some or all of the tags that are auto-suggested
8. Any tags added to the article prior to running auto-tagging will be removed as part of the process
a. Why would we add tags and then remove them?
9. Existing AEM components won't require any changes to continue working as intended
a. We need to check cluster pages and the 'or/and' list functionality

User flow in Authoring


1. User will complete their article and request auto-tagging
2. Authoring tool will be updated to display the returned tags

3.

609
3. User manually removes the tags that are not required
4. User manually adds any additional tags
5. User Saves/Publishes the article

Tag Function assumptions:


1. On accepting a new tag (e.g. a model like'Focus' for a ford car)
2. Until the new tag is accepted, journalists could re-request to add tag (i.e. when creating a new ford Focus article)
a. Has implications for article finder
b. Has implications for generating cluster pages
c. Has implications for List functionality
d. Will duplicate requests (i.e. how do we handle spelling mistakes)
3. Tags are provided as a limited (minimum) set of preferred terms
a. The ability to 'auto extract' is not linked to the ability to tag / limit tags used

Sequence Diagram for Creation of New Tags and Auto-Tagging

610
611
Components and related features
This page is not up to date - see here for a more up to date component catalogue (Richard Spence updates this periodically - this has not been updated
since 2015):

https://docs.google.com/spreadsheets/d/1tc-xIHxcQLI4mdS_g0oLJfJDqQEaOFoH_-pwGmVf24Y/edit#gid=0

Components
Features
Templates
Snippets

Components

Component Description Notes Entity model integration

Telegraph - Components

Article Body Displays an image from the None


Image - old DAM in an article. Accessed
from the content finder in
Author mode.

Article Body Used by review template. None


Headline

Article Body Used by review template at None


Standfirst the verdict

Article Body Insert a table into an article. Minimum 2 None


Table x2

Article Body Displays a text section in an Limited to None


Text - old article. 50,000
characters

Article Date Display article date. None


Included in templates.

Author Bio Used in Author pages to fill None


in details

Author Path Displays author's profile with None


image, name, function and
also a "get in touch" button.

Call to Action Display button to link to Yes. Link URL and button label are normally retrieved from entity but label can be overridden.
Box target page.

Breadcrumb Included by most templates None


if configured to be used

Box It's like a container in which None


you can put anything you
want and apply a style on it.

Byline Displays list of authors None


(deprecated) profiles with name, role
(optional) and location
(optional)

Compare Displays a group of entities Yes (properties configurable in 2 places - in component itself, based on entity definition selected in
in a grid (for a Comparison component, and in entity definition page "Compare Configuration" tab)
page).

Countdown Displays time remaining None


until configured date

Curated List List that consists of None


manually curated and
automatically populated list
tiles.

Curated List 2 List that consists of None


manually curated and
automatically populated list
tiles (this is an update of Cur

612
ated List and meant to
ultimately supersede it)

External Video Embed YouTube, Vimeo, None


Player Vine & Instagram videos
into page

Headline Displays the headline of Limited to


page 400
characters

Image Group Shows image gallery. None

Lead Asset Image which will also None


represent page when used
in lists and other links.

List Displays list of articles, Yes. After selecting entity type in the first configuration tab of component, the Entity configuration tab
reviews, author or becomes available. User has to select Entity definition, and later properties of that entity definition. In
comparison pages. entity definition page properties there is "List View Configuration" tab, on which user can configure which
entity properties are displayed on the list items (dynamic configuration by placeholders). This
configuration is currently used in listItem selector of the following templates: core/review, shop/product

List Of Links Display a list of links based None


on selected tags with
optional header and footer.

List of Tags - Display the tags of the page


old and link to the linked topic
page

Logo Bar Display section logo None

Meta Property The Meta Property None


component displays simple
meta information: label and
date

Most Viewed Displays automatically Based on


List generated content based on the Curated
data derived from analytics. List
component

Renderer Used in Design Mode to Impacts entity behaviour


Config override Entity Rating type
maximum value

Review List of Used by review template None


Links

Stand First Used by Article & Review Limited to None


templates 500
characters

Social Inserts social sharing None


functionality (Facebook,
Twitter, Email or Print) also
supporting Gigyia providers.

Summary Used by Topic template None

Text Displays a text section. Limited to None


50,000
characters

Inline Content Displays inline content that None


is consisted of text and
embedded components.

Tweet Displays an embedded None


tweet using the tweet url.

Tweet Timeline Displays an embedded None


tweet using the tweet's
embed code.

Telegraph - Page Ads

Lower instream Inserts a single ad container defined in None


into the page content adverts-
(second in page flow). config

Upper instream Inserts a single ad container " None


into the page content (first in
page flow).

Telegraph - Review Components

Properties Shows entities and their Automaticall Yes. Fixed component on review template. In the entity property definition there is property: "Show in
Entity value in a two column list y included review" - when checked, property is displayed on the review page (both as a review section and in the top
with links to their between rating table). Also "Top rating configuration" is used in review template.

613
paragraphs sections Author
section and
first
paragraph

Quote Represents a quote by an There is None


author or from a specified not limit set
source on the
length of
the quote

Related Lists reviews with the same Automaticall Yes. Search rule contains entity property taken from entity attached to page.
Entities tags or with similar entity y included
values in every
review
below 'The
verdict'
section

Telegraph - Misc

Outbrain Third party container None


populated by Outbrain

Video Player Ooyala video player None

Features

Feature Description Notes Entity


model
integration

Adverts Adverts are dynamically added to the page via the DFP javascript None

Entities Storage of entities that can be reused across the site and be based on data retrieved trough Nitro APIs Yes

Keywords Search page content for keywords and add links to specified content None

Sticky Box Sticky Box - Cars; Behaviour which prevents items from scrolling out of view in the right hand column, can be applied to adverts Added
Cars and box component in the right hand column by
version CCORE-
711

Sticky Ad Sticky Ad - Fashion; Behaviour which prevents items from scrolling out of view in the right hand column. This differs from the Added
Cars version, the Cars version expects more than one sticky element and stacks sticky elements vertically, the Fashion only by AEM-
expects a single sticky element. The Cars version doesn't set a bottom offset so sticky elements stay stuck until they hit the 807
bottom of the page. Fashion version keeps the sticky elements within a defined container, so a page may contain a number of
containers and each container can contain a single sticky element.

Meta tags Metatags are added to pages based on channel specific configuration.

Navigation Display navigation elements

Twitter For auto tweeting channel specific configurations


Config

Templates

Feature Description Sample Entity model integration

Author Author / journalist information Steve H None

Blank System pages; not to be used with user None


accessible pages

Topic Page about specific topic - currently only in How to... None
Cars

Article Article How to buy a car at None


auction?

Simple No sidebar, simple content page FAQ - About us None

Summary Is this used for anything? None

Film - Entity Page Mostly automated listing of content related to Birdman Yes. Uses film card snippet.
Template entity

614
Film - Article Page Film article page. Can be sponsored or not. Birdman review Yes. Uses entity property component to render review stars and
Template film card snippet.

Comparison - Shop Best comparison grid page Best Tablets No (Compare component uses them)
Theme

Product - Shop Theme Best product page iPad Mini 2 Yes

Home - Shop Theme Best home page Telegraph Best No

Account Blank Front end only


Template

Home Page Cars home page No

Review Care review page Yes, also together with list component (in listItem selector)

Snippets
Snippet Description Entity model integration

Commons

defaultFooter None

defaultHeader None

defaultSideBar None

Account

defaultFooter None

defaultHeader None

Film

defaultFooter None

defaultHeader None

defaultSideBar None

summaryCard Yes - uses Entity property with topRatingProperties configuration.

615
Adverts
!! WARNING this page is out of date !!
Description
Advert locations are hard coded into the page templates, with the exception of the two in-stream advert components (Lower and Upper instream adverts)
which page authors can manually add to the page content.

Adverts display in the following locations:

Header
Top of right hand sidebar
Bottom of right hand sidebar
Footer

How to use
The adverts configuration is located in the CQ Author instance at the following URL /etc/telegraph/core/adverts-config.html (link is available from any
page in 'design mode')

Configuration
Name Required? Description

HTML id Unique ID for the advert container

CSS classes Additional class name if required

Name Type of ad being requested eg; 'ban', 'mpu', 'sky' etc... accepts a comma separated list

Allowed Sizes Physical size (in pixels) e.g. '970x90', accepts a comma separated list

Advert type The ad invocation method. eg; 'adi'

Extra parameters This allows for arbitrary key-value-pairs

Tag Type An integer that dictates the output text/tag

View port Breakpoints The breakpoint the advert will display e.g. 'lg', accepts a comma separated list

Sticky box Fix the ad to stay within the view port (only applies to ads in the right hand column)

See Ads for more information on the ad configuration

Dialog
Right click on the item in /etc/telegraph/core/adverts-config.html and choose 'Edit'

616
Display
The ads config gets written to the relevant component in the HTML e.g.

Code location

/apps/telegraph/core/commons/components/advert

uk.co.telegraph.core.commons.advertconfig.AdvertConfigModel

Known issues

Suggested improvements

Related links
Ads
Lower and Upper instream

617
Article Body Headline
Description
Article body headline is used on different page templates and displays an article headline text.

How to use it
The components is automatically added to a review page when created and they need to be configured accordingly. If the template does not display a
headline, it can be added to a paragraph using the page design mode and choosing headline from the No Group Defined component group.

After that, the Headline component can be chosen from the sidekick in General group.

618
If the headline is not configured, the following message is displayed:

Configuration

Name Required? Type Description

Headline Text Text that will be displayed on the page as headline.

Style Select Box Css style set for all components inside box

Dialog

619
Example look
Headline text: Comfort, Dashboard layout

620
Code location
/apps/telegraph/core/commons/components/articleBodyHeadline

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/articleBodyHeadline

uk.co.telegraph.core.article.headline.HeadlineModel

621
Article Body Image - old
Description
Article Body Image component is used to include an image on an Article Page.

How to use it
The component is available in the sidekick in Telegraph - Components group.

To use you need to drag and drop inside the parsys, then double click and drag an image from the content finder. In the "Image Configuration" tab the
"Image Alt" field is required, if it is not set the following error will be shown:

In addition, the Caption field is optional and can also be disabled by checking the "Disable Image Caption" checkbox. Finally, the "Styles" tab is an optional
extra to change the style of the component, default is set to 'none'.

622
Configuration
Name Required? Type Description

Image Smart Image Drag and drop from the content finder

Image Alt Text Text that will be displayed on the page if the image is not available

Caption Text Image caption text

Style Select Box Css style set for all components inside box

Dialog

623
Example look

Code location
/apps/telegraph/core/commons/components/articleBodyImage

Known issues
N/a

Suggested improvements
Version 1.0

624
625
Article Body Standfirst
Description
Article body headline is used on different page templates (review pages for instance) and displays an article standfirst text, just under the article headline.

How to use it
The components is automatically added to the review page when created and they need to be configured accordingly. If the template does not display a
standfirst, it can be added to a paragraph using the page design mode and choosing headline from the No Group Defined component group.

After that, the standfirst component can be chosen from the sidekick in General group.

626
If the headline is not standfirst, the following message is displayed:

Configuration

Name Required? Type Description

Standfirst Text Text Text that will be displayed on the page as standfirst.

Style Select Box Css style for article standfirst text

Dialog

627
Example look
Standfirst text: "Welcoming interior, but struggles to deal with some bumps", "Clear, concise, mostly easy to use"

628
Code location
/apps/telegraph/core/commons/components/articleBodyStandfirst

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/articleBodyStandfirst

uk.co.telegraph.core.commons.standfirst.StandfirstModel

629
Article Body Table
Description
Article Body Table component is used to include a table on an Article Page.

How to use it
The component is available in the sidekick in Telegraph - Components group.

To use you need to drag and drop inside the parsys, then double click to open. By default you are presented with a table of 2 x 2. In order to insert the
table at least one field must be populated with a value. By default the styling is set to alter colours between even and odd rows. Finally, the "Styles" tab is
an optional extra to change the style of the component, default is set to 'none'.

Configuration
Name Required? Type Description

Style Select Box Css style set for all components inside box

630
Icons

Going from left to right:

1) Edit properties of existing table

2) Edit properties of selected cell(s)

3) Insert row above current row

4) Insert row below current row

5) Delete current row

6) Insert column to left of current column

7) Insert column to right of current column

8) Delete current row

9) Toggle text "Bold" on and off

10) Toggle text "Italics" on and off

11) Toggle text "Underlined" on and off

12) Align cell text left

13) Align cell text center

14) Align cell text right

15) Create hyperlink from selected text

16) Remove hyperlink from selected text

17) Create anchor link

18) Toggle unnumbered lists on and off

19) Toggle numbered lists on and off

20) Decrease indentation

21) Increase indentation

Dialog

631
Example look

Code location
/apps/telegraph/core/commons/components/articleBodyTable

Known issues

632
N/a

Suggested improvements
Version 1.0

633
Article Body Text - old
Description
Article Body Text component is used to include a section of text on an Article Page.

How to use it
The component is available in the sidekick in Telegraph - Components group.

To use you need to drag and drop inside the parsys, then double click to open. By default you are presented with an empty text area. In order to insert the
article body text at least one character must be inserted. In terms of formatting, there are basic text edit features such as lists, hyperlinks, text alignment,
indentation, cut, copy, paste, bold, italics and underline. For the styling of the text you are given tree options from the drop down menu - paragraph,
heading 3 and heading 4 (self explained).

634
Finally, the "Styles" tab is an optional extra to change the style of the component, default is set to 'none'.

Configuration
Name Required? Type Description

Style Select Box Css style set for all components inside box

Dialog

Example look

635
Code location
/apps/telegraph/core/commons/components/articleBodyText

Known issues
N/a

Suggested improvements
Version 1.0

636
Article Date Component
SUPERSEDED

This component has been superseded by the Article Date component.

Description
The Article Date component is currently used by other components, for instance by the Author component and displays the article publication date.

How To Use It And Configuration


The Article Date component is not manually configurable, other components that use it can pass a customclass parameter in order to change its design.

Example usage by author.html:

<sly data-sly-unwrap data-sly-use.articleDate="../articleDate/articleDate.html" data-sly-test="${showDate}"


data-sly-call="${ articleDate.dataTime @customclass=''}" />

Example Look

Code Location
/apps/telegraph/core/commons/components/articleDate

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/articleDate

uk.co.telegraph.core.article.model.ArticleDate

637
Author
SUPERSEDED

This component is no longer in use. It was superseded by the Byline (deprecated) and Article Date components

Description
Author component is used to include Author Bio component from AuthorPage.

Original requirements (possibly out of date by now)

How to use it
The component is available in the sidekick in Telegraph - Components group. To use you need to drag and drop inside the parsys, then double click and
select author path.

Configuration
Name Required? Type Description

638
Configuration tab

Author pathfield Path to the author page

Styles tab

Style select Allows to select different design style for the component.

Channel Specific Features


Feature Description

Author date Display page publication date inside author component. Publication date can be overridden in page properties.

Dialog

Display

Element Description

Author image With all data in html, like image alt, caption etc.

Ii is a link to the author page

Author name and surname Link to the author page

Job role

Email button

Twitter button

Example look
1. When path field is empty

2. When path field is correct

639
Code location

/apps/telegraph/core/commons/components/author

Known issues

Suggested improvements
Version 1.0

640
Author component configuration for Film Channel
If you are unable to view the screencast, you can download it - author-date.mov

Your browser does not support the HTML5 video element

641
Author Content (ID) Component Requirement Overview
Target Sprint Release Sprint 6 & 7

Version 0.1

Theme Author Content (ID) Component

Document status Draft

User Story Creator Lindsay Flitton

User Story Owner Ed Keohane

Developers Lead Developer

QA Lead Tester

Template Mind Map

Overview

Component Name
Author Content (ID)

Component Description
Creation of an author ID component which will contain the author's details (name, location, photo, e-mail address & if applicable job title). This component
can then be used to add the author details to an article providing a link to the author's page (see author page component page for details of the page
component)

Users and Workflow

Users
Describe users of the Component and how they will utilise it.

User User Key User Needs Internal or


Name Description External

642
Editor e.g. understanding customer engagement, optimising content placement and testing presentation options to optimise KPIs e.g. internal
such as views and social sharing, ensuring SEO is world class.

Journalist Creator of an The journalist needs to be able to add their details to the article to enable readers to see details of the author
article

Workflows and User Stories


This section will outline the key user stories that support the users' workflows. (consider triggering or triggered workflows, security aspects, customers as
well as internal user needs)

ID User Story Name Comments JIRA Issue Link Priority Component


Version

CH_ Editor As an editor I want to add Capability to enable the article author details to be Mandatory V0.1
247 the article author details to input into an article -story covers the author name
an article so the user can only
Error
see who wrote the article
rendering

macro 'jira'

Unable to

locate Jira

server for this

macro. It may

be due to

Application Link

configuration.

CH_ Editor As a CMS user Capability to create an author ID within a Mandatory V0.1
CHEET-279 - Create
279 I want to be able to create repository that captures the author's forename and
an author id where one surname that can be utilised when adding author Author ID DONE
doesn't exist details to an article (as per CH_247)
So that I can add useful
personal information to it, to 2 scenarios covering new author ID creation and
build an author profile system check when creating author ID to ensure if
one already exists for the author a duplicate is not
created.

CMS User can be editor, writer or journalist.

User Interface and Design


This section will describe the different ways a user can utilise the component and the styles and behaviours of the component - Include mock-ups,
diagrams, visual designs related to the Stories and Acceptance Criteria.

Styles
Author ID's do not have to include a photograph of the author
Author ID's do not have to include a job title for the author
Author ID's do not have to contain a location of the author
Author ID's must always contain the name of the author

Behaviours
The name of the author field can be a URL link through to the Author Page - Biography (Page Component)
Author's name is the first data object displayed in the author ID (as per examples below)

Iconography and visual assets


1. Author Content (ID) displayed within an article - Author photo and name displayed

643
2. Author content (ID) displayed within an article - Author name & job title displayed

3. Author content (ID) displayed within an article - author name, photo and location displayed

Data and Integration


This section includes details of data features, fields, objects that are required within the Component

Data Objects or Properties Description

644
Author Name Name of journalist who authored the article

Author Image Thumbnail Image of the journalist who authored the article

Author Job Title Job title of the journalist who authored the article e.g. Technology Reporter, Theatre Critic

Author Location Location of the journalist who authored the article

Follow Me Option to select to follow the author on social media sites e.g. Twitter

Date and Time Stamp Date and time the article was published

URL The author name is a URL link to the Author Page component

Integrations required
Please outline any integration required for the component.

e.g. This component consumes the XYZ REST API to collect sharing and comment counts for each article in the list. More details on the API or
integration (link here).

Configuration

Dependencies
List of components that the Component being delivered within the User Story has.

Component Component Description Dependency e.g. used by or used for Requirements


Name Overview Page
Link

Author Page Page dedicated to a Telegraph author - biography Used for Author Page - Author ID set as a link on article that can be Author Page
selected to view the article author's bio page (includes a list of articles Component
written by the author) Requirement
Overview

Article Main article view created based on a template, and Used for Article page - Author details are included within the article Article Page
using 1 one or more components e.g. Image, view (this links to the author page)i Component
Headline, Body Copy etc Requirement
Overview

Options
Please list the key configuration options that are available when this component is being used.

Option Name Option Description Default?

Display author location Allow the option to display the location of the author Yes (if a location is available)

Display author job title Allow the option to display the author's job title Yes (if job title is available within the author ID)

Display author image Allow the option to use a thumbnail image of the author Yes (if an image is available within the author
ID)

Display author forename and Allow the option to display the author's forename and Yes - default
surname surname

Non-Functional Requirements
Please consider the key NFRs for this components and ensure they are included, where relevant, in the acceptance criteria of the user stories.

ID Non Functional Requirement Area Priority

645
# Description of requirement Reliability, Performance, Accessibility, Security, etc Priority of requirement

SEO Requirements
SEO ID Subject Requirement

SEO_34 Article All article pages should have a byline with author attribution

SEO_92 Micro-formats Where applicable, it should be possible to implement micro-data for the following content types:

Author profiles

SEO_139 Byline All content types should have a byline (article, gallery, video), this must include:

Author name
Published date and time (this must update if article publish time is updated)
Link to author profile page
Contain rel="author" link to journalist's profile page in source code

SEO_39 Authorship Bylines should link to a journalist's author page with the attribute rel="author" by default

SEO_141 Authorship Author name on byline should link to the author's journalist profile page

SEO_142 Authorship Author image on byline must be suitably optimised

SEO_143 Authorship The byline must be able to contain the location of the author (i.e. Emily Smith *in Istanbul*) when specified within the CMS

SEO_144 Authorship The byline must be able to contain multiple authors

Other

Out of Scope
List the features discussed which are not being delivered within this User Story and are therefore out of scope or may be delivered later or via another
User Story

Questions
Below is a list of questions to be addressed as a result of this User story including any potential gaps or behaviour questions:

ID Question Outcome Status Owner

1 Lionel Le Boiteux & Ed Keohane Open LF

CHEET_271 does not contain the requirement to add an author image, job title etc to
the author ID component but only covers the forename and surname of the author?
Do we need to include these requirements?

The addition of image, location, job title, biography etc is within CHEET_281 - Display
Author Page - should this info not be within the Author
ID?

2 Ed Keohane & Lionel Le Boiteux Open LF

Does the creation of an author ID :-

a) automatically create an author page?

OR

b) automatically pull the ID info into the author page when creating the author page?

3 Ed Keohane & Lionel Le Boiteux Open LF

There are no stories covering the amendment of an author ID e.g. author marries and
changes surname - do we require these?

Do we need to test if the author ID is changed will these changes reflect in existing
areas of the site where the author ID component has been utilised?

4 Raised by Marco Perra: LF - CHEET_279 covers the first time creation of Open LF
the author ID. Awaiting confirmation from Lio / Ed

646
It is the first time an Author is used and therefore the mandatory details must be as to mandatory details for the ID as this is not
entered (e.g. name, etc...) confirmed within the ID stories.

this creates the reusable Author object - LF - Automatic creation of author page as a
does this automatically create them an Author page too? consequence of creation of author ID raised to
Lio / Ed

5 Raised by Marco Perra: See US CHEET_247: Closed LF

It is the second + time that an Author is being used, so you are 'looking up' and Scenario 1 - Editor adds existing author
selecting one that already exisist (e.g. Autocomplete being a mechanism to enable information to article
this)

6 Raised by Marco Perra Open LF

Ed Keohane Can you select an Author that is not you?

Workflow question?

Raised by Marco Perra: LF will follow up persona's / user's with the work Closed LF
being completed by Fabio and Chei - this will be
Is the user a writer or an editor or _journalist_? Pls specify user at the top as we need aligned to the template overviews & stories
to build up the catalogue of users as we go through these.

7 Data & Integration - Lindsay Flitton & Ed Keohane - can you please review this Open LF / EK
with Giuseppe Saltini to make sure Author is specified as a data object (e.g, created
once and managed centrally) and validate the fields here.

8 Raised by Marco Perra: Open LF

Ed Keohane - As default, will the system look up your username and pre-select the
Author object linked to it (LF - referring to journalist username?) and therefore will
every writer on the system have generated automatically an Author object upon
provisioning and have the initial details set-up at the outset?

Workflow question?

9 Future consideration ... raised by Marco Perra: Open LF

Then are we considering having TYPES of authors? And/or a hierarchy of them?


(perhaps post MVP but worth thinking of it)

Assumptions
Describe the assumptions associated with the Component e.g. technical or business assumption

647
Author Bio Component
Description
Provides information about the author. Is used by default in Author Page templates and it can be added as a component to other pages.

How To Use It
The Author Bio component, if not automatically included on the page (Author Pages), it can be added to a template using the Design Mode, editing the
template and making the component available. Then it can be simply drag and dropped from the sidekick, under General tab, to the desired area.

Configuration
Tab Name Required? Type Description

Configuration Firstname Text Author's first name

Lastname Text Author's last name

Email Text Author's email address

Twitter Text Author's Twitter account

648
Show count in twitter Radio button If the number of Twitter followers are shown or not
button

size of twitter button Radio button The size of the Twitter button

G+ profile Text Author's Google Plus account

Long Biography Text Author's long biography, not longer than 50,000 characters

Short Biography Text Author's short biography, not longer than 1,500 characters

Job Role Text Author's job role

Author Image Drag and Drop Author's image asset to be dropped here
Area

Author Image Image Alt Text Image alternative text


Configuration

Caption Text Image caption, if left blank, the image caption from DAM is used
instead

Disable Image Caption Radio button Should the Lead Image Caption be disabled?

Styles Style Dropdown The style of Author Bio component. By default None is selected.

Dialog

649
650
Example Look

651
Code Location
/apps/telegraph/core/commons/components/authorBio

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/authorBio

uk.co.telegraph.core.article.author.Author

Known issues / Limitations

Suggested improvements

652
Box
Description
The Box component is used to include css style around all component inside. The component has parsys build in.

How to use it
The component is available in the sidekick in Telegraph - Component group. To use you need to drag and drop inside the parsys, then you have panel to
configuration and available parsys inside.

Available styles:
Style name Description

box-ver_1 Set yellow background

box-ver_2 Remove all border, margin and paddings (automatically added when the Sticky box configuration is active)

Configuration
Name Required? Type Description

Sticky check If checked the box will be sticky (i.e. it will not scroll out of view) This behaviour only applies to box components added to the right
box box hand column

653
Style select Css style set for all components inside box
box

Dialog
To get dialog click "Edit".

Example look

Code location
/apps/telegraph/core/commons/components/box

Known issues
The Sticky box setting is only applied in the right hand column of the page, it is ignored in all other locations. Also, if nested box components have Sticky
box behaviour it is only applied to the outer Sticky box component and is ignored for child elements.

Suggested improvements
Version 1.0

654
Breadcrumb
Breadcrumb
Nickname
(s)

Show the location of the page plus the cluster where the page belongs to a channel has a cluster configured.
Description
For section- driven channels it shows all folders to current page.

For date-driven channels it excluded the date folders.

Once the Primary Tag code is release it will append the primary tag to the end of the breadcrumb

Interactions

Restrictions

Screenshot Item Screenshot


(s)

In the Tools section of AEM (:4502/miscadmin#/etc/telegraph/admin)


Feature Settings page location

Feature Seeting config

Breadcrumb (section driven


channel)

Breadcrumb (date drive channel)

655
"0" in URL is not present in the Breadcrumb
Pages that use Folder template are
excluded from the Breadcrumb

This is because the Evergreen (/0) page has been created using the Folder template.

Location

JIRA

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Breadcrumbs May 26, Aug 04, Andrzej Robert RELEASED Unresolved
5802 - Mark up 2016 2016 Dolinski [X] Toshman
according to
schema.org
AEM- [SEO] Add the Mar 24, Dec 16, Unassigned Jo Mitchell CLOSED Done
5063 first page to 2016 2016 [X]
the
breadcrumb

656
on paginated
pages
AEM- Breadcrumb Mar 16, Apr 05, 2016 Andrzej Simon Ward RELEASED Unresolved
4906 component 2016 Dolinski [X] [X]
has incorrect
layout markup
classes
applied
AEM- Strip date Sep 28, Jan 13, 2016 Anna Gavin Kirk RELEASED Unresolved
2684 from 2015 Karkkainen [X]
breadcrumb in [X]
dated articles
AEM- Truncate Sep 03, Sep 10, Unassigned Mathias CLOSED Done
2256 breadcrumb 2015 2015 Douchet
trail on mobile
AEM- Breadcrumb Aug 28, Oct 20, 2015 Unassigned Mathias RELEASED Unresolved
2188 changes 2015 Douchet
AEM- Backend: Aug 28, Sep 11, Anna Anna CLOSED Done
2184 Remove 2015 2015 Karkkainen Karkkainen
breadcrumb [X] [X]
from section
page
AEM- Remove grey Aug 13, Feb 11, 2016 Unassigned None RELEASED Unresolved
1962 article 2015
category
repeating the
breadcrumb
on articles
AEM- Update Jun 26, May 25, Anna None RELEASED Unresolved
1363 breadcrumb 2015 2016 Karkkainen
[X]
AEM- Breadcrumb Jun 16, Jul 07, 2016 Unassigned Gavin Kirk CANCELLED Unresolved
1214 improvements 2015 [X]
for SEO
AEM- Frontend - Apr 30, Jun 22, 2015 Unassigned None RELEASED Unresolved
454 DEV: style for 2015
breadcrumbs
AEM- Style Apr 27, Jun 22, 2015 Patrycja Melinda RELEASED Unresolved
395 breadcrumbs 2015 Kurkowiak [X] Rogers [X]
on Fashion
AEM-76 Breadcrumbs Apr 10, Apr 10, 2015 Unassigned None TO Unresolved
2015 REFINE

13 issues

Other

Description

How to use it
Can be add on all pages but in order to use it, the breadcrumb needs to be enabled at channel level. To do that, go to Tools / Telegraph / Admin Tools /
Feature Settings to turn it on for the channel in question.

After this operation, the Breadcrumb component can be seen on the templates on which it is included. No further configuration is needed.

Example look
For instance, for the cars channel, the review template includes the Breadcrumb component:

657
Code location
/apps/telegraph/core/commons/components/breadcrumb

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/breadcrumb

uk.co.telegraph.core.commons.breadcrumb.BreadcrumbView

658
Byline (deprecated)
SUPERSEDED

This page is superseded by Byline.

Description
Displays list of authors profiles with name, role (optional) and location (optional)

How to use it
The component is available in the sidekick in Telegraph - Component group. To use, you need to drag and drop the component inside the parsys and
double click on it. In the dialog you need to select the list of authors and provide an optional Role and Location for each of them.

Configuration
Name Required? Type Description

659
Author Path Field Path to an author page

Role Text Role in context of current article

Location Text Location for current article

Style Select Box Css style set for the byline component

Dialog

Example look

660
Code location
/apps/telegraph/core/commons/components/byline

Known issues
N/a

Suggested improvements
Version 1.0

661
Call To Action Box
Description

Displays a button that links to a target page

How to use it
The component is available in the sidekick in Telegraph - Components group.

Drag and drop the component in the required area and double click it to open the component configuration, which has only one tab and one property:
button text, which is not required and will overwrite the entity configuration data when set.

Configuration

Tab Name Required? Type Description

Configurat Button Text Text displayed on the link. If not present, then the entity property value configured as the “Button text property” inside
ion text the entity definition is used instead.

662
To set the “Call To Action fields” inside the entity definition, open the entity definition properties dialog, Product Configuration tab, Call To Action fields
group. The Button text property uses one of the entity property values in order to be displayed on the button.

Important: The value of the call to action url has to start with "http://" (e.g. "http://www.telegraph.co.uk/" is valid, "www.telegraph.co.uk" is invalid).

If these configurations are not performed inside the entity definition of the entity used on the page where we want to use the Call To Action component,
then the following message is displayed instead of the component:

663
Dialog

Example Look

664
Code Location

/apps/telegraph/core/commons/components/callToActionBox

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/callToActionBox

uk.co.telegraph.core.review.cta.Cta

Known issues / Limitations

Suggested improvements

665
Compare
Description
The Compare component is used to include a group of entities on a comparison page.

How to use it
The component is available in the sidekick in Telegraph - Components group.

To use you need to drag and drop inside the parsys, then double click to open. By default you are presented with the default Configuration tab.

The Configuration tab, set the search criteria for entities to display in the component

The Entity Configuration tab, select the entity definition for the Comparison group

Finally, the "Styles" tab is an optional extra to change the style of the component, default is set to 'none'.

Configuration
Tab Name Required? Type Description

Configuration Tags Tree browser Select relevant tags

" Type Select Box Type of entity

" Rules Select Box Filter to apply

" Max items Text Max number of items to display

Styles Style Select Box Css style set for all components inside box

666
Entity Configuration Entity Definition Tree browser Select the Entity Definition

" Type Select Box

" Order Select Box

" Default order Check Box

" Search rules Multi-item panel To allow the author to add search rules

Dialog

Example look

Code location
/apps/telegraph/core/commons/components/compare

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/compare

uk.co.telegraph.core.review.compare.Compare

Known issues / Limitations


The current HTML implementation is a OL, this has it limitations, currently lining up the rows is only possible via setting the height of each cell and hiding
any excess content.

The reason for using a list rather than building the HTML using a table, is that the development time in CQ was quicker and because the display may be
horizontal rather than vertical, this approach allows us to change the orientation, for example at different break-points.

Suggested improvements
Enable output to be rendered in a Table

667
Version 1.0

668
Countdown Component
Description
Countdown component can be added to a page in order to display the countdown in days, hours, minutes and seconds remaining until a set date and time.

How to use it
Create a Homepage first. Then you need to drag and drop inside the parsys from the Telegraph-Component group sidekick and then double click to open:

Double click the component and a dialog opens with two tabs. Tab User Configuration is for inserting the date and time for which the countdown is
measured and also a description of what the countdown refers to. This information is mandatory. On the second tab Developer Configuration there are
two fields. The Maximum Days is numeric and it is used such that if the timer exceeds the maximum number of days specified in this field then the timer
will not show. Just like bellow:

669
Otherwise if the maximum days set is not exceeded by the timer the countdown component looks like this:

Configuration
Name Required Type Description

Count Down Until Date Datetime The end date and time for the countdown

Description Text The information to display about the countdown event

Maximum days Numeric Maximum number of days the count must count, otherwise it is not shown

Test Url Search Box

Dialog

670
Example look

671
Code location
/apps/telegraph/core/commons/components/countdown/

Known issues
N/a

Suggested improvements
Version 1.0

672
Curated List
Description
The Curated List component is used to create a list that consists of manually curated and automatically populated list tiles.

How to use it
The Curated List component is available in the sidekick in Telegraph - Component group. To use you need to drag and drop inside a parsys. The
component will then create another parsys inside it where you can drag and drop Curated List Tile components (Telegraph - Curated List component
group.

You can then edit the Curated List Tile component you just added and either give it page path (for automatic population) or fill in all the fields manually.

Configuration of a Tile

Configuration Required Functionality


'Automatic page tile' area

Page path Page path where the information will be pulled in from

'Manual tile' area

Image Image from DAM

Label Label

Date Date

Title Title

URL Link

'Styles' tab

Style Allows to select different design style for the component.

Automatic page tile details used

Field Source

Image Lead image of the source page

Link Links to the page

Label Tag from the source page, namespace "label:"

Title Source pages title

Date Last published date of the source page

Dialog

673
Example look
Curated List component dropped in the page in editing mode, displaying one valid Tile component with image, one Tile component displaying errors and
one Tile component that hasn't been configured yet. Only the first valid one will be shown in preview/publish mode.

674
Code location
/apps/telegraph/core/commons/components/curatedList

Known issues
Suggested improvements

Version 1.0

675
Curated List 2
Description
The Curated List 2 component is used to create a list that consists of manually curated and automatically populated list tiles. It is an updated version of
Curated List and intended to ultimately supersede it.

How to use it
The Curated List 2 component is available in the sidekick. The editor can then add either "Curated List Tile 2" or "Major News Block Tile" components to
the Curated List 2.

Major News Block Tile should only be used when the style of the Curated List 2 component is set to "V23 - Major News Block".
Curated List Tile 2 will be used in all cases when the style of Curated List 2 is not "V23 - Major News Block". This will be the vast majority
of cases when adding tiles to a curated list.

Configuration of a Tile

Configuration Required Functionality


Confguration

Hide date/time Hides the date time on all tiles in the curated list

Hide primary tag Hide the primary tag from all tiles in the curated list

Heading & Footer

Component heading Curated list heading

Component heading link Link for the curated list heading

Component subheading Not displayed by any of the list styles (possibly redundant)

Component footer link label Not displayed by any of the list styles (possibly redundant)

Component footer link Not displayed by any of the list styles (possibly redundant)

Styles

Style Sets the style of the curated list. Default is "None" but should be set to one of the recongnised style.

Branding

Branding "None" uses the lists branding while "Premium" add premium branding to the list.

Dialog - Curated List 2

Configuration

676
Heading & footer

Styles

677
Branding

Dialog - Curated List Tile 2

Configuration

678
Dialog - Major News Block Tile

Configuration

679
Example look

Code location

Known issues
See AEM-5495 - Curated List 2 fixes TO REFINE

Suggested improvements

680
External Video Player
Description
The Video Player component is used to play external videos from YouTube, Vimeo, Vine & Instagram in embeded mode. Videos can be configured by
typing in the video url.

The component is available in the sidekick in Telegraph - Component group. To use you need to drag and drop inside the parsys.

After dropping it onto parsys, video to be played can be configured by adding the video url in the component's dialog.

Configuration
Name Required? Type Description

Video URL textfield The video URL

Dialog

681
Example look

Code location
/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/externalVideoPlayer

Known issues
Suggested improvements

682
Headline Component
Description
Headline component is used to display the headline of a page.

How to use it
To start create an article page or a simple page. When you open the page the component should be already there and it should look like this:.

Now double click to open the configuration dialog. By default you are presented with an empty text input on the Configuration tab. In the second tab Styles
the style of the headline is selected, default being None.

Configuration
Name Required? Type Description

Headline Text The actual headline text

Style Select Box Css style set for the headline text

Dialog

683
Example look

Code location
/apps/telegraph/core/commons/components/headline

Known issues
N/a

Suggested improvements
Version 1.0

684
Image group
Description
Image group is used to display image gallery. There are no limits about number of images. You can change the order and manage each image. The
component has a button "View larger pictures" to view images in fullscreen.

How to use it
The component is available in the sidekick in Telegraph - Component group. To use, you need to drag and drop the component inside the parsys and
double click on it. In the dialog you need to select the list of paths to the images.

Configuration
Name Required? Type Description

Images list of pathfield List of pathfields to the images. Arrows are using for change the order, and red icon to delete selected.

Style selectbox Css style, at this moment no one is dedicate

Dialog

685
Example look
1. When list of path to images is empty:

2. When images are set:

686
Code location
/apps/telegraph/core/commons/components/imageGroup

Known issues

Suggested improvements
created configuration page when images can be drag and drop from content finder

Version 1.0

687
Image with Text

688
Inline Content
Description
The Inline Content component is used to include text and embedded components on the page. The component dynamically splits the text into paragraphs
creating parsys containers between them to allow editor place embedded components between text paragraphs.

How to use it
The component is available in the sidekick in Telegraph - Component group. To use you need to drag and drop inside the parsys and edit it.

Once text has been added, the content will re-arrange itself and will automatically create parsys areas between the text areas to allow editor insert other
components, for example Quote or Image components. Embedded components can also have different styling options that allow them to float left or right
of the text paragraphs. Please check the embedded components option for further details.

Available styles:
Style name Description

Configuration
Name Required? Type Description

Text richtext Text to be displayed on the page

Dialog

689
Example look

690
Code location
/apps/telegraph/core/commons/components/inlineContent

Known issues
Suggested improvements

Version 1.0

691
Lead Asset Component
Description
Lead asset component is used to display an image in an article page. This image will also represent the page when used in lists and other links.

How to use it
To start, create an article page. When you open the page the component should be already there and it should look like this:.

Now double click to open the configuration dialog. By default you are presented with an empty box on the Lead Image tab.

Configuration
Name Required? Type Description

Lead Image Smartimage The image file that will represent this lead asset

Image Alt Text The image alt to be displayed

If not image is uploaded the image alt is not mandatory,

but if an image is set then the image alt becomes mandatory

Caption Text The image caption to be displayed; maximum length is 1000 characters

Disable Image Caption Checkbox If checked the image caption is not displayed

Dialog

692
In order to change the lead image open the dialog box and drag and drop another image from the left hand menu images tab onto the Lead Image tab.

In order to delete the existing image use the Clear button from the left hand bottom corner found on the Lead Image tab.

693
The exclamation sign button next to the Clear button is used for getting the file reference information about the image uploaded and if you click the link
from the small popup the image file

from the AEM Assets will be opened in another tab.

694
Example look

695
Code location
/apps/telegraph/core/commons/components/leadAsset

Known issues
N/a

Suggested improvements
Version 1.0

696
List
Overview
Lists are made of by the assembly of List Item Types into a pattern that is called a List Version. Authors cannot assemble List Item Types. They can only
choose from a list predefined List Versions.

List Item Types - these are the list item (or tiles) that are used to build the pattern for a given List Version.
List Versions - these are the assembly of a group of List Item Types. This is what the author uses choosing the style of a list

Please refer to the List Version Matrix.

697
How to provide design requirements for lists? - draft
We'd like to introduce checklist related with design requirements for list.
It is associated with current list architecture.

The most important documents about current list architecture:


LINK1. List version matrix:
https://docs.google.com/spreadsheets/d/1mTU1lwyw-7V1dw6JnzvMbmCHww6bkFGlevm-JV8bXsY

LINK2. Available list versions:


https://confluence.aws.telegraph.co.uk/display/AEM/List+Versions

LINK3. Available list's item types:


https://confluence.aws.telegraph.co.uk/display/AEM/List+Item+Types

LINK4. Available list's headlines (*):


https://confluence.aws.telegraph.co.uk/display/AEM/List+Headings

(*) we need update this document (status 04/01/16)

Types of documents which describe design requirements:


DR1. List version
Example here: DR1.pdf

DR2. Item type


Example here: DR2.pdf

DR3. Headline type


Example here: DR3.pdf

Steps to prepare design requirements for new list

698
699
700
List Content Types

701
Content Type Comment

702
Content Type Live

703
Content Type Video
List Item with content type 'Video' needs extra markup:

(1) new class 'video' on <li> level

(2) new wrapper for img with class 'list-of-entities__item-image' and div with class 'video-icon'

(3) wrapper with 'video-icon-wrapper' class + component 'video-icon' with 'video-icon--text-image' modifier in link element with 'list-of-entities__item-image-
container' class

(4) component 'video-icon' with 'video-icon--text-only' modifier in headline element with 'list-of-entities__item-body-headline' class

Please check code below.

<li class="list-of-entities__item video"> <!-- extra markup for video content type (1) -->
<div class="list-of-entities__item-link">

<a href="#" class="list-of-entities__item-image-container">

<!-- extra markup for video content type (2) START -->
<div class="video-icon-wrapper">

<img class="list-of-entities__item-image">

<!-- extra markup for video content type (3) -->


<div class="video-icon video-icon--text-image component">
<div class="video-icon__play">
<div class="video-icon__arrow"></div>
</div>
<time class="video-icon__duration" datetime="P3M1S">3:01</time> <!-- datatime format
reference https://www.w3.org/TR/html5/infrastructure.html#duration-time-component -->
</div>
<!-- END -->

</div>
<!-- extra markup for video content type (2) END -->

<span class="list-of-entities__item-image-rating-container">(...)</span>
</a>

<div class="list-of-entities__item-body">

<span class="m_meta-property">(...)</span>

<h3 class="list-of-entities__item-body-headline">

<!-- extra markup for video content type (4) -->


<div class="video-icon video-icon--text-only component">
<div class="video-icon__play">
<div class="video-icon__arrow"></div>
</div>
</div>
<!-- END -->

<a href="#">(...)</a>
</h3>

<span class="list-of-entities__item-body-rating-container">(...)</span>

<span class="m_entity-property">(...)</span>

<p class="list-of-entities__item-abstract "></p>

</div>

704
</div>
</li>

JavaScript Template
<li class="list-of-entities__item video" data-video-path="{{videoPath}}">
<div class="list-of-entities__item-link">
<a href="{{pagePath}}" class="list-of-entities__item-image-container">
<div class="video-icon-wrapper">
<img data-lazy-loaded="true" class="list-of-entities__item-image" src="{{imageUrl}}" data-frz-
ratio="1.00" itemprop="image">
<div class="video-icon video-icon--text-image component">
<div class="video-icon__play">
<div class="video-icon__arrow"></div>
</div>
<time class="video-icon__duration" datetime="{{videoIsoDuration}}">{{videoDuration}}</time>
</div>
</div>
<span class="list-of-entities__item-image-rating-container">
<span class="list-of-entities__item-image-rating-item">
<span class="list-of-entities__item-image-rating-item-label"></span>
<span class="list-of-entities__item-image-rating-item-numeric">
<span class="list-of-entities__item-image-rating-item-numeric-score">
<span class="list-of-entities__item-image-rating-item-numeric-score-value"></span>
</span>
</span>
</span>
</span>
</a>
<div class="list-of-entities__item-body">
<p class="list-of-entities__item-body-series-title">{{seriesName}}</p>
<h3 class="list-of-entities__item-body-headline"><a href="{{pagePath}}">{{videoTitle}}</a></h3>
<p class="list-of-entities__item-tags">
<span class="list-of-entities__item-tag list-of-entities__item-channel-name">{{channel}}</span>
<span class="list-of-entities__item-tag list-of-entities__item-series-label">{{seriesLabel}}</span>
</p>
</div>
</div>
</li>

705
List for Cars and Film
List component dynamically displays list of pages based on configurable criteria.

Example

Configuration

Configuration Required Functionality


'Configuration' tab

Tags List will display only articles that are associated with at least one of the specified tags

Type What type of pages should be displayed on the list

Review - Only pages created using 'Review' template will be included


Article - Only pages created using 'Article' template will be included
Author - Only pages created using 'Author' template will be included
Comparison - Only pages created using 'Comparison - Shop Theme' will be included

Display Advert If checked, last element of the list will be replaced with an advert

Rules Defines sorting order. Only 'Most Recent' is currently supported

Max number of items Limits number of pages included. If not specified 50 is assumed.
displayed

'Header and Footer' tab

Component Heading Text to display before list. eg. "Editor's Choice"

Component subheading Unused

Component Footer Link Label for the link at the end of the list. eg. "More"
Label

Component Footer Link Page where the link points to

'Styles' tab

706
Style Allows to select different design style for the component. Styles that change layout of the list are named 'list-
of-entities-ver_X'

Type: Comparison
When type 'Comparison' is selected, then the result list will contain valid pages that have all of the Comparison metadata filled in the page properties
Comparison tab (Headline, Description and Image). Invalid comparisons that do not have all of the properties configured will be displayed only in author
mode with error messages.

Code location
/apps/telegraph/core/commons/components/list

Known issues

Suggested improvements

707
List Headings
There are 3 types of headlines for list

Primary Heading
Secondary Heading
Secondary title

Designs: Header_Styles_v1.2.pdf

708
Primary Heading

709
Secondary Heading

710
Secondary title

711
List hover states

712
List Item Types
Overview
List Item Types are the building blocks that are assembled to create a List Version. Authors cannot access a List Item Type to build lists. They are rather
an architectural concept that is used by developers when creating list patterns to build a List Version.

List Item Type 1


List Item Type 2
List Item Type 3
List Item Type 4
List Item Type 5
List Item Type 6
List Item Type 7
List Item Type 8
List Item Type 9

Designs:
item_logic_v2-2.pdf

713
List Item Type 1
List item type 1 - (channel fashion).

714
List Item Type 2
List item type 2 - (channel fashion).

715
List Item Type 3
List item type 3 - (channel fashion).

716
List Item Type 4
List item type 4 - (channel fashion).

717
List Item Type 5
Not styled yet.

718
List Item Type 6
List item type 6 - (channel fashion).

719
List Item Type 7
List item type 7 - (channel fashion).

720
List Item Type 8
List item type 8 - (channel fashion).

721
List Item Type 9

722
List Versions
Overview
A list version is a collection of List Item Types that can be reused by an author when they are butting a List onto a page. The author selects the List
Version under the Style tab off the List component.

Please refer to the List Version Matrix.

Desktop List Versions Gallery

723
724
725
Breakpoints
This page is superseded. Please refer to Breakpoints instead.

For the list variants presented within this section the screenshots titles refer to the following breakpoints (screen width):

Desktop - width for 1008 px and above,


Tablet - width from 730 px to 1007 px,
Mobile - width from 480 px to 729 px.

Please notice there is a specific rule introduced for width equals 479 px and below: the design is based on the "mobile" one but the list items should be
placed in one column only. Thus when two items are in one row for 480px the second one is to be moved below for narrower screens.

Example:

Width = 480 px Width < 480 px

726
727
Important: This rule applies to the list variants only.

728
List Version 1
Desktop

Tablet

729
Mobile

730
731
732
List Version 2
List version originally designed for Sport

Desktop

733
Tablet

734
735
Mobile

736
737
738
List Version 3
List version originally designed for Sport

Desktop

739
740
Tablet

741
742
Mobile

743
744
745
List Version 4
Desktop

746
747
Tablet

748
749
Mobile

750
751
752
List Version 5
Desktop

Tablet

753
754
Mobile

755
756
757
List Version 6
Desktop

Tablet

758
Mobile

759
760
761
List Version 7
Desktop

Tablet

762
Mobile

763
764
List Version 8
Desktop

Tablet

765
766
Mobile

767
768
769
770
List Version 9

List version originally created for Sport

771
List Version 10
List version originally created for Sport

High density
Desktop

Tablet

772
Mobile

773
Medium Density
Desktop

774
Tablet

775
Mobile

776
777
Low density
Desktop

778
779
Tablet

780
781
Mobile

782
783
784
List Version 11
Desktop

Tablet

785
Mobile

786
Hover state

787
788
List Version 12
Desktop

789
790
791
Tablet

792
793
794
795
796
Mobile

797
798
799
800
List Version 13
Desktop

Tablet

801
Mobile

802
Hover

803
804
List Version 14
Desktop

805
806
807
808
Tablet

809
810
811
812
Mobile

813
814
815
816
List Version 15
Desktop

WARNING: TWO IMAGES FOR DESKTOP (didn't have time for combining them together)

817
Tablet

818
819
WARNING: TWO IMAGES FOR TABLET (didn't have time for combining them together)

820
Mobile

821
822
WARNING: TWO IMAGES FOR MOBILE (didn't have time for combining them together)

823
824
Hover

825
List Version 16
DESKTOP

TABLET

826
827
MOBILE

828
829
830
831
News Homepage Timebreaks
Resources:
AEM-2640 - News - Time Breaks RELEASED

AEM-2894 - News Homepage TO REFINE

That long PDF that takes days to get our head around:

https://jira.aws.telegraph.co.uk/secure/attachment/34758/News%20Structure%20v20.pdf

(don't read the PDF, just follow this page as guide...)

Possible Timebreak values


WeekDay DDth Month | Top Stories
Updated 24 hours a day | Latest News
Over One hour ago
Over Two hours ago
Over N hours ago
....
Over Twenty three hours ago
WeekDay DDth-1 Month YYYY
WeekDay DDth-2 Month YYYY
....

Conditions & restrictions


We can't have 2 timebreaks consecutively placed on the list
If a timebreak falls in between 2 lists we should display it in the largest list in width, except for the following condition:
A timebreak never displays above a sponsored block

Examples
First top timebreak

Second top timebreak

Other timebreaks within the same day

832
Last/past days timebreaks

Markup
JS wil be injecting the timebreaks at the correct list item.

CSS should position the timebreak by:

1. offsetting the list item with positive margin top (or bottom if item is the last in the list)
2. offsetting the timebreak with negative margin top (or bottom, if item is the last in the list)

First top timebreak


<div class="js-list-of-entities component-content">

<!-- SOF Timebreak -->


<div class="component-header">
<h2 class="component-heading">Top stories</h2>
<p class="component-subheading">
<!-- Time tag printed by Akamai https://confluence.aws.telegraph.co.uk/display/AEM
/Time+tag -->
<time class="m_meta-property__date" datetime="2015-10-13T14:15:00">
<span class="m_meta-property__date-date">Tuesday 13th October</span>
</time>
</p>
</div>
<!-- EOF Timebreak -->

<ol class="js-list-of-entities__container list-of-entities__container">

<li class="list-of-entities__item " data-timestamp="1447258320000">


<div class="list-of-entities__item-link">
...
</div>
</li>

Second top timebreak


<div class="js-list-of-entities component-content">

<!-- SOF Timebreak -->

833
<div class="component-header">
<h2 class="component-heading">Latest news</h2>
<p class="component-subheading">Updated 24 hours a day</p>
</div>
<!-- EOF Timebreak -->

<!-- empty list -->


</div>

Other timebreaks within the same day


<li class="list-of-entities__item " data-timestamp="1447258320000">
<!-- SOF Timebreak -->
<div class="component-header">
<h2 class="component-heading">Over one hour ago</h2>
<p class="component-subheading"></p>
</div>
<!-- EOF Timebreak -->

<div class="list-of-entities__item-link">
...
</div>
</li>

834
List of Links
List of Links component is used to display various links based on selected tags.

Example

Configuration

Configuration Required Functionality


'Configuration' tab

Tags List will display only links to existing pages that are associated with at least one of the specified tags

Search in What type of pages the links will point to

reviews - links will point to review pages that are tagged accordingly
topic pages - links will point to Topic pages generated for one of the configured tag

'Header and Footer' tab

Component Heading Text to display before list. eg. "Editor's Choice"

Component subheading Text displayed between heading and links

Component Footer Link Unused


Label

Component Footer Link Unused

835
'Styles' tab

Style Allows to select different design style for the component. Styles that change layout of the list are named 'list-
of-links-ver_X'

Code location
/apps/telegraph/core/commons/components/listOfLinks

Known issues

Suggested improvements

836
List of Tags - old
AEM-586 - List of Tags RELEASED

AEM-1263 - List of Tags enhancements RELEASED

837
Logo Bar Component
Description
The Logo Bar component unlike other components like Countdown, List etc... is not available in the sidekick to be dragged and dropped on the page,
instead it is included by default in the header section of a series of templates like: homepage, topic page, review page templates, etc. What it does is to
add an image as the logo in the header of such pages.

How to use it
To start, create a homepage. When you open the page the header component containing the logo bar is already there but can not be seen.

The next step is to create under the new homepage a blank page called application.

Underneath the application page you must create a new page using template Logo Bar and the name of this page must be logoBar (! this part is very
important because it will determine the path for the newly created logo bar page). See the images bellow:

838
The path for the logo bar page is inferred from the code (see image bellow) and in this example it is /content/telegraph/homepage/application/logoBar
/jcr:content/configuration.

So if you instead of Homepage would have had a Cars page the path where the logo would be looked up would be: /content/telegraph/cars/application
/logoBar/jcr:content/configuration

You can see in the image bellow the path for the logo bar page:

839
Now open the logo bar page in Author instance. At this point only a parsys should be available in the page. From the sidekick open the Components tab
and drag and drop

the only available component the Lead Asset. Double click this and in the dialog opened, on tab Lead Image drag and drop an image from the left hand
side menu. This image will

be the logo image displayed in the homepage's header and can be found under path: /content/telegraph/homepage/application/logoBar/jcr:content
/configuration/leadasset/image.

840
The Homepage will look like bellow now that the logo image is set correctly:

Code location
-- the actual logo bar component:

/apps/telegraph/core/commons/components/logoBar

uk.co.telegraph.core.commons.logo.LogoBarView

-- the header that includes the logo bar

/apps/telegraph/core/commons/snippets/defaultHeader

-- the homepage template renderer that includes the default header:

/apps/telegraph/core/commons/renderers/homePageRenderer

841
Known issues
N/a

Suggested improvements
Version 1.0

842
Lower and Upper instream
Description
The lower/upper in-stream advert containers are used to add ad containers into the flow of the document. They are used together the Upper instream
appearing near the top of the document content and the Lower further down.

How to use them


The component is available in the sidekick in Telegraph - Page Ad group. To use you need to drag and drop inside the parsys, there is no configuration,
they use the configuration set in advert-config.

Available styles:
Style name Description

Configuration
Name Required? Type Description

Dialog
-

843
Example look

Code location
/apps/telegraph/core/commons/components/advertContainer/advertContainer.html

/Tools/telegraph/core/advers-config

Known issues

Suggested improvements
Version 1.0

844
Meta Property Component
Description
The Meta Property component displays simple meta information: label and date and can be added on any template if configured so.

How To Use It
It can be used individually or by other components (like the Quote component). To add it to a page go to sidekick to Telegraph - Modules section and
drag and drop the Meta Property component to the wanted area.

If not listed by default for that template, go to Design Mode and make the component available to the template.

When used by other components, like the Quote component, the include looks the following (quote.html):

<div data-sly-use.meta="${ '../metaProperty/metaProperty.html' }"


data-sly-call="${meta.metaproperty @ label=properties.label, date=properties.date}" data-sly-unwrap></div>

Configuration
When used by other components, the label, date, quote parameters need to be passed from inside the calling code.

Tab Name Required? Type Description

845
Configuration Label / Category Text A label used for the meta information.

Date Text The date to display

Styles Style Text The css style of the component. By default None is selected.

Dialog

Example Look
Used individually:

Used by the Quote component:

Code Location
/apps/telegraph/core/commons/components/metaProperty

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/metaProperty

846
Known issues / Limitations

Suggested improvements

847
Meta tags
Description
Meta tags are output in page head. They are placed there based the configuration of Meta Tags configuration pages that are in the tools are of
AEM. There is a site wide meta tags configuration page and channel specific meta tags configuration pages are used if any of the channels tags need to
be different and cannot be set to be dynamically from channel properties.

At time of writing (and very unfortunately) it is the case the every channel needs its own meta tag configuration page because a few of the meta
tags on the Portal are set statically and therefore cannot the site wide configuration page is not suitable to inherit down across the rest of the
site. This could actually be resolved very easily we fix the bug
AEM-5081 - Meta data items configurable for All Pages, Portal only & Exclude Portal CLOSED .

Then the entire site could be served by one meta tags configuration page. At present it need as many as we have channels which is in the
order of 115. Each with about 45 items of meta data which are almost all the same (refer Core Meta Tags spreadsheet). This is UNMANAGEA
BLE if yu consider trying to change one item might mean a person needing to open 115 pages and change the meta tags there.

Core Meta Tags spreadsheet


This Core Meta Tags spreadsheet holds the canonical configuration for the Meta Property Components on the Meta Tags page. See above note of how
the current MANY pages might be reduced to a single page for the whole site.

Configuration
Meta tags configuration is under Tools admin. The default configuration is under: /etc/telegraph/core/metatags. In order to create configuration specific to
one particular channel, folder named the same as channel root has to be created under /etc/telegraph/core/. For example for cars channel, cars specific
configuration is stored under /etc/telegraph/core/cars, so metatags config page is the following: /etc/telegraph/core/cars/metatags. Metatags page should
be created with "Meta Data" template.

Metatags configuration page contains one parsys, which allows only "Meta Data" components to be added to it.

Meta Data component configuration


Single metadata component corresponds to one meta element available in header of a page. Available properties:

Name Required? Description

Tag type One of:

Name: tag that uses name attribute for name.


Link: e.g. canonical link.
Akamai: tag will be wrapped in Akamai Edgesuite tag.
OpenGraph: metatag using property attribute instead of name.

Meta tag name The name of meta tag, goes to <meta name="NAME" ...

Content type Type of data to be propagated into content or link href. See Content Types table for details. One of:

Full parent page path


Parent page name
Collapsed article name (without any separators)
Page title
Level three page name (Genre)
Level two page name (Category)
Level one page name (Channel)
Channel and category separated with dash (-)
Channel and category separated with dot (.)
Literal describing page type (story, index, video, gallery)
Page Level
Name of the author
First publication date
Article Path (Article ID)
First tag name
Description
Image path
Page url
Page tags

848
Entity property
Homepage property
Twitter handle
Static value
Business segment
Facebook Title
Facebook Description

Static value If 'Static value' was selected, specify it in this property. It is ignored otherwise

Where to display One of:


metatag?
All pages
Homepage only
Exclude homepage

Omit if blank? Check if tag without content should be committed altogether

Homepage property The name of a property configured on homepage. Value of configured property is returned.
name

Tags namespace When empty, all page tags are displayed, otherwise only tags from configured namespace.

Entity Definition Valid when Entity property is configured in Content type. The entity definition used to retrieve list of
properties from.

Property Required when Entity property is configured in Content type. Value of selected property is used as meta
content.

Content types
Content Type Description

Full parent page path Returns url of the parent page without content root, eg: given /content/telegraph/cars/ford/reviews/ford-focus-review
expect /cars/ford/reviews

Parent page name The name of parent page

Collapsed article name Name of current page without any separators, eg: for /content/telegraph/cars/citroen/citroen-c1 result is citroenc1
(without any separators)

Page title Title of current page

Level three page name Page name of third page in current page path without starting /content/telegraph, eg: for /content/telegraph/cars/citroen
(Genre) /citroen-c1 returned value is citroen-c1

Level two page name Page name of second page in current page path without starting /content/telegraph, eg: for /content/telegraph/cars
(Category) /citroen/citroen-c1 returned value is citroen

Level one page name Page name of first page in current page path without starting /content/telegraph, eg: for /content/telegraph/cars/citroen
(Channel) /citroen-c1 returned value is cars

Channel and category Concatenation of channel (see above) and category (see above) properties using dash, eq for /content/telegraph/cars
separated with dash (-) /citroen/citroen-c1 returned value is cars-citroen

Channel and category Concatenation of channel (see above) and category (see above) properties using dash, eq for /content/telegraph/cars
separated with dot (.) /citroen/citroen-c1 returned value is cars.citroen

Literal describing page type Returns "index" for aggregate pages, "video" for article with video component on the page, "gallery" for gallery and
(story, index, video, gallery) gallery item pages and "story" otherwise. Please see AEM-21 for details of template categories

Page Level Returns current page level calculated without starting /content/telegraph, eg for /content/telegraph/cars/citroen/citroen-c1
returned value is 3

Name of the author Concatenation of firstname, space and lastname of author assigned to current page

First publication date First publication date of current page

Article Path (Article ID) Path of current page without starting /content/telegraph eg, for /content/telegraph/cars/citroen/citroen-c1 returned value
is /cars/citroen/citroen-c1

First tag name Name of the first tag assigned to current page

Description Returns standfirst text for reviews and articles, summary property for topic page and short biography for author pages

849
Image path Returns external path of small rendition of lead asset for review and article pages or author image for author page. When
not set, defaults to small rendition of logo image.

Page url Returns page url

Page tags Returns names of tags assigned to current page separated by comma

Entity property Returns entity property defined in Entity Definition and Property configuration option

Homepage property Returns property value of homepage. For /content/telegraph/cars/citroen/citroen-c1 homepage is /content/telegraph
/cars. Property name to be displayed is configured in Homepage property name configuration option

Twitter handle Returns twitter handle of author assigned to current page or empty string if author has got no twitter handle configured

Static value Returns value configured in Static value configuration field.

Business segment Returns the title of the Business Segment configured via page properties for the current channel/page. Please see Busine
ss Segment for more details.

Facebook Title Returns the value of the Facebook Title field in page properties or if this is empty then the title of the page

Facebook Description Returns the value of the Facebook Description field in page properties or if this is empty then the text from the Standfirst
component on the page This is a problem because the articles and galleries no longer use the Standfirst

Campaign ID Pulls in the campaign ID from the page properties. Used for pages that are running a Spark campaign.

Sponsored Enables Spark to flag the page as sponsored. If the page is sponsored (has a campaign ID then = TRUE not rendered as
a full tag

850
Most Viewed List (old)
Description
The most viewed list AEM component is actually just an extension of the Curated List component that is automatically populated with tiles, as opposed to
being manually curated.

The following documentation describes all the collaborating components that make up the most viewed list solution:

1. Data Access - how the analytics data is accessed


2. Refresh Scheduler and creating the Most viewed lists
3. Most Viewed list component used within CQ UI

1. Data access - how the analytics data is accessed


Most viewed data is retrieved from the [RETIRED] Most Viewed List API Service Description via an AEM service:

uk.co.telegraph.core.foundation.mvl.MvlConfigurationService

See the following configurations for pre-prod and prod configurations:

PRE PROD: core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author/uk.co.telegraph.core.


foundation.mvl.MvlConfigurationService.xml
PRODUCTION: core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author.prod/uk.co.telegraph.
core.foundation.mvl.MvlConfigurationService.xml

2. Refresh Scheduler and creating the Most viewed lists


The following classes are the main AEM components and services that make up the MVL solution, their collaboration is discussed later:

uk.co.telegraph.core.foundation.analytics.dynamic.list.RefreshScheduler
uk.co.telegraph.core.foundation.analytics.dynamic.list.RefreshConfiguration
uk.co.telegraph.core.foundation.analytics.dynamic.list.RefreshJob
uk.co.telegraph.core.foundation.analytics.dynamic.list.RefreshScheduler

uk.co.telegraph.core.foundation.mvl.MvlDataHandler
uk.co.telegraph.core.foundation.mvl.MvlConfigurationService

The following flow details the basic mechanism behind the most viewed list solution:

An instance of the RefreshScheduler is created and activated on the CMS instance


Currently 3 RefreshConfigurations are then loaded - daily, weekly and monthly (at the time of writing, the only the daily configuration is enabled).

core-root/cq/core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author/uk.co.telegraph.core.
foundation.analytics.dynamic.list.RefreshConfiguration-daily.xml
core-root/cq/core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author/uk.co.telegraph.core.
foundation.analytics.dynamic.list.RefreshConfiguration-weekly.xml
core-root/cq/core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author/uk.co.telegraph.core.
foundation.analytics.dynamic.list.RefreshConfiguration-monthly.xml

When new channels are launched or new sections need to have most viewed lists, just add the channel to the enabled.channels section of
each of the configurations above.

If a new content type needs to be supported - such as "gallery" then this would be added into the page.types section of each of the above
configurations - note: this would have to go through the development process and be QA'ed before releasing.

851
For each config, if the config is enabled, a sling scheduled job - an instance of RefreshJob - is created and scheduled according to the scheduler
expression specified in the config - for example the daily job is (currently) scheduled to be run every 1/2 hr. The job contains both a list of
channels and a list of AEM content types (currently just "story") that need to be created.
When a RefreshJob executes, it iterates through all channels and types creating an instance of uk.co.telegraph.core.foundation.analytics.
dynamic.list.EndpointJob for each channel/type combination. These jobs are then queued for execution by the configured sling ThreadPool - "T
MG-ADFS-ThreadPool"

TMG-ADFS-ThreadPool is used to constrain the impact that the Most Viewed list refreshing has on the CMS. See the configuration file for the
min and max pool size:

core-config/src/main/cq/jcr_root/apps/telegraph/configuration/config.author/org.apache.sling.commons.threads.impl.DefaultThreadPool.factory-
TMGADFS.config

Note: this constraint (limiting the number of parallel jobs that can be run) is important. As the process runs on the CMS the impact of
the scheduled jobs needs to be minimised to avoid impacting editorial workflows.

The EndpointJob uses the uk.co.telegraph.core.foundation.mvl.MvlDataHandler to do the following:

852
3. Most Viewed List component used within CQ UI
Once the above schedule has been run for a particular channel, the MostViewedList component can then be used within the content of that channel:

853
If the scheduler has not run for the channel, then the most viewed list will show the following warning when used in a page:

854
855
Outbrain
Description
The Outbrain component is used as a place holder which is populated by Outbrain. See CCORE-713.

How to use it
The component is available in the sidekick in Telegraph - Component group. To use you need to drag and drop inside the parsys, then you have panel to
configuration and available attributes inside.

Available styles: NA
Style name Description

- -

Configuration
Name Required? Type Description

Type Yes select Sets the data-widget-id attribute on the Outbrain component,
box
Key to widget IDs:
AR_3 = sidebar (4 thumbnail image version)
AR_16 = below article (4 internal & 4 external thumbnail image version)
MB_1 = mobile (2 internal & 4 external image version)

see Outbrain documentation for more information

Template Yes free text Template used by Outbrain

Test No free text In order to test the Outbrain component, the author may need to add a valid URL (e.g. a link to a page which contains outbrain
URL script... http://telegraph.co.uk/news) in order to get the widget to display in preview. This value MUST be EMPTY when the page is
published though. This value is only used for testing purposes.

Dialog
To get dialog click "Edit".

856
Example look in Author

Code location
/apps/telegraph/core/commons/components/outbrain

Known issues
The outbrain javascript causes the CQ Author to fail, for this reason it is disabled in the Author instances and the outbrain widget will only display content
on Publish version.

Suggested improvements
Version 1.0

857
Page ID
Implemented by AEM-621 - Add Page ID to page properties RELEASED

Background
Ad Ops & Spark require an immutable Page ID so that they can target or suppress advertising for pages.
Analytics require a Page ID so they can ensure that pages are not lost to their reports if they change their names or location.
Picture Desk require a Page ID for reconciling payments of images used on pages. They will add the Page ID into the Description field in their
payment system, EIS, which goes out to the payment advice documentation to image providers.

Scope
All pages must be assigned a their own unique Page ID at time of creation (including gallery slides - see later note about meta tag for gallery
slides).
Apply the Page ID to all AEM nodes where jcr.primaryType = cq:Page
Page ID should be viewable in the page properties but read only.
Page ID should be assigned no matter what mechanism created the page - Authoring, AEM or automatic
When a page is activated it must have the same Page ID on the author, publish & dispatcher instances
The Page ID will be exposed in the source in the metatags:
tmgads.articleid for Ad Ops (e.g.: <meta name="tmgads.articleid" content="Aj70Ygj2blb3")
DSCext.articleId for Analytics (e.g.: <meta name="DCSext.articleId" content="Aj70Ygj2blb3">)
Picture Deck can use either of these as their content will be identical
The Page ID exposed in the meta tags on all of the slides of a gallery should match the Page ID of the gallery (i.e.: not the Page ID of the slides)
The Page ID must be immutable:
Authors cannot edit or delete (it is accepted that an administrator will be able to do this and that they should know not to)
Page ID is not changed when the page is moved or renamed
If a page is copied, this is to be treated as a new page, and a new Page ID will be generated
The Simpleflake method will generate an 11 character id (e.g.: j70Ygj2blb3) which will be prepended an "A" is signify that the page is on AEM
rather than eScenic and avoid dupes between the 2 platforms.
A Simpleflake API has been created by Architecture which is available for use however it is thought that java library using the same
algorithm based solution may be a better approach as it will be a technically simpler solution and more performant. This will be confirm
during development.
All existing pages will also receive a Page ID (see AEM-3245) so that once this is implemented all AEM pages will have a Page ID
This ticket should add a new Content Type of "Page ID" to the Meta Tag Tool (see Meta tags page).

Removal of 'A' from Page ID


After the Page ID was released to Production is was brought to light that the the 'A' prefix was not required and not desired from an data cleanliness
perspective. The ideal Page ID should only consist of the Simpleflake ID. In light of this AEM-4372 - Remove 'A' from Page ID CLOSED was
created and worked upon to remove the 'A'. This included writing the scripts to remove the 'A' from existing pages. This ticket, however was not released
as it was decide it would be too disruptive and risky to orchestrate in that it would need to be chased through to the Content API and the Travel team to
ensure that nothing is broken there.

Should the 'A' prefix ever need to be removed in the future the developers can look at the work done by referring to the code here - https://stash.aws.
telegraph.co.uk/projects/CHEET/repos/telegraph-component/commits?until=refs/heads/bugfix/AEM-4372-remove-a-from-page-id.

Please note this code was not fully complete and has not be code reviewed or QA'ed

858
Properties Entity
Displays list of entities linked to the review page on which it is placed. Every item is a link to their respective section of a review.

Example

Configuration
There are no configuration options for this component. Entity information are configured on review page properties.

Code location
/apps/telegraph/core/commons/components/entityProperty

859
Quote Component
Description
Quote component can be added to a page in order to display a quote from a given source or by a certain author.

How to use it
Create a page first. Then you need to drag and drop inside the parsys from the Telegraph-Component group sidekick and then double click to open:

Double click the component and a dialog opens with two tabs. Tab Configuration is for inserting the quote information and meta information about the
quote. The Quote Information section consists of the text for the actual quote and the author or the source of the quote can be set here. On the second
tab Styles the style of the quote can be selected. It defaults to None. In the Meta Information section the date of the quote and the label/category can be
set.

Configuration
Name Required Type Description

860
Quote Text The actual quote

Author Text The author of the quote

Author Link Path field Link to the author of the quote; can be internal or external links

Source Text The source of the quote

Source Link Path field Link to the source of the quote; can be internal or external links

Label / Category Text Represents the category the quote refers to. Gets displayed right before the quote

Date Date Represents the date of the quote. Gets displayed right before the quote and after the category

Dialog

861
Example look

862
Code location
/apps/telegraph/core/commons/components/quote/

Known issues
N/a

Suggested improvements
Version 1.0

863
Rating
Rating configuration for Film
If you unable to view the screencast you can download it - rating-5-stars.mov

Your browser does not support the HTML5 video element

864
Related Entities
Shows list of reviews that are similar to the one currently being viewed. Relation can be based on tags or similar values of entity properties.

By default component searches for other car reviews that share at least one tag. A configurable number of reviews will be displayed with pictures.
Reminder up to configured to be displayed as List of Links.

Component can also be set up to search for related entities using the Search rules and specifying to entity properties that should be compared by search.

Example

Related entities with similar entity value

865
866
Related reviews with the same tags

Configuration: sample queries


Please note that only cars that have the entity data fields filled in are taken into account when searching. For example, if searching by 'Seats' property,
results will only include cars whose entity data contains a valid numeric value in the 'Seats' entity property field.

Sample query 1
Simple related entity search to search related entities with one specified property, to find cars where fuel economy value is smaller than the current model's
fuel economy.

Sample query 2
CarSeats=FeaturedCarSeats&
Listprice<1.2*FeaturedListPrice&
Listprice>0.8*FeaturedListPrice

867
Sample query 3
CarSeats=FeaturedCarSeats&
Listprice<1.2*FeaturedListPrice&
Listprice>0.8*FeaturedListPrice&
CarBootSpace<1.2*FeaturedBootSpace&
CarBootSpace>0.8*FeaturedBootSpace

Sample query 4
CarSeats=FeaturedCarSeats&
Listprice<1.2*FeaturedListPrice&
Listprice>0.8*FeaturedListPrice&
CarLength<1.2*FeaturedCarLength&
CarLength>0.8*FeaturedCarLength

868
Sample query 5
CarSeats=FeaturedCarSeats&
Listprice<1.1*FeaturedListPrice&
Listprice>0.9*FeaturedListPrice&
CarLength<1.2*FeaturedCarLength&
CarLength>0.8*FeaturedCarLength

869
Configuration Required Functionality

Title For rule-based list only. Text displayed before the list of reviews. In the second example "Cars with better fuel
economy"

Links title For rule-based list only. Text displayed after reviews with images and before small links. In the second
example "More fuel efficient cars"

Max number of items Indicates what is the maximum number of reviews that can be shown in the component including the ones with
displayed photo and the ones with links

Max number of items Indicates number of reviews shown including the lead image.
displayed with image

Search rules

870
Allows to define a number of rules based on numerical entity values to search for related reviews. If not
configured component will find reviews that share at least one tag as the one currently viewed.

Search rules fields

Property Name of entity that you want to search for

Operator Comparison operation to perform on other articles' entity value. Possible options are:

Less Than - Finds reviews which have greater or equal entity property value than that in the currently
viewed review
Equal - Finds reviews which have the same value of entity property
Not Equal - Finds reviews which have different value of entity property
Greater Than - Finds reviews which have lower or equal entity property value than that in the currently
viewed review

Divisor Modifies value of related review in order to match reviews that don't have exact same value.

Example: Currently viewed page has fuel economy set to 10. Find reviews that have greater 'Fuel Economy'
than 8 of current one.
Result will search for all cars that have 'Fuel Efficiency greater or equal to 8.

Property: 'Fuel Economy'


Operator: Less Than
Divisor: 1.25 (because 10/1.25 = 8)

Known Issues
Less than (<) and Greater than (>) operators are swapped.
List shows one more element than configured, but shows 1 element when set to show 1 element.
Only numerical properties can be compared. Text, Currency and Boolean are currently not comparable
Links without images don't have .html extension on author. When clicked error page is shown (HTTP 403)
"Coefficient" should be called "divisor" as entity value from current review is being divided by the value of 'Coefficient'

871
Improvement ideas
Fix entity data
Some entities store numeric data in text fields. Issue needs to be investigated in detail to understand extent of if in production.

CCORE-1037 - Fix entity data types DONE

Fix known issues in component


< & > to work logically
Replace coefficient term with better one and provide examples
Other issues noted in parent page

This should be timeboxed to 2 days

CCORE-1038 - Fix known issues with Related Entities component [Timebox 2 days] DONE

Provide examples using current UI for queries requested in CCORE-663


So that feature can be used ASAP.

Possible improvements noted in brainstorming session


1. Create UI where range is defined in drop down, e.g. "+/- 10%"
2. Index entities in Solr and provide information how to retrieve related entities as sample queries
3. Use Nitro API advanced queries to retrieve related entities
4. Extend entity definition pages to define where what is "related entity", e.g. car could be related to other car that has similar price and 2 or more
same tags
5. Use Webtrends or Adobe Analytics data to retrieve pages that other users have viewed after viewing this page

872
Renderer Config Component
Description
The Renderer Config component is used in Design Mode to override Entity Rating type maximum value.

How To Use It
To use it simply go to design mode and into the page renders's configuration by clinking Edit.

Configuration
Tab Name Required? Type Description

Configurati Override Best Number This setting will override the default Best Rating (10) value used for Entity Properties of a Rating type. If not
on Rating set, the value is 10.

Dialog

873
Example Look
After the best rating max value is changed, the consequences can be seen on an firm entity page for instance, where the rating display changes
accordingly.

Default value of 10:

Changed best rating max value to 5:

874
Code Location
/apps/telegraph/core/commons/components/rendererConfig

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/rendererConfig

875
Review List of Links
Review List of Links is a component that has the super type List of Links. Basically it is a List of Links component that is by default included in the Review
template.

It can not be dragged and dropped from the sidekick like the List of Links component since it has the group component .hidden.

Example

Configuration
The configuration is the same as for List of Links component.

See in the images bellow the configuration for the example above:

876
Code location
/apps/telegraph/core/commons/components/reviewListOfLinks

-- referenced in:

/apps/telegraph/core/commons/renderers/reviewRenderer/bodyContent.html

Known issues

Suggested improvements

877
Snippet and Snippet Reference
Nickname Snippet & Snippet Reference
(s)

Description A Snippet is a piece of reusable content built on its own page but delivered to other pages. The snippet page itself is not meant to be
public facing.

A Snippet Reference is the component used to deliver the snippet to a page.

Create a snippet

In AEM go to any "application" folder in the content structure and if one does not already exist create a page called "snippets"
beneath it using the Blank template (the name "snippets" is important).
Create a new page under "snippets" using the "Snippet" template (this will be you snippet page)
Open the snippet page and add the components and content required.
Activate the snippets folder (if this has not already been done) and activate the snippet page itself.
In AEM go to the page that you want the snippet to appear on and open it.
Add a Snippet Reference component to the page in the location that you want it to appear
Edit the Snippet Reference config to point to the snippet page you created above
Click OK to save the config
Activate the page

Editing a snippet

Snippets use server side includes (SSI) so therefore to update a snippet you only need to edit and activate the snippet page itself.
Any page that it already appears on will be update automatically without having to go to that page and activate it separately.

Portal

Snippets are used heavily on the Portal page. This allows multiple editors who want to update their various part that appear on the
Portal to update their snippets, activate them and not have to worry about overwriting someone else who is updating anotehr part of
the page at the same time (because they are each working on different snippets).

Interactions

Restrictions Snippets can be in any "application" folder in the content structure

Screenshot
Item Image
(s)

Snippet pages
and location

Snippet
Reference
component
config

878
Location

JIRA AEM-3165 - Enable reusing content on multiple pages (snippets for Opta Widgets) RELEASED

AEM-4479 - Enable the Snippet Reference to be used in Onward Journeys RELEASED

879
Social Component
Description
The Social component provides social networking share support: Facebook, Twitter, LinkedIn, Email and also Print functionality of the current page.

How To Use It
The Social component is available on the sidekick, under General tab. it can be dropped on the required area.

Configuration
Tab Name Required? Type Description

Plugin Position of social counter Text Values: either top, right or now. Gives the position where the social counter will be displayed,
Configuration (lowercase) relative to each social share icon.

Layout Dropdo Either Vertical or Horizontal. Gives the display layout of the social component.
wn

Remove Button Borders Text Values: either true or false, default value is true. If true, it removes the borders of the social
share buttons.

Gigya Providers Panel Optional information about different Gigya social share providers to use.

Gigya Providers: Provider Dropdo Either Facebook, Twitter, LinkedIn, Print or Email.
wn

Gigya Providers: Tooltip Text The Gigya social share provider button tooltip.

Gigya Providers: Icon Only Text Values: either true or false. If true, only the icon will be displayed for the Gigyia provider.

Styles Style Dropdo Default: none. The style of the social component.
wn

Dialog

880
881
Example Look

Code Location
/apps/telegraph/core/commons/components/social

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/social

Known issues / Limitations

Suggested improvements

882
Stand First Component
Description
Stand first component is used to display in an article page the introductory/summary paragraph right bellow the headline.

How to use it
To start create an article page. When you open the page the component should be already there and it should look like this:.

Now double click to open the configuration dialog. By default you are presented with an empty text input on the Configuration tab.

Configuration
Name Required? Type Description

Standfirst Text Text The actual stand first text

Dialog

Example look

883
Code location
/apps/telegraph/core/commons/components/standfirst

Known issues
N/a

Suggested improvements
Version 1.0

884
Sticky Ad
DEPRECATED

This code has been deprecated with the implementation of Advert Management (and the Sticky MPU on Article (SMoA), Sticky Banner on
Mobile (SBoM) & Sticky MPU on Gallery (SMoG)).

See also Advert Management background and usage.

Description
The Sticky plugin runs on the right hand column, it fixes components within the view port using bootstrap affix. Currently supported by Ad Block-C on
Article 2 template.

There can only be one sticky ad (per container), the sticky ad will stay within it's bonding box (container) .

How to use it
Settings
Sticky ad Block-C can be turned on per single Article 2 page, or per whole content branch under Hub page. (NB: you'll need to republish the page).
Whenever stickiness on Article 2 page level is set to Inherit, the Article page inherits configuration from parent Hub page. If Article 2 has got "Show" config
option chosen, Sticky ad is turned on regardless of hub configuration, and in case of "Hide" config option selected, sticky ad is turned off regardless of hub
configuration.

Code location
cq/core-design/src/main/cq/jcr_root/etc/designs/telegraph/core/clientlibs/tmgchannels/_base/js/plugins/tmg.sticky.js

ui-test/spec/spec.plugin.tmg-sticky.fashion.js

Interface developer: how to use / extend


The sticky element will try to stay within a container, it will also check it has content and if not it will not activate, so when we initiate it we'll tell it what
parent and what content to expect.

Options

885
var options = {
activeClass: "is-tmg-sticky", // class name added if behaviour is active
containerSelector : ".tmg-sticky-ad-container-enabled", // selector for the container of the
sticky element
childSelector: ".component-content > *", // for Ad Block-C we enable sticky if ads are served
offsetY: { // affix offsets
top: 10, // must match CSS top property
bottom: 50
}
};
$(options.containerSelector).find('.tmg-sticky:last').each(function(){
$(this).tmgSticky(options);
});

See jsfiddle for vanilla implementation.

Things to remember.

Sticky behaviour is disabled at small screen sizes. This is done in the CSS see cq/jcr_root/etc/designs/telegraph/core/clientlibs/tmgchannels
/_base/sass/plugins/tmg.sticky.scss
Sticky behaviour for Ab Block-C is added on page load after everything else has loaded and run.
The behaviour uses bootstrap affix
The plugin is called "tmgSticky" on the front end, but "tmgStickyFashion" in the Jasmine tests (this is to differentiate it from the existing "tmgSticky"
box used in Cars)

Known issues
Flickering on IE and FF, see AEM-1413 this doesn't happen on the jsfiddle example so assume something in the tmg CSS is causing this. To
reproduce open tmg.sticky.js and comment out the IE FF hack and follow the instructions on AEM-1418
Currently doesn't support Tablet
One of the Jasmine tests fails on phantomjs when running mvn test -P execute-jasmine (but works in a browser when run mvn
initialize jasmine:bdd -P execute-jasmine) currently it's commented out in the code. Needs a little investigation see AEM-1413.

Suggested improvements
Add support for Tablet browsers AEM-1413
Fix failing test, see commented out test in Jasmine spec (test works when run in a browser but not when run in phantomjs)
Consider removing bootstrap, what else do we use it for?

Version 1.0

886
Sticky box
NO LONGER IN USE

This was developed specifically for the original Cars channel which
itself ha now been replaced. The Sticky Box was never supported on
other channels and is no longer used in the new Cars.

Description
The Sticky box plugin runs on the right hand column, it fixes components within the view port using bootstrap affix. Currently supported by Ads and the Box
component.

There can be any number of sticky boxes, they will stack vertically, the final sticky element will auto scroll back to it's original position after a specific time
(an inherited page parameter). The current use case is to have an optional 'call to action' and an Ad, in this case the call to action would be persistent and
the Ad will slide out of view back to it's original position after 10 seconds.

How to use it
Box component
See the Box component page for information about making a Box sticky

Advert config
See the Adverts page for information administering the advert config

Settings
To set the scroll delay (10 seconds by default, set to 0 to disable the scroll behaviour).

Select "Page Properties" from the sidekick, then click on the "Adverts & Sticky box" tab.

Set the 'Sticky box delay' for the current page and any decedents to the desired value, click OK to save.

Code location
cq/core-design/src/main/cq/jcr_root/etc/designs/telegraph/core/clientlibs/tmgthemes/cars/js/plugins/tmg.sticky.js

Known issues
The 'bottom' parameter is not supported due to issues with FireFox flicker, so don't get pushed up
Sticky box, requires the full bootstrap.js (version >= v3.2.0) to be included, the Affix.js on it's own will case the sticky behaviour to fail. (when
scrolling up, the position fixed elements don't get position static applied at the correct offset, so jump)
Nested sticky items will be ignored, only the outer most sticky element will have the sticky behaviour (though this is not an issue, more a 'feature'!)

887
Suggested improvements
Remove reliance on bootstrap affix to fix points 1 and 2 above, and to reduce the overall javascript file size

Version 1.0

888
Summary Component
Description
Summary component is used to display in an topic page the summary of the page right bellow the headline of the page.

How to use it
To start create a topic page. When you open the page the component should be already there and it should look like this:.

Now double click to open the configuration dialog. By default you are presented with an empty text input on the Configuration tab.

Configuration
Name Required? Type Description

Summary Text The actual summary text

Dialog

Example look

Code location

889
/apps/telegraph/core/commons/components/summary

Known issues
N/a

Suggested improvements
Version 1.0

890
Text
Description
Text component displays a highlighted paragraph of text

Original requirements (possibly out of date by now)

How to use it
The component is available in the sidekick in Telegraph - Component group. To use you need to drag and drop inside the parsys, then you have panel to
configuration and available parsys inside.

Available styles:
Style name Description

text-ver_1 Yellow background and 'quote' image

Configuration
Configuration Tab
Name Required? Type Description

Text Text Editor Text to be displayed on the page

Heading and footer


Settings in this tab have no effect on this component

Styles tab
Name Required? Type Description

Style select box Css style set for all components inside box

Dialog

891
Example look

Code location
/apps/telegraph/core/commons/components/text

Known issues

Suggested improvements
Version 1.0

892
Body Copy Component Requirement Overview
Target Sprint Release

Version 0.1

Theme Body Copy Component

Document status Draft

User Story Creator Lindsay Flitton

User Story Owner Ed Keohane

Developers Lead Developer

QA Lead Tester

Template Mind Map

Overview

Component Name
Body Copy (text) component

Component Description
Allows text to be added and edited in the main body of an article component

Users and Workflow

Users
Describe users of the Component and how they will utilise it.

User Name User Description Key User Needs Internal or External

893
Editor e.g. a Section Editor is responsible for the management of a section page and all related content. Internal

Workflows and User Stories


Outline the key user stories that support the users' workflows. Please also consider triggering or triggered workflows, security aspects, customers as well
as internal user needs. Please link each user story to their JIRA entry.

ID User Story Name Comments JIRA Issue Link Priority Component


Version

CHE Editor Add Body Copy Text to Mechanism to enable an editor to add text to the main Mandatory V0.1
ET_ Article body of a new article by either manually typing, dragging
238 and dropping or copying and pasting the text from
Error
As an editor I want to add existing content
body copy text to a new renderin
article so that the article can
be viewed by users g

macro

'jira'

Unable

to locate

Jira

server

for this

macro.

It may

be due

to

Applicati

on Link

configura

tion.

CHE Editor Add Body Copy Text to Mechanism to enable an editor to amend the text in the Mandatory V0.1
ET_ Article main body of an existing article by either manually
239 typing, dragging and dropping or copying and pasting
As an editor I want to edit the text from existing content. This also covers the deletion
body copy text in an existing of existing text from the main body within the article.
article so that I can present Unable
the most up to date
information to locate

Jira

server

for this

macro.

It may

be due

to

Applicati

on Link

configura

tion.

CHE User Capability to ensure that the body copy text within an Mandatory V0.1

894
ET_ Display body copy text at article is displayed across all appropriate devices to the
243 appropriate size to my correct specifications to ensure quality at all times for the
device customer

As a user I want to see


article body copy text at an Unable
appropriate size for my device
to locate
So that I can use a variety of
devices to easily read the
Jira
article
server

for this

macro.

It may

be due

to

Applicati

on Link

configura

tion.

CHE Reader Sub-headings in body copy Mandatory V0.1


ET_
422 As a reader
I want the body copy to be
marked up with H3/H4 etc
So that I can understand the Unable
structure of the article
to locate

Jira

server

for this

macro.

It may

be due

to

Applicati

on Link

configura

tion.

User Interface and Design


This section will describe the different ways a user can utilise the component and the styles and behaviours of the component - Include mock-ups,
diagrams, visual designs related to the Stories and Acceptance Criteria.

Styles

Behaviours

Iconography and visual assets

895
1. Body Copy text content within an article (Author ID component showing above the start of the body copy text)

Data and Integration


Include details of data features, fields, objects that are required within the Component

Data Objects or Properties Description

e.g. Time Stamp e.g. date and time when the article was published

Integrations required
Please outline any integration required for the component.

e.g. This component consumes the XYZ REST API to collect sharing and comment counts for each article in the list. More details on the API or
integration (link here).

Configuration

Dependencies
List of components that the Component being delivered within the User Story has.

Component Name Component Description Dependency e.g. used by or used for

Options
Please list the key configuration options that are available when this component is being used.

Option Name Option Description Default?

896
e.g. Preview There are two options available: portrait and landscape Landscape
orientation

e.g. Stylesheet The default stylesheet used by the component can be overwritten and the user can specify which one Uses inherited styles
to use instead

e.g. Show Image? Allow the option to use a thumbnail image for the article Yes (if an image is
available)

Non-Functional Requirements
Please consider the key NFRs for this components and ensure they are included, where relevant, in the acceptance criteria of the user stories.

ID Non Functional Requirement Area Priority

# Description of requirement Reliability, Performance, Accessibility, Security, etc Priority of requirement

Other

Out of Scope
List the features discussed which are not being delivered within this User Story and are therefore out of scope or may be delivered later or via another
User Story

Questions
Below is a list of questions to be addressed as a result of this User story:

Question Outcome Owner

Assumptions
Describe the assumptions associated with the Component e.g. technical or business assumption

897
Tweet Component
Description
The Tweet component provides embedded tweet functionality using only the tweet url.

How To Use It
The Tweet component is available in the sidekick under Telegraph - Components: Embed Tweet.

Configuration
Tab Name Required? Type Description

Configuration Tweet url Text The url of the tweet to embed. For instance:

https://twitter.com/TelegraphTravel/status/553147626745364482

Hide Media Radio button If the tweet's media (image, video) be hidden or not. False by default.

Styles Style Dropdown The css style of the Tweet component. By default None is selected.

898
Dialog

Example Look

899
Code Location
/apps/telegraph/core/commons/components/tweet

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/tweet

Known issues / Limitations

Suggested improvements

900
Tweet Timeline Component
Description
The Tweet Timeline component provides embedded tweet functionality using the tweet's embed code.

How To Use It
The Tweet Timeline component is available in the sidekick under Telegraph - Components: Embed Tweet Timeline.

Configuration
Tab Name Required? Type Description

Config Tweet Text The embed code of the tweet to embed. For instance:
uration embed
<blockquote class="twitter-tweet" lang="en"><p>The world&#39;s most
inspirational rivers for writers <a href="http://t.co/XnXXeBPz9m">http://t.co
/XnXXeBPz9m</a>

901
<a href="http://t.co/pmtn4CbVj0">pic.twitter.com/pmtn4CbVj0</a></p>&mdash;
Telegraph Travel (@TelegraphTravel)
<a href="https://twitter.com/TelegraphTravel/status/553147626745364482"
>January 8, 2015</a></blockquote>

Styles Style Dropdo The css style of the Tweet Timeline component. By default None is selected.
wn

Dialog

902
Example Look

903
Code Location
/apps/telegraph/core/commons/components/tweetTimeline

/cq/core-app/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/tweetTimeline

Known issues / Limitations

Suggested improvements

904
Twitter Configuration
Description
Twitter configuration page allows extra channel specific configurations for automatic tweeting.

Configuration
Twitter configuration is under Tools admin. In order to create configuration specific to one particular channel, folder named the same as channel root has to
be created under /etc/telegraph/core/. For example for cars channel, cars specific configuration is stored under /etc/telegraph/core/cars, so twitter config
page is the following: /etc/telegraph/core/cars/twitter-config. Twitter config page should be created with "Twitter Config" template.

Important: Twitter configuration page name must be "twitter-config" in order for the configuration to be found.

Twitter configuration page contains a configuration component that allows the editing of configurable values, currently only whether auto tweeting is on or
off for the current channel.

905
Video Player
Description
The Video Player component is used to play Ooyala videos on page. Videos can be configured by drag&dropping them onto component or by providing
video id by hand.

How to use it
The component is available in the sidekick in Telegraph - Component group. To use you need to drag and drop inside the parsys.

After dropping it onto parsys, video to be played can be configured in two ways:

by configuring it in component's dialog


by drag and dropping it from Ooyala content finder

906
Configuration
Name Required? Type Description

Video Path textfield Ooyala video id

Video Title override textfield If provided, will override title of the video provided by Ooyala service

Auto play checkb Video will autoplay on page when checked


ox

Auto scale checkb Video will autoscale when checked


ox

Video type Normal / Sensitive / Exclusive

Exclusive Expiration Relevant only when video type is set to Exclusive


Date

Sensitive checkb When checked, video is considered sensitive and ads won't be played (not implemented yet)
ox

Share checkb Shows social media share option


ox

907
Embed checkb Allows users to embed
ox

Captions checkb Provides captions


ox

Fullscreen checkb Allows user to make the video fullscreen


ox

Video Lead Image image When provided, overrides video image provided by Ooyala displayed before video is played

Search Path textfield If provided, will override channel home page. Used for searching recently added videos on all pages under the given
path (for the end screen)

Number of results textfield Number of results shown on end screen (up to 8)

Hide end screen checkb Turns off end screen


ox

Style

Dialog

908
909
910
Example look

911
Code location
/core-app-commons/src/main/cq/jcr_root/apps/telegraph/core/commons/components/videoPlayer

Known issues
Suggested improvements

912
Component Tracking
Component tracking enable the Analytics team to report of usage of component instances of page when visitors navigate from page to page on the site.

When a visitor clicks on a component to navigate to another page various metadata elements are passed from the starting page to a cookie on the
destination page. Adobe Analytics then reads the contents of the cookie upon destination page load. Doing the tracking in this manner saves on
Adobe Analytics calls (i.e.: onload only rather than both onclick and onload) and therefore save a lots of money.

The data that is passed is sent in two ways:

An eVar containing all of the metadata in a single string


Separated out eVars each containing part of the metadata

Single String eVar


The tracking string is fed into eVar16

String Part Description

component-name Name of component that contains the link

'_' Secondary delimiter (present only if the component is configured with a heading

Heading-label The heading of the component that contains the link if one is present. Use the label text with hyphens used for character
replacement.

';' Primary delimiter

'Gallery:' If the link is in a List and to a Gallery then prepend 'Gallery:' (should advise SR1 to make Video links adhere to this standard too)

Link-label Link label text with hyphens used for character replacement

'_' secondary delimiter (if the link has no label then this is not required

'txt', 'img' or 'ico' 'txt': user cilcks on the text link in the component, 'img': user clicks on the image in a component, 'ico': user clicks on the icon in a
component.

';' Primary delimiter

content_path_of_ Public facing content path of the current page with underscore separators between pages in the path. Pages that have their URL
current_page rewritten should show the public facing path. For example see (A), (B) & (C) below

Example
Visitor was on page http://www.telegraph.co.uk/property/buy/amazing-grade-i-listed-homes-that-dont-need-to-break-the-bank/little-hall-is-a-four-bedroom-
house-in-tetbury-known-as-the-gate/ and used the header breadcrumb on to arrive on the Money page

Separate eVars
The tracking strings are fed into eVar94, 95, 96 & 97

Console variable eVar Name String formula

v94 eVar94 Navigation: Component Name component-name + _ + Heading-label

913
v95 eVar95 Navigation: Destination 'Gallery:' (if links to a gallery) + Link-label

v96 eVar96 Navigation: Link Type 'txt', 'img' or 'ico'

v97 eVar97 Navigation: Page of Use public_facing_content_path_of_current_page

Example
Same journey as the above example.

JIRA references:

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

AEM- Analytics - Component Apr 06, Jul 05, Andrzej Zeid Hadi RELEASED Unresolved
5213 tracking - Adding New 2016 2016 Dolinski [X] [X]
eVars

AEM- Component tracking for Jan 26, Jun 01, Andrzej Gavin Kirk RELEASED Unresolved
4155 Analytics - tranche 2 2016 2016 Dolinski [X] [X]

AEM- Component tracking for Oct 13, Mar 16, Unassigned Gavin Kirk CLOSED Done
2884 Analytics - tranche 1 2015 2016 [X]

3 issues

914
Content Refresh
Web Operations has setup a small server that has access to the Prod Slave Author. Each night this server runs a content export from the Production Slave
Author to a local CQ instance. This middle-man instance can then be accessed by servers from other environments and from local PCs.

Content Export Server details

Host cms1.aem-export.awspreprod.telegraph.co.uk:4502

User content

Password c0nt3nt

Content Refresh script


The content-refresh.sh script is included within the scripts/ directory of the telegraph-component repository. This script is installed into /opt
/aem/content-refresh.sh by Bamboo

Bamboo install to be completed after CCORE-889 - Create How-To Page - Content Export DONE is merged into develop. For the
moment it has been manually copied onto the DEMO Author.

Script Configuration
The script reads configuration from 2 separate files:

/etc/aem/content-refresh.conf
Intended to be setup on the servers once
~/.aem-content-refresh
Intended for local PC use (also useful for setting up per-user local overrides on server)

The script has a large set of configurable options, but most have sensible defaults.

Minimum config for local PC sync


This should be enough to get you going for a local CQ sync and you already have VLT installed in your system path

~/.aem-content-refresh

LOG_DIR=./
DESTINATION_AUTH_LOGIN=admin
DESTINATION_AUTH_PASSWORD=admin

SOURCE_AUTH_URL=cms1.aem-export.awspreprod.telegraph.co.uk

Typical config for a server sync

export JAVA_HOME=/usr/java/default
export VLT_OPTS="-Djava.io.tmpdir=/tmp"

VLT=/opt/aem/vault-cli-2.4.34/bin/vlt

DESTINATION_AUTH_LOGIN=admin

915
DESTINATION_PUB1_LOGIN=
DESTINATION_PUB1_URL=azaem-pub1-uat.awsdev.telegraph.co.uk
DESTINATION_PUB2_LOGIN=
DESTINATION_PUB2_URL=azaem-pub2-uat.awsdev.telegraph.co.uk

RCP_PATHS=(
"/etc/tags/cars"
"/content/telegraph/cars"
"/content/dam/cars"
"/content/dam/team"
)

Most frequently used configuration options

VLT path to the VLT script. VLT is available as part of your CQ installation in the crx-quickstart/opt
/filevault/ directory. Choose the TGZ or ZIP and extract it into a location, then set this variable to the full
path to the bin/vlt

LOG_DIR Path you want to log file to be written to

DESTINATION_AUTH_LOGIN All DESTINATION_*_LOGIN variables are used to determine if that server should be synced or not.

On most instances this will be admin

DESTINATION_AUTH_PASSWORD On most instances you are running this script, this value will be the CQ default admin

DESTINATION_AUTH_URL localhost normally (since you will run the script from the author server you want to update)

RCP_PATHS This is an array of CRX paths to sync, defaults are setup for cars.

DESTINATION_PUB1_* These variables are the same as the *AUTH* except used to sync directly to a publish instance (without the
need to activate content)

Notes
1. Content completely syncs each path from RCP_PATHS. This means that if you have existing content there that does not exist on the source
server, it will be deleted.
2. Content Export server only syncs from the Author in production - this means we cannot accurately activate what is currently on Prod Publishers if
a page on the author has been modified since publication (signified by blue icon)

916
917
Cookie Audit
This Cookie Audit spreadsheet lists the cookies that have been found on the site and is intended to show the owner and purpose of each one.

The following documentation is also available explaining cookies:

Opentag Cookie Widget Setup


Cookie changes for new meter
SAM Cookies

918
Core Concepts

919
Entities
An entity definition is a category that contains multiple objects (entities) sharing the same properties. An entity definition is created by clicking the new
button in CQ and selecting as a template Entity Definition. To add properties one can drag and drop the Entity Property Definition. In an entity definition the
properties wanted for the entities will be defined, they need to contain the name, title, type (text or currency) and optionally prefix, suffix and weather it
should show in the review page or not.

In order to create an entity for a certain entity definition one must select that entity definition, click the new button in CQ and select the Entity template.
After this in the page one has to complete all the previously defined properties.

Entities are used in the review pages in order to automatically show information and in components like List and List of links.

An entity definition has some extra page properties that allow showing some information in the components. In the Top List Of Links Configuration tab one
can set the heading and subheading that they would like to appear for the list of links component (from the review page template).

920
In the Top Rating Configuration tab one can set the information (maximum 3 properties) that will appear in a component from the review page under the
lead image.

921
In the List View Configuration one can set properties or just extra text that will appear on the List component for a list of reviews. The name, title or/and
value of the entity properties can be used.

922
Tags
A tag is a keyword or label that can be assigned to some of the components and pages. Multiple tags can be assigned to the same content element. This
allows them to be classified by several different categorizations at the same time.

A tag can be a simple word or a hierarchical taxonomy (eg. cars/Good for families, meaning both the generic car and more specific Good for families).
Tags are identifies by strings, either by an ID or an absolute path to the tag. A tag also contains meta information such as a title and sescription.

Managing tags
All tags can be found in CQ under the Tagging Option and a count of how often they are referenced in the websites.

Depending on the starting level you can create either a tag or a namespace using the New button. In both cases the title and name are mandatory and the
description is optional. Namespaces and tags can also be edited, deleted and activated/deactivated by right clicking on them, or by selecting the desired
one and then from the above menu selecting corresponding the option.

Assigning Tags
Tags can be assigned to pages, or to one of the following components: List and List of Links. For a page the field can be found under the Basic tab when
selecting the Page Properties, and for one of the components under the Configuration tab when editing it.

923
924
Debug Caching Issues
When an issue occurs on the live site, we need to identify where the issue is occuring. By disabling javascript, you can rule out js/optimisely issues
occuring, however, when this doesn't identify the issue, we have to isolate the problem.

Architecture
Akamai/Cloudfront
Varnish/Nginx
Dispatchers
Isolating The Issue
Verifying Varnish

Architecture
telegraph.co.uk -> Akamai (cache)-> Vanish (cache) (instances x4) -> Load balancer -> Dispatcher (cache) -> AEM Publish

Akamai/Cloudfront

The TMG website is fronted by Akamai. Most pages have a TTL of 10 minutes although this may vary (/travel/ has a longer cache time in particular at time
of writing).
Static content such as images, Javascript and CSS are stored for 365 days unless explicitly flushed from the cache.

Subscriptions and any other pages that require HTTPS are served from Amazon Cloudfront under the domain "secure.telegraph.co.uk" with a 10 minute
TTL.

Varnish/Nginx
Behind Akamai is a "proxycache" layer consisting of Varnish and Nginx. This provides another layer of caching and also routes content to various
backends (some content is still served from older systems, and some backends serve alternate versions of content - for example Google AMP pages are
taken from the API, transformed and served from Amazon S3).

Varnish has a 60s TTL on most objects and absorbs a lot of traffic that would otherwise hit the dispatchers. This is important as the dispatchers cannot
handle the full production load even after Akamai has offloaded a large amount of it. If the dispatchers are experiencing problems, we will sometimes
lengthen the TTL on cache objects to reduce load.

It is also responsible for redirecting URLs where needed. Between daily editorial requests and redirects pointing to older content which has been migrated
to AEM, it contains several thousand individual redirect rules.

Work is being done to take non AEM-related logic out of the AEM dispatcher configs and put it into the proxycache layer. As part of this we expect
to replace Nginx with Apache before the migration to AMS in production.

925
Dispatchers
The Travel department has its own separate publish/dispatcher pairs. This is only used to shard traffic - they hold the same code and content as the main
publish/dispatcher pairs.

TMG use a modified 'refetch' replication agent which sends a notification the dispatcher on publish. When this notification is received, the dispatcher
fetches content immediately (so it is effectively pre-cached). During normal operation this cache is not cleared unless a page is republished.

The cache is cleared slowly (over the course of ~3 days) each time we release code - this ensures that where artifacts are versioned (as is the case for
AEM clientlibs), all pages eventually reference the latest version and do not display old content.

Isolating The Issue


If the issue is in the markup on telegraph.co.uk, we know that the issue can be either Akamai, or further back down the stack.

If we veify the content in the individual dispatcher instances for our domain area, and it works correctly. This isolates the issue to either Varnish or Akamai.
If it doesn't, the issue could be a dispatcher cache issue and we can verify directly on the publish instances.

To rule out Akamai, we can test Varnish responses for the issue. We need to test all 4 to ensure that all 4 nodes are correct. If one is cached invalidly, this
can create a sporadic issue.

Verifying Varnish
To test Varnish, we need to know the instances. As these instances can be replaced, we need to get the current running instances.

Johnny has a magic script that gets these, so he can run this locally as: ~/findAWSIP-Prod.sh "varnish*"

Talk to your local sysadmin for an updated copy of these IPs if you have any issue. Those varnish IPs as of 13/07/2017 are:

10.17.111.68

10.17.111.53

10.17.112.153

10.17.112.238

This should return 4 URL's or however many instances are active.

We need a header set to get a response from varnish. Example is as follows:

curl [VARNISH_IP]/path/to/file/ -H "Host: www.telegraph.co.uk"

This can also be done through a browser plugin that changes the request headers. On Chrome, an example of this is ModHeader. https://chrome.google.
com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj?hl=en

Set Host parameter as above, and hit the URL:

http://<varnish_ip>/travel/destinations/europe/united-kingdom/england/oxfordshire/oxford/hotels/

Verify all 4 instances.

If it works on these instances, then the issue is likely in Akamai, if it is an issue there, then potentially there is a faulty cache and it needs to be cleared.

926
Deploying the List Service
Pipeline
The pipeline for the list service can be found here : https://jenkins-prod.api-platforms.telegraph.co.uk/job/Pipeline/job/list-service
Simple type in the name of that branch that you want to build and click build.
This will build from source. Copy the commons library to nexus. Deploy your changes to preprod. Finally there is an option at the end of the build to deploy
to production.
DO NOT DO THIS WITHOUT ADULT SUPERVISION!!!
Most of the time you will not need to do this. Changes pushed to master are picked up by the pipeline automatically and deployed to Nexus and Preprod.
The only manual step is confirming the push to production.

Changing where the list service gets it's data from


This document makes the assumption that you have the code for list service downloaded locally.
The file to update can be found from the root in this location list-service/list-service-web/src/main/resources/application.yml
There are three configurations here. Default(local), Preprod and Production. Insert your changes into the correct place
What is of interest here is urlDynamic and urlCurated.
If you want to change preprod to point at qa2 you would change
urlDynamic: http://aem-docker-training.aws-preprod.telegraph.co.uk:4503/bin/list-service-adaptor
urlCurated: http://aem-docker-training.aws-preprod.telegraph.co.uk:4503/bin/curated-list-service-adaptor
to
urlDynamic: http://pub.aem-qa2.platforms-preprod-gcp.telegraph.co.uk/bin/list-service-adaptor
urlCurated: http://pub.aem-qa2.platforms-preprod-gcp.telegraph.co.uk/bin/curated-list-service-adaptor
I would advise against copying and pasting from here. Yaml is white space sensitive so be careful when editing. Never use tabs!

Updating the List Service with changes that affect AEM-CORE


The most important thing to keep in mind when creating a new version of the list service is that backwards compatibility must be maintained at all times. No
downtime is acceptable. With this in mind a code change to the list service is usually staggered over two releases. First the web service is deployed in the
first release. Then the code release for aem-core is deployed in the second release. The process looks like this.

1. pull request merged to List Service master.


2. automatic build is pushed to Nexus and pre-prod.
3. new build sits in pre-prod for a while and is tested as part of release.
4. if existing functionality is not impacted and pre-prod stable then a CHG ticket can be raised and then deployed to prod.
5. after the release aem-core changes (inlcuding pom update) can be merged.
6. new functionality tested and no stablity problems found then these changes can be deployed in the next release.

927
Image Renditions
AEM Rendtions
Image renditions are created automatically when images are uploaded to AEM.

List of renditions created:

Name Rendition Comments

thumbnail cq5dam.web.140.100

xsmall cq5dam.web.160.160

small cq5dam.web.320.320

medium cq5dam.web.480.480

large cq5dam.web.720.720

xlarge cq5dam.web.1280.1280

xxlarge cq5dam.web.1500.1500

cq5dam.thumbnail.48.48 Initial image loaded

cq5dam.thumbnail.140.100 Initial image loaded

cq5dam.thumbnail.319.319 Initial image loaded

cq5dam.thumbnail.480.480 Initial image loaded

Old Escenic ImageMagick configuration


Table showing the ImageMagick configuration that was used on Escenic

id Label maxWidth maxHeight fallback operation format name compression sharpen

a - - - - - - -

b B:620 620 999999 skip jpg 0.9 0.85

c C:460 460 999999 skip jpg 0.9 0.85

d D:380 380 999999 skip jpg 0.9 0.85

e E:300 300 999999 skip jpg 0.9 0.75

f F:220 220 999999 skip jpg 0.9 0.75

g G:140:Thumbnail (Slideshow v2) 140 999999 skip jpg 0.9 0.75

h H:60 60 999999 skip jpg 0.9 -

i I:620x400:Slideshow (old) 620 400 skip jpg 0.9 0.85

j J:60x60:Thumbnail 60 60 skip jpg 0.9 -

k K:858x536:Slideshow v2 858 536 skip jpg 0.9 -

l L:512x357 512 357 skip jpg 0.9 -

m M:780 780 9999999 skip jpg 0.9 0.85

n N:540 540 9999999 skip jpg 0.9 0.85

o O:120 120 9999999 skip jpg 0.9 0.85

p P:93 93 9999999 skip jpg 0.9 0.85

928
The following is the format of the ImageMagick configuration file used on Escenic.

<imageDef>
<originalVersion id="a">
<label>A:Default</label>
</originalVersion>
<version id="b">
<label>B:620</label>
<maxWidth pix="620" />
<maxHeight pix="999999" />
<fallback operation="skip" />
<format name="jpg" compression="0.9" sharpen="0.85"/>
</version>
<version id="c">
<label>C:460</label>
<maxWidth pix="460" />
<maxHeight pix="999999" />
<fallback operation="skip" />
<format name="jpg" compression="0.9" sharpen="0.85"/>
</version>
<version id="d">
<label>D:380</label>
<maxWidth pix="380" />
<maxHeight pix="999999" />
<fallback operation="skip" />
<format name="jpg" compression="0.9" sharpen="0.85"/>
</version>
<version id="e">
<label>E:300</label>
<maxWidth pix="300" />
<maxHeight pix="999999" />
<fallback operation="skip" />
<format name="jpg" compression="0.9" sharpen="0.75"/>
</version>
<version id="f">
<label>F:220</label>
<maxWidth pix="220" />
<maxHeight pix="999999" />
<fallback operation="skip" />
<format name="jpg" compression="0.9" sharpen="0.75"/>
</version>
<version id="g">
<label>G:140:Thumbnail (Slideshow v2)</label>
<maxWidth pix="140" />
<maxHeight pix="999999" />
<fallback operation="skip" />
<format name="jpg" compression="0.9" sharpen="0.75"/>
</version>
<version id="h">
<label>H:60</label>
<maxWidth pix="60" />
<maxHeight pix="999999" />
<fallback operation="skip" />
<format name="jpg" compression="0.9"/>
</version>
<version id="i">
<label>I:620x400:Slideshow (old)</label>
<maxWidth pix="620" />
<maxHeight pix="400" />
<fallback operation="skip" />
<format name="jpg" compression="0.9" sharpen="0.85"/>
</version>
<version id="j">
<label>J:60x60:Thumbnail</label>
<maxWidth pix="60" />
<maxHeight pix="60" />
<fallback operation="skip" />

929
<format name="jpg" compression="0.9"/>
</version>

<version id="k">
<label>K:858x536:Slideshow v2</label>
<maxWidth pix="858" />
<maxHeight pix="536" />
<fallback operation="skip" />
<format name="jpg" compression="0.9"/>
</version>

<version id="l">
<label>L:512x357</label>
<maxWidth pix="512" />
<maxHeight pix="357" />
<fallback operation="skip" />
<format name="jpg" compression="0.9"/>
</version>

<version id="m">
<label>M:780</label>
<maxWidth pix="780" />
<maxHeight pix="999999" />
<fallback operation="skip" />
<format name="jpg" compression="0.9" sharpen="0.85"/>
</version>
<version id="n">
<label>N:540</label>
<maxWidth pix="540" />
<maxHeight pix="999999" />
<fallback operation="skip" />
<format name="jpg" compression="0.9" sharpen="0.85"/>
</version>

<version id="o">
<label>O:120</label>
<maxWidth pix="120" />
<maxHeight pix="999999" />
<fallback operation="skip" />
<format name="jpg" compression="0.9" sharpen="0.85"/>
</version>

<version id="p">
<label>P:93</label>
<maxWidth pix="93" />
<maxHeight pix="999999" />
<fallback operation="skip" />
<format name="jpg" compression="0.9" sharpen="0.85"/>
</version>
</imageDef>

Escenic ImageMagick config.txt

930
Login, Registration and Subscription
This section covers the Login, Registration and Subscription functionality built in AEM. This covers the work done to unify the login process with new API's
and a single AEM Login page.

API's
Forgotten Password
Global Navigation setup
Login
Password Reset
Payment
Payment Confirmation
Registration
SoapUI - testing of TMG account API's
Test accounts

931
API's
The following API's are used for Login, Registration, Social Login, Social Registration & Subscription:

Known as Purpose API request URL Reference Pages


name

Login API Enables user to login to their account and to comment /tokens POST /tokens Password
Grant
For normal login pass in the user's email and password
For Facebook login pass the user's Facebook ID and auth key POST /tokens Social Grant

Registration API Enables user to register a new account on the site /commerce/accounts/lite POST /accounts/lite

Social Registration Enables user to register their Facebook account site and link it to /commerce/accounts/me POST /accounts/me
API their TMG account /socialregistration /socialregistration

Forgotten Enables user to reset their password /commerce/accounts/passwordreset POST /accounts


Password API /passwordreset

932
Forgotten Password
Configuration
Location: /content/telegraph/secure

Title: Account Reset Password

Name: password

Template: Account Reset Password Template

Tab Field Value Comments

Basic Title Registration

URLs Commerce API Location https://commerce-uat-gateway-api.awsdev.telegraph.co.uk/commerce Example for UAT environment.

Identity API Location https://commerce-uat-gateway-api.awsdev.telegraph.co.uk/identity Example for UAT environment.

Home link /content/telegraph

Old URL www.telegraph.co.uk

Registration link /content/telegraph/secure/registration

Old URL http://web1.aem-dev7.awspreprod.telegraph.co.uk/secure/login.html?logintype=tmg

Templates Template commercial-account

933
Global Navigation setup
Global Navigation setup should be configured to point to the AEM Login, Register, My Account & Logout pages which are all now unified under the
/telegraph/secure node

Not logged in
Item Title Display Text URL Nofollow Icon

Login null Login Prod & End-to-End environments: https://secure8.telegraph.co.uk/secure/login?redirectTo= unchecked null

Dev & testing environments: /content/telegraph/secure/login?redirectTo=

Register null Register Prod & End-to-End environments: https://secure8.telegraph.co.uk/secure/registration?redirectTo= unchecked null

Dev & testing environments: /content/telegraph/secure/registration?redirectTo=

Subscribe null Subscribe http://www.akamai8.awspreprod.telegraph.co.uk/subscriptions/sub-bar/?WT.mc_id=menuSubscribe unchecked null

Video null Video /content/telegraph/video unchecked Video

The "Video" link does not form part of the user account functionality. It is included here for completeness sake as it was included in the Global Header at
time of writing.

Logged in and not a subscriber:


Item Title Display URL Nofollow Icon
Text

Log out null Log out /content/telegraph/secure/logout?redirectTo= unchecked null

My null My Account https://secure.telegraph.co.uk/secure/account/ unchecked null


Account

Subscribe null Subscribe http://www.akamai8.awspreprod.telegraph.co.uk/subscriptions/sub-bar/?WT. unchecked null


mc_id=menuSubscribe

Video null Video /content/telegraph/video unchecked Video

The "Video" link does not form part of the user account functionality. It is included here for completeness sake as it was included in the Global Header at
time of writing.

Logged in and a subscriber:


Item Title Display Text URL Nofollow Icon

Log out null Log out /content/telegraph/secure/logout?redirectTo= unchecked null

My Account null My Account https://secure.telegraph.co.uk/secure/account/ unchecked null

Video null Video /content/telegraph/video unchecked Video

The "Video" link does not form part of the user account functionality. It is included here for completeness sake as it was included in the Global Header at
time of writing.

934
Login
Configuration
Location: /content/telegraph/secure

Title: Account Login

Name: login

Template: Account Login Template

Tab Field Value Comments

Basic Title Account Login

URLs Commerce API https://commerce-uat-gateway-api.awsdev.telegraph.co.uk/commerce Example for UAT environment. Not required to be
Location populated

Identity API https://commerce-uat-gateway-api.awsdev.telegraph.co.uk/identity Example for UAT environment.


Location

Home link /content/telegraph

Old URL www.telegraph.co.uk

Forgotten /content/telegraph/secure/password
Password link

Registration link /content/telegraph/secure/registration

Old URL http://web1.aem-test8.awspreprod.telegraph.co.uk/secure/registration.


html?logintype=tmg

Templat Template commercial-account


es

935
Password Reset
Configuration
Location: /content/telegraph/secure

Title: Account Reset Password Form

Name: resetpassword

Template: Account Reset Password Template

Tab Field Value Comments

Basic Title Registration

URLs Commerce API Location https://commerce-uat-gateway-api.awsdev.telegraph.co.uk/commerce Example for UAT environment.

Identity API Location https://commerce-uat-gateway-api.awsdev.telegraph.co.uk/identity Example for UAT environment.

Home link /content/telegraph

Old URL www.telegraph.co.uk

Templates Template commercial-account

Testing
Testing of the Forgotten Password functionality relies on the API's in the UAT environment (refer Environments Overview) which is hard coded to send an
email containing a reset link with the domain https://secure8.telegraph.co.uk. Ths domain is linked with Test 8 (http://web.aem-test8.awspreprod.telegraph.
co.uk). This cannot be changed so if we are trying to test end-to-end functionality of forgotten password on any other dev or test environment please
follow in the steps below.

1 - Navigate to reset page & submit you registered email address

2 - You will be taken to the rest link confirmation page

3 - Check your email for the "Please reset for password" message and open the link within

936
4 - Allow the page to load

5 - In your browser's address bar replace the Secure8 domain with the domain of you test environment and refresh the page. Fill in the form and submit it.

Change the https to http (unless your test environment is using https for this password reset page)

6 - You will be taken to the confirmation message advising that your password has been change.

937
Payment
Configuration
Location: /content/telegraph/secure

Title: Payment

Name: payment

Template: Payment Template

Tab Field Value Comments

Basic Title Registration

Text Headline tmg.acquisition.title

Direct Debit Freetext content


Guarantee

URLs Commerce API https://commerce-uat-gateway-api.awsdev.telegraph. Example for UAT environment.


Location co.uk/commerce

Identity API https://commerce-uat-gateway-api.awsdev.telegraph. Example for UAT environment.


Location co.uk/identity

Confirmation Page /secure/payment/confirmation Not sure why this works without "/content/telegraph" prefix but it is
working in Production electing to leave this as a partiial relative path.

Missing Product /secure/application/errorpages/404/


Page

Subscription terms http://www.telegraph.co.uk/subscriptions/terms-and-


and conditions link conditions/#30-telegraph-mobile-apps-subscription

Forgotten /content/telegraph/secure/password
Password link

home link

enable javascript http://www.enable-javascript.com

Terms and http://www.telegraph.co.uk/topics/about-us/3692012


conditions link /Terms-and-Conditions.html

Privacy policy link http://www.telegraph.co.uk/topics/about-us/3691972


/Privacy-and-Cookie-Policy.html

Account link /content/telegraph/secure/account Not sure what this setting is doing. If it is simply a redirect location to
the Account page then it should be the relative path.
Old link - https://auth.telegraph.co.uk/

Tokens Sandobx (for dev environments)

Production (for production)

Enable Credit Card checked

Enable Direct Debit checked

Frameurl /content/telegraph/secure/zuoraiframe/

Develop disabled validation unchecked Only set to checked during development/testing. Must not be checked
only - se at for UAT or Production
own risk

Templates Template commercial-acquisition

938
Payment Confirmation
Configuration
Location: /content/telegraph/secure/payment

Title: Confirmation

Name: confirmation

Template: Confirmation Template

Tab Field Value Comments

Basic Title Confirmation

Text Headline text Thank you <%= name %>

Direct Debit Guarantee Freetext content telling the users their subscription is now active.

URLs home link /content/telegraph

enable javascript http://www.enable-javascript.com

Terms and conditions link http://www.telegraph.co.uk/topics/about-us/3692012/Terms-and-Conditions.html

Terms and conditions link http://www.telegraph.co.uk/topics/about-us/3692012/Terms-and-Conditions.html Escenic page

Privacy policy link http://www.telegraph.co.uk/topics/about-us/3691972/Privacy-and-Cookie-Policy.html Escenic page

Templates Template commercial

939
Registration
Configuration
Location: /content/telegraph/secure

Title: Registration

Name: registration

Template: Account Registration Template

Tab Field Value Comments

Basic Title Registration

URLs Commerce API Location https://commerce-uat-gateway-api.awsdev.telegraph.co.uk/commerce Example for UAT environment.

Identity API Location https://commerce-uat-gateway-api.awsdev.telegraph.co.uk/identity Example for UAT environment.

Not required to be populated

Home link /content/telegraph

Old URL www.telegraph.co.uk

Terms and conditions link http://www.telegraph.co.uk/topics/about-us/3692012/Terms-and-Conditions.html This is an Escenic page

Login link /content/telegraph/secure/login

Old URL http://web1.aem-dev7.awspreprod.telegraph.co.uk/secure/login.html?logintype=tmg

Templates Template commercial-account

940
SoapUI - testing of TMG account API's
The TMG account API's can be testing used SoapUI.

Download & install SoapUI (it can be downloaded from here https://www.soapui.org/downloads/latest-release.html)
Download this XML project file to the machine you install SoapUI (TMP API full-soapui-project.xml)
Import this XML project file into SoapUI (File > Import Project)

941
Test accounts
Few test accounts (subscribed) which Escenic team used for testing are:

UN: george.bamgboye+0912151@telegraph.co.uk
PWD: Telegraph1

UN: george.bamgboye+0912152@telegraph.co.uk
PWD: Telegraph1

UN: george.bamgboye+0912153@telegraph.co.uk
PWD: Telegraph1

Below is an account which is registered but not subscribed:

UN: george.bamgboye+0701161@telegraph.co.uk
PWD: Telegraph16

942
New Relic

943
New Relic Authoring Data
This is reference to the TMG Authoring data available in New Relic.

Important note: Where name of the transaction has 'api' in it duration refers to API processing time. Specially for publishing number of additional steps take
place before story is actually published and it's important to understand what duration is reported.

Create Story - New story created in Authoring

Name WebTransaction/Custom/authoring/api/create-story

Attributes duration Time to process in seconds

section Section for article (News, Sport etc.)

storyAction Always ‘CREATE’

storyType ‘Article’, ‘Gallery’ or ‘Live Article’

Sample queries Amount of galleries created per day in last week - View in Insights

SELECT count(*) as 'Number of galleries'


FROM Transaction
WHERE name = 'WebTransaction/Custom/authoring/api/create-story'
AND storyType = 'Gallery'
FACET dateOf(timestamp)
SINCE 1 WEEK AGO

Amount of articles created by section in last 24 hours - View in Insights

SELECT count(*) AS 'Number of articles'


FROM Transaction
WHERE name = 'WebTransaction/Custom/authoring/api/create-story'
AND storyType = 'Article'
FACET section
SINCE 1 DAY AGO

Publish Story - Story published in Authoring

Name WebTransaction/Custom/authoring/api/publish/publish-story

Attributes duration Time to process in seconds

section Section for article (News, Sport etc.)

storyAction ‘PUBLISH’ or 'REPUBLISH'

storyType ‘Article’, ‘Gallery’ or ‘Live Article’

Sample queries Average time taken to publish a story per story type - View in Insights

SELECT average(duration) as 'Time to publish a story'


FROM Transaction
WHERE name = 'WebTransaction/Custom/authoring/api/publish/publish-story'
FACET storyType
SINCE 1 day ago

Update Story - Story saved in Authoring

Name WebTransaction/Custom/authoring/api/publish/publish-story

Attributes duration Time to process in seconds

944
section Section for article (News, Sport etc.)

storyAction Always ‘UPDATE’

storyType ‘Article’, ‘Gallery’ or ‘Live Article’

Sample queries Number of times story has been saved per section - View in Insights

SELECT count(*) as 'Story saved'


FROM Transaction
WHERE name = 'WebTransaction/Custom/authoring/api/update-story'
FACET section
SINCE 1 day ago

Get Story - Story opened for editing in Authoring

Name WebTransaction/Custom/authoring/api/get story

Attributes duration Time to process in seconds

Sample queries Graph how often articles are opened in Authoring - View in Insights

SELECT count(*)
FROM Transaction
WHERE name = 'WebTransaction/Custom/authoring/api/get story'
TIMESERIES 5 minutes
SINCE 1 day ago

Finder Search

Name WebTransaction/Custom/authoring/api/finder/search

Attributes duration Time to process

channels List of channels used for filtering

headline Searched headline

storyType ‘Article’, ‘Gallery’ or ‘Live Article’

status Status (Draft, Published etc)

Sample queries Average response time for Finder searches over last week - View in Insights

SELECT average(duration)
FROM Transaction
WHERE name = 'WebTransaction/Custom/authoring/api/finder/search'
TIMESERIES 1 HOUR
SINCE 1 WEEK AGO

Keyword Search

Name WebTransaction/Custom/authoring/api/keyword/search

Attributes duration Time to process

Sample queries Minimum and maximum time to get keywords in last day - View in Insights

SELECT min(duration), max(duration)


FROM Transaction
WHERE name = 'WebTransaction/Custom/authoring/api/keyword/search'
SINCE 1 DAY AGO

945
Asset Upload

Name WebTransaction/Custom/authoring/api/asset/upload

Attributes duration Time to process

assetName Filename

filenameChanged Yes if unsupported characters were removed or replaced

oldAssetName Original filename (including unsupported characters)

uploadDirectory Path in DAM where asset was uploaded to

request.headers.contentLength HTTP request size; unfortunately as string.

chpID CHP Image ID used

chpSucces yes, no, no value (for assets)

usingCHP yes (if image from CHP), no value (for rest images)

headline headline of the article

articleUrl relative url of the article

userId Id of the logged in user who is uploading image.

Sample Number of images uploaded per day for last 7 days - View in Insights
queries
SELECT count(*)
FROM Transaction
WHERE name = 'WebTransaction/Custom/authoring/api/asset/upload'
FACET dateOf(timestamp)
SINCE 1 week ago

SELECT pageId, assetName, chpId, chpSuccess, usingChp


FROM Transaction
WHERE name = 'WebTransaction/Custom/authoring/api/asset/upload'
SINCE 1 day ago

SELECT headline, pageId, articleUrl, assetName, timestamp, userId FROM Transaction WHERE name LIKE
'%/authoring/api/asset/upload' and usingChp = 'no' SINCE 1 day ago

Replication listeners

Name OtherTransaction/Custom/authoring/eventhandler/ResourceReplicationStartListener
OtherTransaction/Custom/authoring/eventhandler/PageReplicationListener
OtherTransaction/Custom/authoring/eventhandler/ResourceReplicationFinishListener
OtherTransaction/Custom/authoring/eventhandler/ResourceActivationListener

Attributes duration Time to process in seconds

Description These are used by development team to monitor how often replication events take place and how they perform.

These have limited or no value for wider analytics purposes.

Publish Story - Full publish action

Name WebTransaction/Custom/authoring/browser/publish/publish-story

Attributes duration Time to process

articleId Authoring Article ID

galleryLength Number of images in gallery

946
Description Full publishing action timings calculated from time publish button is pressed to confirmation that story has been published trough all
replication agents.

This is KPI for Authoring publishing performance.

Sample Graph how publishing has performed over last day - View in Insights
queries
SELECT average(duration) / 1000 as 'Seconds to publish'
FROM PageAction
WHERE actionName = 'WebTransaction/Custom/authoring/browser/publish/publish-story'
TIMESERIES 10 minutes
SINCE 1 day ago

Autosuggest Keywords

Name WebTransaction/Custom/authoring/browser/auto-suggest (when button is clicked)


WebTransaction/Custom/authoring/browser/autosuggest-fetched (when response is received)

Attributes duration Time to process (in autosuggest-fetched)

articleId Authoring Article ID

galleryLength Number of images in gallery

Description Actions from using keyword autosuggestion feature.

Sample queries Graph how often autosuggest feature is used in last day - View in Insights

SELECT count(*)
FROM PageAction
WHERE actionName = 'WebTransaction/Custom/authoring/browser/autosuggest-fetched'
TIMESERIES 1 hour
SINCE 1 day ago

Open-Premium Dialog

Name WebTransaction/Custom/authoring/browser/premium/view-dialog (when open OP dialog)


WebTransaction/Custom/authoring/browser/premium/accept (when click done on OP dialog)
WebTransaction/Custom/authoring/browser/premium/cancel (when click cancel on OP dialog)
WebTransaction/Custom/authoring/browser/premium/select-override-premium
WebTransaction/Custom/authoring/browser/premium/select-override-open
WebTransaction/Custom/authoring/browser/premium/lock
WebTransaction/Custom/authoring/browser/premium/unlock

Attributes premiumDialogId unique Id for each OP dialog

articleId Authoring Article ID

channel Channel for the story

headline Headline for the story

galleryLength Number of images in gallery

Description Actions from using OP dialog

Sample queries List of all OP dialog actions together with dialogId - View in Insights

SELECT actionName, premiumDialogId


FROM PageAction
WHERE actionName
LIKE 'WebTransaction/Custom/authoring/browser/premium/%'
SINCE 1 days ago

Example how many action user perform for each OP dialog instance - View in Insights

SELECT count(*)
FROM PageAction

947
WHERE actionName
LIKE 'WebTransaction/Custom/authoring/browser/premium/%'
FACET premiumDialogId
SINCE 1 days ago

Move assets between lead asset & body

Name WebTransaction/Custom/authoring/browser/remove-asset (remove lead asset)


WebTransaction/Custom/authoring/browser/delete-asset (remove body embed image/video)
WebTransaction/Custom/authoring/browser/move-lead-asset (move lead asset to the top of the body)
WebTransaction/Custom/authoring/browser/replace-lead-asset (replace lead asset with body asset)
WebTransaction/Custom/authoring/browser/swap-with-lead-asset (swap lead asset and body asset)

Attributes articleId

Description Actions related to moving assets between body and lead asset

Sample
queries SELECT *
FROM PageAction
WHERE actionName
LIKE 'WebTransaction/Custom/authoring/browser/[remove-asset, delete-asset, move-lead-asset, replace-
lead-asset, swap-with-lead-asset]'
SINCE 1 days ago

Add new 3rd party embed types

Name WebTransaction/Custom/authoring/browser/html-embed/insert (insert embed into body)

Attributes articleId Authoring Article ID

type embed type

storyType ‘Article’, ‘Gallery’ or ‘Live Article’

Description Actions related to embedding 3rd party types

Sample queries
SELECT *
FROM PageAction
WHERE actionName
LIKE 'WebTransaction/Custom/authoring/browser/html-embed/insert'
SINCE 1 days ago

Asset dialog image selection and Desktop upload

Name WebTransaction/Custom/authoring/browser/asset-dialog/reused-image

Attributes articleId Authoring Article ID

CHPImageId CHP Image ID used

imageName CHP image filename

imageFolder image folder in DAM

origin CHP (reused), Desktop (reused), Desktop (upload)

Description Log of assets taken from Image Library or uploaded from desktop

Sample query
SELECT articleId, CHPImageId, headline, imageName, imageFolder, origin
FROM PageAction
WHERE actionName = 'WebTransaction/Custom/authoring/browser/asset-dialog/reused-image'
SINCE 1 days ago

948
CHP upload via drag and drop

Name WebTransaction/Custom/authoring/browser/CHP/image-drag-and-drop

Attributes articleId Authoring Article ID

CHPImageId CHP Image ID used

imageName CHP image filename

imageFolder image folder in DAM

origin CHP (drag and drop)

Description Log of actions using d&d functionality (dragged from CHP portal)

Sample query
SELECT articleId, CHPImageId, imageName, imageFolder, origin
FROM PageAction
WHERE actionName = 'WebTransaction/Custom/authoring/browser/CHP/image-drag-and-drop'
SINCE 1 days ago

CHP upload via ID field

Name WebTransaction/Custom/authoring/browser/CHP/image-from-id-field

Attributes articleId Authoring Article ID

CHPImageId CHP Image ID used

imageName CHP image filename

imageFolder image folder in DAM

origin CHP (upload)

Description Log of actions using insert ID functionality (uploaded from CHP portal)

Sample query
SELECT articleId, CHPImageId, imageName, imageFolder, origin
FROM PageAction
WHERE actionName = 'WebTransaction/Custom/authoring/browser/CHP/image-from-id-field'
SINCE 1 days ago

Usage API Single

Name Custom/AEM/authoring/api/chp/usage-api/single

Attributes assetId Unique ID of asset from Assets API

success 'yes' if usage was recorded

usageApiStatus 'pending' for draft, 'published' or 'cancelled' for unpublished

path Path to page where asset was used

duration Time needed to send single usage

Description Log of assets reported one by one to Usage API

Sample queries

SELECT assetId, duration, success, usageApiStatus, path


FROM UsageApi
WHERE action = 'Custom/AEM/authoring/api/chp/usage-api/single'
SINCE 1 days ago

949
Usage API

Name Custom/AEM/authoring/api/chp/usage-api/single

Attributes imagesOnPa Number of all images on the page (searched in lead asset, article body, live posts etc. also including images not
ge connected with Assets API)

sentImages Number of images reported to Usage API

failedImages Number of calls to Usage API that failed

usageApiSta 'pending' for draft, 'published' or 'cancelled' for unpublished


tus

path Path to page where asset was used

duration Time needed to process and send all usage

Description Log of pages processed in order to report assets to Usage API

Sample
queries SELECT imagesOnPage, sentImages, failedImages, duration, usageApiStatus, path
FROM UsageApi
WHERE action = 'Custom/AEM/authoring/api/chp/usage-api'
SINCE 1 days ago

950
Opentag tag management
Opentag is "enterprise tag management solution" - this doesn't really mean anything.

In reality it's way to add and modify scripts on websites without going trough traditional heavy release process.

In Telegraph AEM team Opentag is sometimes mistakenly used to refer piece of code which includes Opentag script. This was previously
misused to include other scripts and CSS-files.

Please read Script Management for more information

Naming convention for all OpenTag Prod and UAT containers


{Department owner}: {Tag name} {version number} e.g ADTECH: Krux [v1.0]

All production tags have been committed to Stash under the OpenTag project for version control purposes.

Releasing new tags or updates to existing


Steps to release a new/update script via OpenTag:

1. Create a JIRA ticket in the OpenTag JIRA project


2. Link any corresponding OpenTag tickets from your project to the OT JIRA ticket
3. Test the script in the respective UAT container
4. Once testing is confirmed, commit the script to the respective repo within the OpenTag Stash project.
a) All scripts should follow the naming convention: {Department owner}: {Tag name} {version number}
b) All commits to the OpenTag project should have the OT ticket number in the commit message
4. Add the standard OpenTag release steps to the corresponding RFC, stating the script name and the copy from and to location.
5. Once live the OT JIRA ticket should be closed once testing is confirmed.

Unknown User (mirzad) can be contacted for additional information on release process.

Testing Tags
To test what scripts are included the page run the page with ?opentag_debug_tool at the end, e.g. http://www.telegraph.co.uk/cars/?opentag_debug_tool

While testing you can bypass the CDN and go directly to open tag by changing the domain to opentag.s3.amazonaws.com (rather than *.cloudfront.net) to
avoid waiting for 10 minute delay.

The open tag documentation can be found at http://docs.qubitproducts.com/opentag/

Configuring Opentag script URL is done at http://localhost:4502/system/console/configMgr - search for uk.co.telegraph.core.commons.configuration.osgi.


OsgiConfigurationService to find configuration to update.

Support
Best way to get support for Opentag from the Qubit Digital is to email customersupport@qubitdigital.com - they often respond within 30 minutes.

They also have form on their web page for support request but in the past nobody has received responses trough it.

951
Opentag Cookie Widget Setup
Update Notes:

Notification Widget - Content CSS

To enable the cookie widget you need to check the Requires cookie consent box. Image below.

Step-by-step guide
1. Setting up the custom script that changes the cookie position
2. Customise cookie consent widget

Adding the custom script that changes the cookie position


1. First add a new script to your container by clicking on the + Add New Script button.
2. You can set whatever name you like to your script, but it's best to use a descriptive name.
3. From the Script Type options select Custom Script
4. In the inline HTML box copy and paste the code below.

Inline HTML

<script type="text/javascript">
var cookieHolder = document.createElement("div"),
mainBody = document.getElementsByTagName("body")[0];

cookieHolder.style.webkitTransition = "all .3s";


cookieHolder.style.MozTransition = "all .3s";
cookieHolder.style.transition = "all .3s";
cookieHolder.style.height = "0";
cookieHolder.style.overflow = "hidden";

mainBody.insertBefore(cookieHolder, mainBody.childNodes[0]);

function cookieTop() {
var cookieConsent = document.getElementById("qb_cookie_consent_main");
if (cookieConsent === null) {
setTimeout(cookieTop, 500);
return;
}
cookieHolder.appendChild(cookieConsent);
cookieHolder.style.height = "76px";
cookieRemove();

setTimeout(function() {
cookieHolder.parentNode.removeChild(cookieHolder);
cookieHolder = null;
}, 15000);
}

function cookieRemove() {
var cookieConsent = document.getElementById("qb_cookie_consent_main");
if (cookieConsent != null) {
setTimeout(cookieRemove, 250);
return;
}

952
if (cookieHolder != null) {
cookieHolder.parentNode.removeChild(cookieHolder);
}

cookieTop();
</script>

Customise cookie consent widget

First open the Consent Widget by clicking on the Custimize Consent Widget. A pop-up modal will appear and on the first tab (Basic Settings) you can
alter the mod, when to ask again etc.

For the content under the second tab (Notification Widget) follow the the instructions below

1. In the Notification Widget HTML area copy and paste the code below

Notification Widget HTML

<div class="container">
<div class="tmg-cookie-box">

953
<p>
We use cookies to enhance your visit to our site and to bring you advertisements that might
interest you. <br>
<b>Read our <a href="{{cookieAndprivacyPolicyUrl}}"
target = "_blank"
id="{{cookieAndPrivacyAndPolicyId}}">
{{cookieAndprivacyPolicyText}}
</a> to find out more. </b>
</p>
</div>
</div>

2. In the Iframe CSS area copy and paste the code below

Iframe CSS

display: block;
height: 76px !important;
position: static;
width: 100%;

3. In the Content CSS area copy and paste the code below

Content CSS

body {
background: #f8f3df;
display: table;
font-family: Georgia, Arial, Tahoma, sans-serif;
font-size: 14px;
margin: 0 auto;
padding: 19px;
max-width: 1240px;
}

body > div {


display: table-cell;
vertical-align: top;
}

body > div.content {


padding-left: 40px;
width: 120px;
}

.tmg-cookie-box {
color: #262626;
}

.tmg-cookie-box p{
margin: 0;
}

.tmg-cookie-box b {
font-size: 12px;
font-weight: normal;
}

.tmg-cookie-box a {
color: #262626;
}

#closePopup {

}
.action-footer #buttonAccept,

954
#closePopup {
background: none transparent;
border: 1px solid #000;
border-radius: 2px;
cursor: pointer;
display: block;
float: right;
font-size: 12px;
font-weight: bold;
line-height: 36px;
text-align: center;
text-transform: uppercase;
width: 100%;
}

#closePopup {
font-size: 0;
line-height: 0;
}

#closePopup:before {
content: "Ok";
font-size: 12px;
line-height: 36px;
}

.action-footer #buttonAccept:hover,
#closePopup:hover {
box-shadow: none;
}
.action-footer #buttonAccept:active,
#closePopup:active {
position:relative;
top: 1px;
}
.action-footer #buttonDecline {
display: none;
color: #555;
cursor: pointer;
line-height: 44px;
padding-right: 15px;
text-align: right;
float: left;
width: 121px;
}

@media only screen and (max-width: 768px) {


.tmg-cookie-box p { font-size: 12px; }
.tmg-cookie-box p br { display: none; }
body > div.content { width: 70px; }
}

/* Iphone font-size fix on landscape */


@media only screen and (min-device-width : 320px) and (max-device-width : 568px) and (orientation :
landscape) {
body { padding-top: 10px; }
.tmg-cookie-box p,
.tmg-cookie-box p b { font-size: 8px; }
}
@media only screen and (max-width: 475px) {
body { padding-top: 5px; }
.tmg-cookie-box p,
.tmg-cookie-box p b { font-size: 10px; }
.tmg-cookie-box p br { display: none; }
}

4. For the Accept Button Text and Decline Button Text use whatever suits your project.

For the content under the third tab (Status Widget) follow the the instructions below

955
1. In the Status Widget HTML area copy and paste the code below

Status Widget HTML

<div class="content">
<div class="icon"></div>
<div id="{{cookieStatusId}}"></div>
</div>

2. In the IFrame CSS area copy and paste the code below

bottom: 0;
left: 0;
height: 20px;
width: 100%;
z-index: 2147483647;
display: none;

3. In the Content CSS area copy and paste the code below

Content CSS

body {
background: transparent;
margin: 0;
padding: 0;
font-family: arial, helvetica;
text-align: center;
vertical-align: middle;
font-size: 12px;
line-height: 18px;
}
.content {
max-width: 1280px;
margin: 0 auto;
text-align: left;
}
html>body #{{cookieStatusId}} {
width: auto;
}
#{{cookieStatusId}} {
padding: 1px 10px 0px 22px;
width: 11.5em;
cursor: pointer; !important
}
.icon {
background-image: url("https://d3c3cq33003psk.cloudfront.net/consent/img/background-image.png");
width: 20px;
height: 20px;
position: absolute;
background-position: 6px -116px;
background-repeat: no-repeat;
z-index: 199999;
}
.declined #{{cookieStatusId}} {
-webkit-box-shadow:inset 0px 1px 0px 0px #f5978e;
box-shadow:inset 0px 1px 0px 0px #f5978e;
background: #c43838;
-moz-border-radius:5px 5px 0px 0px;
-webkit-border-radius:5px 5px 0px 0px;
border-radius:5px 5px 0px 0px;
border:1px solid #d02718;
display:inline-block;
color:#ffffff;
font-family:arial;

956
font-size:12px;
text-decoration:none;
}
.declined #{{cookieStatusId}}:hover {
background: #ac3232;
}
.declined #{{cookieStatusId}}:active {
position:relative;
top: 1px;
}
.accepted #{{cookieStatusId}} {
-moz-box-shadow:inset 0px 1px 0px 0px #6ebf26;
-webkit-box-shadow:inset 0px 1px 0px 0px #6ebf26;
box-shadow:inset 0px 1px 0px 0px #6ebf26;
background: #32ac5d;
-moz-border-radius:5px 5px 0px 0px;
-webkit-border-radius:5px 5px 0px 0px;
border-radius:5px 5px 0px 0px;
border:1px solid #619908;
display:inline-block;
color:#ffffff;
font-family:arial;
font-size:12px;
font-weight:normal;
text-decoration:none;
}
.accepted #{{cookieStatusId}}:hover {
background: #28934e;
}
.accepted #{{cookieStatusId}}:active {
position:relative;
top: 1px;
}

4. For the Status buttons text, use whatever suits your project.

Important Notes

Once you save the script you need to COMMIT the changes. Once the commit is done it can take up to 10 minutes for the changes to take
effect.

Some times using ?opentag_debug_tool in the url helps see changes faster. e.g. http://localhost:4503/demosite/home-page.html?
opentag_debug_tool

The script that the system generates for the container needs to be inserted in all the pages.

For more information about Qubit and Opentag please visit the support page. You'll find all the documents there. http://www.qubitproducts.com
/support

957
Templates
Template Description Has Notes
Breadcrumb

Article 2 General use across site for all articles

Author 2 Page promoting stories written by a specific author/journalist

Bare Blank template used by Spark. Can configure to have or not have the Telegraph header and footer Available

Blank Internal AEM maagement page typically used for the Application nodes.

commercial – Template for Zuora iFrame


Zuora Template

Comparison
Template

Confirmation Secure payment confirmation page (Zuora)


Template

Cluster Template Index page originally intneded for Cluster pages. Is still in use the Culter cluster page but the Hub template does
everything htis needs this could be retired and should not be used when creating new cluster pages.

Default Error
Page

Destination

Entity Used in old Cars & Film

Entity Definition Used in old Cars & Film

Error Page Travel error page

error Template Secure payment error template (Zuora)

Film - Article Not actively being use anymore as Film has been migrated to the new templates.
Template

Film - Entity Not actively being use anymore as Film has been migrated to the new templates.
Page Template

Film - Home Not actively being use anymore as Film has been migrated to the new templates.
Page Template

Film - Short Not actively being use anymore as Film has been migrated to the new templates.
article

Folder

Footer Config Used by global navigation

Gallery

Gallery Slide

Generic Error
Page

Global Used by global navigation


Navigation
Config

Home Page

Home - Shop
Theme

Hotel Listing
Template

Hub Template

Logo Bar Template for Logo Bar (must be named 'logoBar')

Navigation Used by global navigation


Config

Navigation Menu Possibly used for navigation on Travel

Non-IAB Spark non-IAB used in the side of Article 2 templates


Advertisments

Onward Journey Used for onward journey lists at the bottom of the page on Article 2

958
Overlay Config Used by global navigation

Payment Secure payment template (Zuora)


Template

Paywall Paywall container page (must be called ''paywall'


Container

Portal

Primary Logo Bar Used by global navigation and video navigation

Review Template for Entity review (eg. VW Golf)

Side Bar Template for Side Bar (must be names 'sideBar')

Simple

Snippet

Tags Mapping Configuration page for tag mapping

Topic (Cars)

Topics

Travel Product -
Tour Template

Video Hub
Template

959
Review Template

960
UI
Table of content

Expand all Collapse all

961
Accessibility

962
TMG Digital Accessibility Framework 2019 (TMG DAF 2019)

963
Why do we need accessibility?
We need accessibility standards so we can make all of The Telegraph's digital products:

Perceivable - so our users can read our content


Operable - so our users can operate our digital products
Understandable - so our users can understand our digital products and their content
Robust - as our users technologies and user agents evolve, the content remains accessible

If any of these are not true, users with disabilities will not be able to use our products.

UK Law (Equality Act 2010) stipulates that websites should be accessible - and that we must make reasonable adjustments to make this happen. This
standard should help us meet our obligations - and that testing with disabled or impaired users ensures that our interpretation of the requirements
successfully makes our content accessible.

What standards is the TMG DAF based on?

The Telegraph Media Group Digital Accessibility Framework is based on the Digital Accessibility Framework by Prof. Jonathan Hassell, Hassell Inclusion.
This Framework, and any amends, are also based on:

WCAG 2.1 – A
WCAG 2.1 – AA
WCAG 2.1 – AAA
WAI ARIA 1.1

How do we get there?

1) All new stories that may have an impact on accessibility (especially ones that introduce or change
markup) must have an acceptance criteria added as follows:

"Must comply to TMG DAF 2019 checkpoints, and their associated WCAG 2.1 Success Criteria when tested in isolation. See https://
docs.google.com/spreadsheets/d/1C_jkcUIQzu6gZvoUAbqUcrUTKWPMBrKsAZmd1TZn5QQ/edit?usp=sharing"

2) Write tickets to make the Pa11y dashboard green:


Automated Accessibility Testing - PA11Y

3) Test to ensure that the Framework is met


This will include automated tests, PA11Y, and manual tests in browser/device.

PROCESS NOTE: QA's should develop a suite of tests to ensure a consistency in testing.

NOTE: Any accessibility settings set on the user's browser AND/OR device need to be adopted and usable in the delivered product. This includes screen
magnifiers, screen readers, increases in font size or page zoom, font/background colour overrides. Additional settings, if available, should also be tested.

4) Train content authors to ensure that accessibility is not broken by content

Accessibility is not just about the technology used to produce web or app content - the content that populates the pages also needs to be considered.

Telegraph Media Group Accessibility Framework 2019 documentation


All documentation can be found on the following Google Sheet

https://docs.google.com/spreadsheets/d/1C_jkcUIQzu6gZvoUAbqUcrUTKWPMBrKsAZmd1TZn5QQ/edit?usp=sharing

964
Front End Optimisations - 2 Seconds TTS
GOAL: 2 Seconds CURRENT: 3.5 Seconds

Released

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

TT- Tidy up gulpfile Oct 14, May 18, Unassigned None CLOSED Done
2889 2016 2017

TT- Improve CSS loading May 24, Mar 10, Matt Gareth CLOSED Done
2202 2016 2018 Newman [X] Clubb [X]

TT- Defer and optimise Apr 07, Jan 10, Matt None CLOSED Done
1723 opentag & sundry scripts 2016 2017 Newman [X]
critical path, including
adverts

AEM- Accessibility refactoring of Mar 09, May 26, Andrzej None RELEASED Unresolved
4772 components (Phase1 - Set 2016 2016 Dolinski [X]
up)

TT- Tidy the head, footer and Mar 09, Mar 10, Matt None CLOSED Done
1724 clientlibs 2016 2018 Newman [X]

AEM- Investigate and spike font Jul 24, Apr 14, Unassigned None CLOSED Done
1708 optimisation 2015 2016

AEM- Investigate and spike Jul 24, Mar 02, Unassigned None CLOSED Done
1707 minification of JS and CSS 2015 2016
and HTML

965
AEM- Investigate and spike Jul 24, Sep 16, Unassigned None Done
1704 modularising/ streamlining 2015 2015 CLOSED
JQuery

AEM- Optimize CSS / JS loading Jul 24, Apr 14, Unassigned None RELEASED Unresolved
1701 strategies 2015 2016

AEM- Lazyload issues Jun 29, Dec 02, Unassigned None RELEASED Unresolved
1383 2015 2015

AEM- Performance - Audit & Jun 22, Oct 20, Unassigned Gavin Kirk CLOSED Done
1255 devolution of Core JS / 2015 2015 [X]
CSS libraries

11 issues

In Progress:

Key Summary T Created Updated Due Assignee Reporter P Status Resolution

No issues found

To do:

key summary type created updated due assignee reporter priority status resolution

Jira project doesn't exist or you don't have permission to view it.

View these issues in Jira

Future Ideas:

Please start spewing ideas for optimisation here.

Move 3rd party scripts to the bottom above </body> - or anything not on the critical path (so, ad trackers, probably mostly). Or remove some if
we can!
gzip as well as minify (maybe this happens already?)

966
List component
List documentation on confluence

967
Schema.org
Schema.org suggested top level itemtypes.
Below is a list of currently used components (tbc) with suggested itemtypes from the schema.org documentation. In some cases additional itemprops are
provided for further detail.

These are only intended as suggestion for the top level itemscope tags. When drilling down into the markup of the components further itemtypes &
itemprops should be applied in the appropriate places.

Components:

advert
<div itemscope itemtype="http://schema.org/WPAdblock">

articleBodyHeadline
<div itemscope itemtype="http://schema.org/headline">

articleBodyImage
<div itemscope itemtype="http://schema.org/image">

articleBodyStandfirst
<div itemscope itemtype="http://schema.org/text">

articleBodyText
<div itemscope itemtype="http://schema.org/ArticleBody">

articleDate
<div itemscope itemtype="http://schema.org/Date">

author
<div itemscope itemtype="http://schema.org/Person" itemprop="http://schema.org/author">

authorBio
<div itemscope itemtype="http://schema.org/Person" itemprop="http://schema.org/author">

box
<div itemscope itemtype="http://schema.org/GeoShape">

breadcrumb
<div itemscope itemtype="http://schema.org/BreadcrumbList">

byline
<div itemscope itemtype="http://schema.org/Person" itemprop="http://schema.org/author">

externalVideoPlayer
<div itemscope itemtype=" http://schema.org/VideoObject">

gallery
<div itemscope itemtype="http://schema.org/ImageGallery">

individual images: <div itemscope itemtype="http://schema.org/image http://schema.org/Url">

968
galleryTeaser
<div itemscope itemtype="http://schema.org/Url">

headline
<div itemscope itemtype="http://schema.org/Headline">

heroBlock
<div itemscope itemtype="http://schema.org/creativeWork" itemprop="http://schema.org/mainEntityOfPage">

htmlEmbed
<div itemscope itemtype="http://schema.org/WebPageElement">

inlineContent
<div itemscope itemtype="http://schema.org/ArticleBody">

leadAsset
<div itemscope itemtype="http://schema.org/ImageObject">

list
<div itemscope itemtype="http://schema.org/ItemList">

listOfLinks
<div itemscope itemtype="http://schema.org/ItemList">

listOfTags
<div itemscope itemtype="http://schema.org/ItemList">

logoBar
<div itemscope itemtype="http://schema.org/brand">

navigationMenu
<div itemscope itemtype="http://schema.org/SiteNavigationElement">

quote
<div itemscope itemtype="http://schema.org/text" itemprop="http://schema.org/citation">

standfirst
<div itemscope itemtype="http://schema.org/text">

splitter
<div itemscope itemtype="http://schema.org/GeoShape">

socialShare
<div itemscope itemtype="http://schema.org/url" itemprop="http://schema.org/shareAction">

tweet
<div itemscope itemtype="http://schema.org/text">

tweetTimeline

969
<div itemscope itemtype="http://schema.org/text">

videoPlayer
<div itemscope itemtype="http://schema.org/Videobject">

Snippets:

commonheader
<div itemscope itemtype="http://schema.org/WPHeader">

defaultFooter
<div itemscope itemtype="http://schema.org/WPFooter">

defaultHeader
<div itemscope itemtype="http://schema.org/WPHeader">

defaultSidebar
<div itemscope itemtype="http://schema.org/WPSidebar">

970
Time tag
We will be replacing (if not replaced already by the time you read this doc) the current span tags that output the datetime on the list items with the time
tag. Thanks to BEM, there should be no changes to the current visual, nor CSS amends needed.

So, from

<span class="m_meta-property__date">05 Nov 2015, 2:15pm</span>

to

<time class="m_meta-property__date">05 Nov 2015, 2:15pm</time>

Then, we will add the datetime and pubdate params.

<time class="m_meta-property__date" datetime="2015-11-05T14:15:00" pubdate>05 Nov 2015, 2:15pm</time>

We also need to print the date in human format by using the title attribute as some of the inner HTML values will be updated via JS.

<time class="m_meta-property__date" title="05 Nov 2015, 2:15pm" datetime="2015-11-05T14:15:00" pubdate>05 Nov


2015, 2:15pm</time>

Date and time will be split in different span tags. Please note that the comma has it's own span and there is no space nor code indentation between the
date and the comma span tags.

/*DON'T INDENT THE CODE!!!*/


<time class="m_meta-property__date" title="05 Nov 2015, 2:15pm" datetime="2015-11-05T14:15:00" pubdate>
<span class="m_meta-property__date-date">05 Nov 2015</span><span class="m_meta-property__date-separator">,<
/span>
<span class="m_meta-property__date-time">2:15pm</span>
</time>

As JS uses RFC 2822 specification for representing dates as string (which is horrible from every point of view), we will be printing the UNIX timestamp, at
the list item component container level, using a data-timestamp parameter.

So, from

<li class="list-of-entities__item">

to

<li class="list-of-entities__item" data-timestamp="123456789">

Authors will be able to turn this functionality ON/OFF by setting a flag for each list of entities block. When set to true, 'data-timelabels=true' will be added to
the element.

<div class="list-of-entities component version-4" data-timelabels="true" data-tmg-dtm-nav-area="list">

971
Updating datetime format in the news list
To stop the page from showing date in 2 different formats and avoiding users from seeing the date/time changing when the page is loaded, we will
combine CSS and JS to hide, update and then show the date/time in the list items.

1. CSS sets dates to visibility hidden

.js .list-of-entities[data-timelabels="true"] .m_meta-property__date {


visibility:hidden;
}

2. JS updates dates following the rules:

IF TODAY

< 1 min ago


1 min ago
2 min ago
...
59 min ago
10:12
...
23:59

ELSE

dd Mon yyyy
19 Oct 2015
6 Nov 2015

3. After sorting the dates for a specific list, the JS adds a class "dynamic-time-done" (or something else that makes sense) to the list container allowing
CSS to show the dates in the correct format.

4. CSS shows dates when the JS has done the job

.js .list-of-entities[data-timelabels="true"].timelabels-done .m_meta-property__date {


visibility:visible;
}

972
TMG Channels guide
Structure
Folder structure
Base
Differences
Universal (_universal gateway)
Channel theme
Channel theme creation
Channel theme sync
Styles
Compile styles
Watch styles
Fonts
Channel specific fonts
Iconfonts
Clientlibs
Clientlib definition
Popular cases
Creating new component (without channel variables)
Creating new component (with channel variables)
Adding new differences file for component
Adding js file for component
Removing existing component
Adding version for component

Structure
Folder structure

TMG channels folder structure

clientlibs
??? tmgchannels (new folder for tmg channels themes)
??? _base
??? css (All base css generated while maven build or gulp styles task. Ignored by git.)
??? img
??? ...
??? iconfont (folder with iconfonts in .svg - read more in Iconfont part of this guide)
??? [icon-name-1].svg
??? [icon-name-2].svg
??? ...
??? fonts
??? [font-name-1]
??? [icon-name-1].woff
??? [icon-name-1].ttf
??? ...
??? [font-name-2]
??? ...
??? sass
??? components
??? component.[component-name-1].scss
??? component.[component-name-2].scss
??? ...
??? content-types
??? content-type.[content-type-name-1].scss
??? content-type.[content-type-name-2].scss
??? ...
??? modules
??? module.[module-name-1].scss
??? module.[module-name-2].scss
??? ...
??? pages
??? page.[page-name-1].scss
??? page.[page-name-2].scss
??? ...
??? _iconfont.scss
??? _mixins.scss

973
??? _variables.scss
??? _base.scss
??? ...
??? ...
??? _differences
??? _universal
??? [theme-name-1]
??? [theme-name-2]
??? ...

- channels.json
- components.json
- content-types.json
- themes.json (manual, only contains channels that have unique differences)

On every site two clientlibs with styles will be loaded:

Base clientlib
Your channel theme clientlib.

Base
This is a standard, shared global style (included with every theme/template). Typically include main fonts, basic component layouts and colours. The
majority of all the styling should be here, shared amongst all channels.

This will generate a separate css file included in the head of the page.

Differences
This ghost theme which allow us to edit the styling for common differences between channels easily without having to do the same change to all channels
individually. A channel can of course not inherit from this folder if it wants to go it alone with its own styling.

Universal (_universal gateway)


This theme is auto generated, it combines all the individual component differences into single files which can then be included in other themes. For
example on the portal page (gateway channel), we use the List and Opta widget universal css. New channels are not automatically added to the Universal
css.

To add channel to the Snippet references dropdown so it can be used on the portal page, do the following;

add the name of your channel to themes.json


run `gulp styles`
open the etc/designs/telegraph/core/clientlibs/tmgchannels/.content.xml file and add your new channel to the snippet reference styles (this
allows the editor to select it in AEM cms)

What's included in Universal?

Because of the size of the universal theme, it only includes components that might be used on the Portal page, e.g. lists, to see exactly what is being
included and to include a new components see etc/designs/telegraph/core/clientlibs/tmgchannels/gateway/localcss.txt and core/clientlibs
/tmgchannels/components.json in order for a components universal CSS to be generated, you need to add the component to the components json in
the "_universal" section.

TODO; contrary to the status this ticket still needs doing AEM-4052

NB: To add bespoke libs to a channel css.txt file, create a localcss.txt in the channel folder, this will be appended to the auto generated css.txt.

Channel theme
This is a tiny theme with css files that overrides only the differences that define that channel identity.

Themes are mostly just a 'shell' with their own variables that generate their own css when the gulp task is run.

The sass that they use is actually inherited from a ghost theme called 'common-differences'. Into those sass are injected variables from channel theme.
Typically this is a colour (channel color) a title font (for the hero) and maybe some additional rollover and secondary colors.

This will generate a separate css file included in the head of the page, and is selected in the AEM interface by choosing '[theme-name]' in the 'Template'
drop-down of page properties.

Css.txt files for each channel are generated automatically by gulp depending on tmgchannels/components.json.

974
Channel theme creation
Go to folder cq/core-design/src/main/cq/jcr_root/etc/designs/telegraph/core/clientlibs/tmgchannels with your command line tool. Run command to
use gulp task prepared for syncing themes:

gulp channels:create

This will create a folder containing all the necessary files, and generate the css files for your channel, based on the values you enter when prompted.
These are:

Theme name (e.g. beauty)


Channel color
Channel color2 - hero box hover [ defaults to rgba($channel-color,0.5) ]
Channel color3 - hero box date [ defaults to #fff ]
Channel box background - hero box bg
Channel box text - hero box text [ defaults to #fff ]

If you don't know the values for those with defaults (some of them are required - Theme name, and Channel color) then leave the defaults by leaving blank
and pressing enter.

Next time you build you will see the new sub theme show up in AEM as 'telegraph-[theme-name]'.

Whole this process will generate a separate channel theme which you can select in the AEM interface in the 'Template' drop-down of page properties.

Channel theme sync


Go to folder cq/core-design/src/main/cq/jcr_root/etc/designs/telegraph/core/clientlibs/tmgchannels with your command line tool. Run command to
use gulp task prepared for creating themes:

gulp channels:sync

This gulp task should be used after adding new component to base and differences. It will copy component file from tmgchannels/_differences
/components/component.[component-name].scss to every channel theme (if file exists then task skips it).

Styles
Compile styles
Go to folder cq/core-design/src/main/cq/jcr_root/etc/designs/telegraph/core/clientlibs/tmgchannels with your command line tool. Run command to
use gulp task prepared for compiling (all) channel themes styles:

gulp styles

There are several subtasks that will generate sections of the styles. These are:

gulp styles:base
gulp styles:universal
gulp styles:channels
gulp styles:clientlibs

Watch styles
Go to folder cq/core-design/src/main/cq/jcr_root/etc/designs/telegraph/core/clientlibs/tmgchannels with your command line tool. Run command to
use gulp task prepared for watching (all) channel themes styles:

gulp watch:styles

Fonts

975
Channel specific fonts
A channel often has its own font in the Hero block or as a headline at the top of its channel page. These fonts have to be added manually to your theme
once created. You just need to define the font as a web font in your sub-theme scss (empty on a newly created sub theme). And then define your 'channel-
font' variable as this in your _variables.scss file.

@import "../../sass/variables";
$channel-color : #9c1006;
$channel-color-2 : rgba($channel-color,0.5); // hover
(placeholder color - if no color defined use 0.5 channel color)
$channel-color-3 : #fff; // date highlight
(placeholder color)
$channel-box-background : #efebe7;
$channel-box-text : #222;
$channel-font : "Austin News Deck Semibold",
Georgia, Times, serif;

Iconfonts
Iconfonts are declared inside of base (tmgchannels/_base) not in single channel theme.

To add new icon to iconfonts you have to have properly prepared .svg file with icon. Next you have to copy it into folder: tmgchannels/_base/img/iconfont.
Then run gulp task to compile fonts from .svg to standart font formats (.woff .ttf etc):

gulp iconfont

As the result of gulp task you will get:

font files inside of tmgchannels/_base/fonts/iconfont


file with iconfont variables tmgchannels/_base/sass/_iconfont.scss. This file is imported to variables so you can use those variables inside of your
styles in .scss files using mixin "map-get-value"

Clientlibs
On every site two clientlibs with styles will be loaded:

Base clientlib
Your channel theme clientlib.

The theme and sub themes are generated using AEM Client side libraries (More details here: https://docs.adobe.com/docs/en/cq/5-6-1/developing
/clientlibs.html).

The base theme has only dependencies on video


The themes have dependency on its parent Theme.

Clientlib definition
.content.xml sits inside the folder of a theme or sub-theme. They define the name and dependencies of a theme or sub-theme. These clientlibs use css.txt
and js.txt to compile all their css and js in to one file, typically of the same name as you give the base or channel theme.

Base

<?xml version="1.0" encoding="UTF-8"?>


<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:
jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
sling:resourceType="widgets/clientlib"
categories="[tmgtheme_telegraph,tmg.theme,tmg.telegraph.js.json,tmg.telegraph.css.header]" dependencies=""
embed="[core]" />

Channel theme

<?xml version="1.0" encoding="UTF-8"?>


<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:
jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
sling:resourceType="widgets/clientlib"

976
categories="[tmgtheme_telegraph-theatre,tmg.theme,tmg.telegraph-theatre.js.json,tmg.telegraph-theatre.css.
header]" dependencies="[tmgtheme_telegraph]" embed="" />

Popular cases
Briefly described (step-by-step) most popular cases.

Creating new component (without channel variables)


1. Create new component file in tmgchannels/_base/sass/components/component.<component_name>.sass.
2. Add component into tmgchannels/css.txt file.

Creating new component (with channel variables)


1. Create new component file in tmgchannels/_base/sass/components/component.<component_name>.sass.
2. Add component into tmgchannels/css.txt file (base clientlib).
3. Create new component differences file in tmgchannels/_differences/sass/components/component.<component_name>.sass with specific styles
across all other channels.
4. Add component into tmgchannels/components.json file.
5. Run gulp sync task within tmgchannels directory (it will put proper dependencies in every channel):

gulp sync

Adding new differences file for component


1. Create new component differences file in tmgchannels/_differences/sass/components/component.<component_name>.sass with specific styles
across all other channels.
2. Add component into tmgchannels/_differences/css.txt file.
3. Run gulp sync task within tmgchannels directory (it will put proper dependencies in every channel):
4. Add component into all channels tmgchannels/<channel_name>/css.txt files <- Do not forget to do this manually for ALL channels as
even when creating/updating channels with gulp sync the css.txt file will NOT be updated

gulp sync

Adding js file for component


1. Add new file for your component in core/js/components/component.<component_name>.js.
2. Add component into core/js.txt file.

Removing existing component


1. Remove component from tmgchannels/css.txt file.
2. Remove component file from tmgchannels/_base/sass/components/component.<component_name>.sass.
3. Remove component file from tmgchannels/_differences/sass/components/component.<component_name>.sass
4. Remove component from tmgchannels/components.json file.
5. Remove component files from all channels: tmgchannels/<channel_name>/sass/components/component.<component_name>.sass

Adding version for component


1. Update file with styling of new variant tmgchannels/_base/sass/components/component.<component_name>.sass.
2. Update differences file with styling of new variant tmgchannels/_differences/sass/components/component.<component_name>.sass.
(Note: If there is lot of versions of component - consider creating folder for all of them and dividing into separated files (as it is done with list of
entities component))

977
TMG SASS guidelines
Main goals:

- set the standard for code quality across a codebase


- promote consistency across codebases
- give developers a feeling of familiarity across codebases
- increase productivity

1. SASS architecture

2. SASS guidelines

3. Useful tools

Sources:

our experiences

http://cssguidelin.es/

https://css-tricks.com/sass-style-guide/

http://geek-rocket.de/frontend-development/scss-styleguide-with-bem-oocss-smacss/

https://blog.groupbuddies.com/posts/32-our-css-sass-project-architecture-and-styleguide

978
Custom styles - ClientLib configuration
In order to improve author experience and to lower the number of content issues caused by wrong style version applied we have introduced a new
mechanism that allows us to define available styles for each component. To make that happen we introduced few changes to content.xml file of each
clientlib.

old content.xml

<?xml version="1.0" encoding="UTF-8"?>


<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:
jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
sling:resourceType="widgets/clientlib"
categories="[tmgtheme_cars,tmg.theme,tmg.cars.js.json,tmg.cars.css.header]" dependencies="[core,video]"
embed="[core,video]" />

Fragment of new content.xml

<?xml version="1.0" encoding="UTF-8"?>


<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:
jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
sling:resourceType="widgets/clientlib"
categories="[tmgtheme_telegraph,tmg.theme,tmg.telegraph.js.json,tmg.telegraph.css.header]" dependencies=""
embed="[core]">
<components
jcr:primaryType="nt:unstructured">
<articleBodyHeadline
jcr:primaryType="nt:unstructured"
name="Article Body Headline"
componentResourceType="telegraph/core/commons/components/articleBodyHeadline">
<versions
jcr:primaryType="nt:unstructured">
<version1
jcr:primaryType="nt:unstructured"
cssClass="version-1"
versionName="Version 1"/>
</versions>
</articleBodyHeadline>
...
</components>
</jcr:root>

As you can see now there is additional node components - this node is used to group all components configuration.

Component Configuration

Component Configuration

<articleBodyHeadline
jcr:primaryType="nt:unstructured"
name="Article Body Headline"
componentResourceType="telegraph/core/commons/components/articleBodyHeadline">
<versions
jcr:primaryType="nt:unstructured">
<version1
jcr:primaryType="nt:unstructured"
cssClass="version-1"
versionName="Version 1"/>
</versions>
</articleBodyHeadline>

979
Name of the node for each component need to be unique - the good practice would be to use the component name for it.

For each component now we can define available styles:

cssClass is the class that will be applied on component


versionName is the name of this class that is going to be displayed to user.

Do I need to define this in every clientlib?


He have introduced also inheritance mechanism - so if you are creating subtheme you just need to add property useParentVersion set to true - this way
you will tell cq to use the styles configuration from the parent theme.

sample subtheme configuration

<?xml version="1.0" encoding="UTF-8"?>


<jcr:root xmlns:sling="http://sling.apache.org/jcr/sling/1.0" xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:
jcr="http://www.jcp.org/jcr/1.0"
jcr:primaryType="cq:ClientLibraryFolder"
sling:resourceType="widgets/clientlib"
useParentVersions="true"
categories="[tmgtheme_telegraph-men,tmg.theme,tmg.telegraph-men.js.json,tmg.telegraph-men.css.header]"
dependencies="[tmgtheme_telegraph]" embed="" />

980
Font Scaling
Principles
We have introduced an architecture for controlling Fonts, Font Sizes and Line Heights, which should in most cases should be grouped, and
standardised centrally. So a simple table has been created by the design team with these laid out, covering styles for headlines, body text and 'meta'
content.

List of Font Scales:


https://docs.google.com/spreadsheets/d/1IHNhTfsCFSdvK3yaZA-aVXr4Z5M6m9dCVrGfMzlZyHY/edit#gid=830025606

To apply a font style we no longer specify font-family, line-height and font-size separately. You simply have to specify a font scale name.

Before

.my-headline{
font-family: "Austin News Deck Medium", Georgia, Times, serif;
font-size: 1.8rem;
line-height: 2rem;
}

After

.my-headline{
@include font($headline-med-2);
}

Mixins
For a simple font that is consistent across all breakpoints use font:

@include font($body-bold-1);

For a font that changes accross breakpoints use fonts:

@include fonts((
default: $body-bold-1,
$screen-sm: $body-bold-2
));

THERE IS NO UNIVERSAL HEADLINE FONT

Austin News Deck Medium should only be used on mobile (< $screen-sm)

Austin News Deck Semibold should only be used on larger than mobile (>= $screen-sm)

@include fonts((
default: $headline-med-4,
$screen-sm: $headline-5
));

So this means that either of these would be an antipattern:

981
ANTIPATTERNS

@include font($headline-med-2);

@include font($headline-2);

Headers / Headings
Headings are sometimes called 'headers' and different to headlines. Headings are the title of a list (sometimes optional) that describes the list below it, eg:
'Latest news', or 'Related articles'.

These are standardised using a mixin that is most appropriate:

Primary heading - used for most lists

@include primary-heading();

Secondary heading - used for lower impact lists

@include secondary-heading();

There are also sponsored-heading(), news-heading() and news-subheading() but they are not for general use.

Old font variables vs new variables


$medium1 => $headline-med-1
$medium2 => $headline-med-2
$medium3 => $headline-med-3
$medium4 => $headline-med-4
$medium5 => $headline-med-5
$medium6 => $headline-med-6
$semibold1 => $headline-1
$semibold2 => $headline-2
$semibold3 => $headline-3
$semibold4 => $headline-4
$semibold5 => $headline-5
$semibold6 => $headline-6

982
SASS architecture
Folder structure - Theme
Folder structure - Sub Theme (channel)
File structure
Component
Component versions

Folder structure - Theme


cq/core-design/src/main/cq/jcr_root/etc/designs/telegraph/core/clientlibs/tmgthemes/

[theme-name]
.content.xml (clientlib definition)
css.txt
js.txt
css/
fonts/
img/
inline/
js/
libs
sass/
_inline.scss
_mixins.scss
_variables.scss
_iconfont.scss
[theme-name]-inline.scss
[theme-name].scss
components/
component-1/
component-2/
component-1.scss
(...)
content-types/
pages/
snippets/
_[sub-theme-name] - 1
_[sub-theme-name] - 2
(...)

/sass/_iconfont.scss

List of icon fonts.

/sass/_mixins.scss

List of mixins.

/sass/_variables.scss

Definition for colours, fonts, default sizes, breakpoints.

/components

List of components files, and components directories.

/content-types

983
Modifiers for content type related styles e.g. "comment" where the comment content type modifies the display of the header, list items and byline
components

/components/component-1

List of components variants files. If there are no variants for component - there is not separate directory for component.

/pages

Specific styles for specific pages.

/snippets

Styles for snippets (header, footer etc.)

Folder structure - Sub Theme (channel)


A sub theme is typically used to style a single channel (eg. beauty). It sits within a Theme (described above) and generates its own tiny css file that has a
dependency on its parent Theme, and overrides its for just a few colors and fonts. More is described here : TMG Channels guide

_[sub-theme-name]
.content.xml (clientlib definition)
css.txt
js.txt
css/

fonts/ (optional)
inline/
sass/
_variables.scss
[sub-theme-name]-inline.scss (optional)
[sub-theme-name].scss
components/
component-1/
component-2/
component-1.scss
(...)

File structure
Component
@import "../variables";
@import "../mixins";

.[component-name] {
&__item {
// (...)
}
&__caption {
// (...)
}
&__copyright {
// (...)
}
&--modifier {
// (...)
}

984
.ua-ie & {
// (...)
}
}

Component versions
Component version should be encapsulated in their own namespace and not nested in the default version, to make it easy to scan down version.

@import "../variables";
@import "../mixins";

.[component-version] {
&__item {
// (...)
}
&__caption {
// (...)
}
}

985
SASS guidelines
Syntax and Formatting
Comments
Selectors
Rules order
List of mixins
IE bugs
Images / Icons
Fonts
CSS vendor prefixes
Naming Convention

Syntax and Formatting

title example description

use tabs, no spaces

80 character wide columns

correct
a space before our opening brace ({)
.foo,
.foo--bar,
.baz {
background-color: green;
color: red;
display: block;
}

wrong

.foo, .foo--bar, .baz


{
background-color:green;
color:red;
display:block; }

ditto
properties and values on the same line

ditto
a space after our property–value
delimiting colon (:)

ditto
each declaration on its own new line

ditto
the opening brace ({) on the same line as
our last selector

ditto
our first declaration on a new line after
our opening brace ({)

986
ditto
our closing brace (}) on its own new line

ditto
a trailing semi-colon (;) on our last
declaration

CSS should be written across multiple


multi-line CSS .icon--home { background- lines,
position: 0 0 ; } except in very specific circumstances.
.icon--person { background- Exceptions to this rule should be fairly
position: -1.6px 0 ; } apparent,
.icon--files { background- such as similar rulesets that only carry
position: 0 -1.6px; } one declaration each.
.icon--settings { background-
position: -1.6px -1.6px; }

Comments
title example description

It is rare to regret leaving a comment in code. It is either


be generous with .overlay { helpful or easily ignorable.
comments // modals are 6000, saving messages are
5500, header is 2000
z-index: 5000;
}

We have to use one comments convention.


comments /*------------------------------------*\
convention COMPONENT / VARIANT
TITLE
\*------------------------------------*/

.selector {}

One (1) empty line between closely related rulesets.


meaningful /*------------------------------------*\ Two (2) empty lines between loosely related rulesets.
whitespace #COMPONENT Five (3) empty lines between entirely new sections.
\*------------------------------------*/

.selector {}

/*------------------------------------*\
#ANOTHER-COMPONENT
\*------------------------------------*/

/**
* Comment
*/

.another-selector {}

987
Selectors

title example description

DRY

select what you want


explicitly

write selectors for


reusability

do not nest selectors


unnecessarily

do not qualify selectors


unnecessarily

keep selectors as simple


as possible

not using IDs

avoid !important

The single responsibility principle states that every context (class, function,
use Single Responsibility .box { variable, etc.)
Principle display: block;
padding: 10px; should have a single responsibility,
}
and that responsibility should be entirely encapsulated by the context.

.message {
font-
weight: bold;
border-style:
solid;
border-width:
1px 0;
}

.message-error {
background-
color: #fee;
color: #f00;
}

.message-success {
background-
color: #efe;
color: #0f0;
}

988
use The Open/Closed correct Software entities (classes, modules, functions, etc.) should be open for extension,
Principle but closed for modification.
.box {
display: block;
padding: 10px;
}

.box--large {
padding: 20px;
}

wrong

.box {
display: block;
padding: 10px;
}

.content .box {
padding: 20px;
}

The are many ways in CSS to set color (hex, name, rgb - decimal/percent). We
for colors - only HEX have to use one approach.

If it's possible - use 3-digit version.

We get a set of variables that makes more sense than plain hexadecimal colors
two levels of color // 1st level: color and that are meaningful.
variables $green: #31bf76
$grey: #83929a

// 2nd level:
function
$primary-color:
$green
$secondary-color:
$grey

REMs :
use appropriate CSS units - font-size
- line-height

PX / % :
- others

Both solutions are ok, but we have to one convention.


use 0 for fraction // correct
margin: -0.2px;

// wrong
margin: -.2px

Rules order
title example description

1st level 1. List @extend


.selector {
@extend %module;

989
@include transition(all 0.3s ease); 2. List @include (apart from 'mobile' mixins)
margin: 0;
@include break-by-prop("padding", (
default : 1px,
$screen-sm : 0 3. List "Regular" Styles ('break-by-prop' below property)
));
background: LightCyan;
@include break-by-width($screen-sm) { 4. Mobile mixins ('break-by-width' and 'break-by-range')
background: pink;
}
&:hover {
background: DarkCyan; 5. Nested Pseudo Classes and Pseudo Elements
}
&::before {
content: ""; 6. Additional Classes (versions etc.)
display: block;
}
&.version-1 {
color: red; 7. Nested Selectors
}
> h3 {
@include transform(rotate(90deg));
border-bottom: 1px solid white;
}
}

2nd level Alphabetical order


// Element-Base
.selector {
background: blue;
border: 1px solid red; 1. Box
color: white; margin, padding, display, floats, positions etc.
font-size: 1.6rem;
margin: 1px;
2. Border & Background
padding: 1px;
border, border-radius, background-color, etc.
transform: translate3d(0,0,0);
}
3. Text
color, font-size, text-transform, etc.

4. Other stuff
animations, transforms, etc.

List of mixins

List of TMG custom mixins.

GENERAL

title example output

apply-unless- @include apply-unless-takeover(){ body:not(.cq-wcm-edit):not([style*=background]) &


takeover padding: 0; {
} @content
}

clearfix .section { .section:after {


@include clearfix(); visibility: hidden;
} display: block;

990
font-size: 0;
content: " ";
clear: both;
height: 0;
}

size .section { .section {


@include size(10px, 10px); width: 10px;
} height: 10px;
}

font-size .section { .section {


@include font-size(1rem, font-size: 1rem;
2rem); line-height: 2rem;
} }

text hiding .section { .section {


@include text-hide(); font: 0/0 a;
} color: transparent;
text-shadow: none;
background-color: transparent;
border: 0;
}

clear spacing .section { .section {


@include clear-spacing(); margin: 0;
} padding: 0;
}

MOBILE

title example description

break- .component { /* output: */


by- @include break-by-prop
prop ("font-size", ( .component {
default : 2.3 font-size: 2.3rem;
rem, }
$screen-xs : @media only screen and (min-width: 480px) {
2.2rem, .component {
$screen-sm : 2.1 font-size: 2.2rem;
rem, }
$screen-lg : 1.9rem }
)); @media only screen and (min-width: 730px) {
} .component {
font-size: 2.1rem;
}
}
@media only screen and (min-width: 1328px) {
.component {
font-size: 1.9rem;
}
}

991
break- @include break-by-width
by- ($screen-sm) {
width float: left;
}

break- @include break-by-width


by- ($screen-sm, $screen-lg) {
range float: left;
}

proposed by AEM-2849 Sets an element to be flush to the edge on mobile breakpoint and below by setting
flush- negative gutter width margins on the element it's applied to
on-
@mixin flush-on-mobile(){
mobile
// ATTENTION, this includes
$screen-xs breakpoint
@include break-by-range(0,
$screen-xs + 1){
margin-left: $grid-
gutter-width * -0.5;
margin-right: $grid-
gutter-width * -0.5;
@content
};
}

ICON

title example

map-get-value content: map-get-value($iconfont, social-facebook);

FONT

title example

quick- @include quick-font("Marian Poster Roman", "Marian Web Fonts", "Marian Poster Web-Roman", 400,
font "_ascii");

IE bugs

title example description

http://cssuseragent.org/
by html classes .selector {
.ua-ie & {

992
display: none;
}
}

Images / Icons

Try to avoid images (png, jpg etc.).

Use iconfont as often as possible.

Iconfont setup https://confluence.aws.telegraph.co.uk/pages/viewpage.action?spaceKey=AEM&title=Frontend+Developer+New+Starter+Guide

Fonts
title example description

font: arial 1.2rem #000; IE fails to support rems for this always use
never use font shortcut in css long format.

fonts declaration in theme


/subtheme.scss

@include font-face() @include font-face("Telesans Text


Bold",
font-files(
"telesans-bold/TelesansTextBold.
woff",
"telesans-bold/TelesansTextBold.
ttf",
"telesans-bold/TelesansTextBold.
svg"
),
"telesans-bold/TelesansTextBold.
eot", 800);

CSS vendor prefixes

As it is also mentioned in Rules order - Never Write Vendor Prefixes. Also do not use any mixins to add prefixes.

We have autoprefixer as part of gulp task. It detect all required prefixes (based on browsers table inside of gulpfie) and apply them after generating css file.
The process does not require any custom actions.

Example:

Proper code:

.selector {
transition: all 4s ease;
}

993
Wrong code:

.selector {
-webkit-transition: all 4s ease;
-moz-transition: all 4s ease;
-ms-transition: all 4s ease;
-o-transition: all 4s ease;
transition: all 4s ease;
}

Naming Convention
Example description

Follow basic BEM syntax (Block, Element, Modifier)


.breadcrumbs {
... Keep nesting as flat as possible with single nesting level, never needlessly nest
&__container { declarations
...
}

&__item {
&:nth-child(1){
...
}
&:first-child:after,
&:last-child:after {
...
}
}

&__item--active {
...
}

994
Useful tools
EditorConfig
TMG settings
Configuration for SCSS files in project
Plugins for editors
SCSS lint

EditorConfig
http://editorconfig.org/

EditorConfig helps developers define and maintain consistent coding styles between different editors and IDEs.

TMG settings
.editorconfig (main project directory)

Configuration for SCSS files in project


[*.scss]
indent_style = tab
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
max_line_length = 80

Plugins for editors


Webstorm - No plugin necessary

Sublime Text - http://editorconfig.org/#download

SCSS lint

https://www.npmjs.com/package/gulp-scss-lint

gulp task to lint scss files,


check on 'change'

todo:

todo: prepare settings file based on https://github.com/brigade/scss-lint/blob/master/config/default.yml


add task to gulp

995
Using the HTML embed to inject 'widgets'
See:

Adding content, javascript or CSS to a page using the HTML Embed

996
Password encryption for TCUK website

997
SEO - GoogleBot
Requirement
Requirement 1 - To allow GoogleBot to scrape the content behind paywall and regwall.

Requirement 2 - To follow the guidelines prescribed by Google with respect to paywalled content aka prevent cloaking

Solution Options
Requirement 1

There are two options:

Option 1 - Use Akamai - We can use Akamai's Bot manager service which will identify google bot. The service can set a header parameter which can be
used by the <esi> in the article or gallery

body to display or hide the content. The cons is that we would need to purchase Akamai's Bot manager service.

Option 2 - Identify user-agent - In the frontend code, we can identify the user-agent. If the user-agent happens to be Googlebot, then we can show the
content behind the regwall or paywall to Googlebot. One of the biggest pros of this option is that there is no cost involved. However, the cons remains that
if a user decides to spoof by tweaking their user-agent in the browser, the content will be shown to the user.

This cons has been discussed and the risk has been accepted by the senior management and hence Option 2 is the recommended solution

Option 3 - Use VerifyGoogleBot Service - The frontend html esi code will make a check whether the user-agent contains "google". If it contains then a call
is made to VerifyGoogleBot service with the Client IP as a parameter (still to be developed). The VerifyGoogleBot service then does a reverse lookup and
determines whether the call is indeed made by Google.The service returns the response in esi format and the response determines whether the premium
and reg content needs to be opened for GoogleBot or not.

Requirement 2

There are no solution options for this requirement. We will have to follow Google's guidelines to avoid cloaking in our website and amp pages.

"isAccessibleForFree": "False",

Implemented Solution

Requirement 1 - Option 2 - Identify user-agent

Requirement 2 - Followed Google's guidelines

998
Code Snippet

File Name - ...cq/jcr_root/apps/telegraph/core/commons/renderers/pageRenderer/esiVarsInitialization.html

<esi:assign name=“isGooglebot”>$(HTTP_USER_AGENT) has_i ‘Googlebot’</esi:assign>

File Name - ...main/cq/jcr_root/apps/telegraph/core/commons/renderers/articleRenderer2/bodyContent.html

<esi:choose>
<esi:when test=“$(paywallContent)==‘1’“>
<esi:text>
<meta itemprop=“isAccessibleForFree” content=“false” />
</esi:text>
</esi:when>
</esi:choose>

File Name - .../main/cq/jcr_root/apps/telegraph/core/commons/renderers/galleryRenderer/bodyContent.html

<esi:choose>
<esi:when test=“$(paywallContent)==‘1’“>
<esi:text>
<meta itemprop=“isAccessibleForFree” content=“false” />
</esi:text>
</esi:when>
</esi:choose>

File Name - .../apps/telegraph/core/commons/snippets/meterCheckOpenPremium/meterCheckOpenPremium.html

<esi:choose>
<esi:when test=“$(isPaywallHidden)==‘0’ || $(isRegwallHidden)==‘0’“>
<esi:assign name=“paywallContent”>1</esi:assign>
</esi:when>
</esi:choose>
<esi:choose>
<esi:when test=“$(isGooglebot)==‘1’“>
<esi:assign name=“isPaywallHidden”>1</esi:assign>
<esi:assign name=“isRegwallHidden”>1</esi:assign>
</esi:when>
</esi:choose>

External Documentation

Akamai ESI documentation https://www.akamai.com/uk/en/multimedia/documents/technical-publication/akamai-esi-developers-guide-


technical-publication.pdf

Google's guidelines for paywalled https://developers.google.com/search/docs/data-types/paywalled-content


content

Bots from Google https://support.google.com/webmasters/answer/1061943?hl=en

999
UI components & modules

1000
Excerpt
A guide for understanding role of UI component & module, their naming convention and HTML structure

Time Required 1h

Target Audience UI Developers

Form Guide

Prerequisites
Skills

HTML
CSS
SASS
MVSass
Knowledge of BEM principals welcome

Environments

Expected Outputs
Attendees will

understand the key concepts and know the terminology


understanding idea behind component and differences between module
be able to create style for component variations with modules

Guide Agenda
Defining
component
module
Examples of existing components and modules
Creating css with two different variations that contain one or more modules within

Training Materials
Frontend Developer New Starter Guide
http://bem.info/method/definitions/

1001

You might also like