From 767c0c19d4feab61c134f4e467b1bf604794eedc Mon Sep 17 00:00:00 2001
From: Dani Palou <dani@moodle.com>
Date: Tue, 30 Jul 2019 16:16:45 +0200
Subject: [PATCH] MOBILE-3108 siteplugins: Allow create only title and
 prerendered blocks

---
 .../block/badges/providers/block-handler.ts   |  5 +-
 .../block/blogmenu/providers/block-handler.ts |  5 +-
 .../blogrecent/providers/block-handler.ts     |  5 +-
 .../block/blogtags/providers/block-handler.ts |  5 +-
 .../glossaryrandom/providers/block-handler.ts |  5 +-
 .../newsitems/providers/block-handler.ts      |  5 +-
 .../onlineusers/providers/block-handler.ts    |  5 +-
 .../recentactivity/providers/block-handler.ts |  5 +-
 .../rssclient/providers/block-handler.ts      |  5 +-
 .../block/tags/providers/block-handler.ts     |  5 +-
 .../core-block-pre-rendered.html              |  2 +-
 .../classes/handlers/block-handler.ts         | 27 +++++---
 .../siteplugins/components/block/block.ts     |  5 +-
 .../components/components.module.ts           |  4 ++
 .../core-siteplugins-only-title-block.html    |  3 +
 .../only-title-block/only-title-block.ts      | 69 +++++++++++++++++++
 src/core/siteplugins/providers/helper.ts      | 15 ++--
 17 files changed, 126 insertions(+), 49 deletions(-)
 create mode 100644 src/core/siteplugins/components/only-title-block/core-siteplugins-only-title-block.html
 create mode 100644 src/core/siteplugins/components/only-title-block/only-title-block.ts

diff --git a/src/addon/block/badges/providers/block-handler.ts b/src/addon/block/badges/providers/block-handler.ts
index 9cf9b3622..d6cfb677a 100644
--- a/src/addon/block/badges/providers/block-handler.ts
+++ b/src/addon/block/badges/providers/block-handler.ts
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import { Injectable, Injector } from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
 
 import { CoreBlockHandlerData } from '@core/block/providers/delegate';
 import { CoreBlockPreRenderedComponent } from '@core/block/components/pre-rendered-block/pre-rendered-block';
@@ -27,7 +26,7 @@ export class AddonBlockBadgesHandler extends CoreBlockBaseHandler {
     name = 'AddonBlockBadges';
     blockName = 'badges';
 
-    constructor(private translate: TranslateService) {
+    constructor() {
         super();
     }
 
@@ -44,7 +43,7 @@ export class AddonBlockBadgesHandler extends CoreBlockBaseHandler {
             : CoreBlockHandlerData | Promise<CoreBlockHandlerData> {
 
         return {
-            title: this.translate.instant('addon.block_badges.pluginname'),
+            title: 'addon.block_badges.pluginname',
             class: 'addon-block-badges',
             component: CoreBlockPreRenderedComponent
         };
diff --git a/src/addon/block/blogmenu/providers/block-handler.ts b/src/addon/block/blogmenu/providers/block-handler.ts
index 362b97899..231137b8e 100644
--- a/src/addon/block/blogmenu/providers/block-handler.ts
+++ b/src/addon/block/blogmenu/providers/block-handler.ts
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import { Injectable, Injector } from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
 
 import { CoreBlockHandlerData } from '@core/block/providers/delegate';
 import { CoreBlockPreRenderedComponent } from '@core/block/components/pre-rendered-block/pre-rendered-block';
@@ -27,7 +26,7 @@ export class AddonBlockBlogMenuHandler extends CoreBlockBaseHandler {
     name = 'AddonBlockBlogMenu';
     blockName = 'blog_menu';
 
-    constructor(private translate: TranslateService) {
+    constructor() {
         super();
     }
 
@@ -44,7 +43,7 @@ export class AddonBlockBlogMenuHandler extends CoreBlockBaseHandler {
             : CoreBlockHandlerData | Promise<CoreBlockHandlerData> {
 
         return {
-            title: this.translate.instant('addon.block_blogmenu.pluginname'),
+            title: 'addon.block_blogmenu.pluginname',
             class: 'addon-block-blog-menu',
             component: CoreBlockPreRenderedComponent
         };
diff --git a/src/addon/block/blogrecent/providers/block-handler.ts b/src/addon/block/blogrecent/providers/block-handler.ts
index 69140e96d..55f03cb8e 100644
--- a/src/addon/block/blogrecent/providers/block-handler.ts
+++ b/src/addon/block/blogrecent/providers/block-handler.ts
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import { Injectable, Injector } from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
 
 import { CoreBlockHandlerData } from '@core/block/providers/delegate';
 import { CoreBlockPreRenderedComponent } from '@core/block/components/pre-rendered-block/pre-rendered-block';
@@ -27,7 +26,7 @@ export class AddonBlockBlogRecentHandler extends CoreBlockBaseHandler {
     name = 'AddonBlockBlogRecent';
     blockName = 'blog_recent';
 
-    constructor(private translate: TranslateService) {
+    constructor() {
         super();
     }
 
@@ -44,7 +43,7 @@ export class AddonBlockBlogRecentHandler extends CoreBlockBaseHandler {
             : CoreBlockHandlerData | Promise<CoreBlockHandlerData> {
 
         return {
-            title: this.translate.instant('addon.block_blogrecent.pluginname'),
+            title: 'addon.block_blogrecent.pluginname',
             class: 'addon-block-blog-recent',
             component: CoreBlockPreRenderedComponent
         };
diff --git a/src/addon/block/blogtags/providers/block-handler.ts b/src/addon/block/blogtags/providers/block-handler.ts
index cd6ae4c46..aa2a17495 100644
--- a/src/addon/block/blogtags/providers/block-handler.ts
+++ b/src/addon/block/blogtags/providers/block-handler.ts
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import { Injectable, Injector } from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
 
 import { CoreBlockHandlerData } from '@core/block/providers/delegate';
 import { CoreBlockPreRenderedComponent } from '@core/block/components/pre-rendered-block/pre-rendered-block';
@@ -27,7 +26,7 @@ export class AddonBlockBlogTagsHandler extends CoreBlockBaseHandler {
     name = 'AddonBlockBlogTags';
     blockName = 'blog_tags';
 
-    constructor(private translate: TranslateService) {
+    constructor() {
         super();
     }
 
@@ -44,7 +43,7 @@ export class AddonBlockBlogTagsHandler extends CoreBlockBaseHandler {
             : CoreBlockHandlerData | Promise<CoreBlockHandlerData> {
 
         return {
-            title: this.translate.instant('addon.block_blogtags.pluginname'),
+            title: 'addon.block_blogtags.pluginname',
             class: 'addon-block-blog-tags',
             component: CoreBlockPreRenderedComponent
         };
diff --git a/src/addon/block/glossaryrandom/providers/block-handler.ts b/src/addon/block/glossaryrandom/providers/block-handler.ts
index 48b97b5a1..d639ccb16 100644
--- a/src/addon/block/glossaryrandom/providers/block-handler.ts
+++ b/src/addon/block/glossaryrandom/providers/block-handler.ts
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import { Injectable, Injector } from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
 import { CoreBlockHandlerData } from '@core/block/providers/delegate';
 import { CoreBlockPreRenderedComponent } from '@core/block/components/pre-rendered-block/pre-rendered-block';
 import { CoreBlockBaseHandler } from '@core/block/classes/base-block-handler';
@@ -26,7 +25,7 @@ export class AddonBlockGlossaryRandomHandler extends CoreBlockBaseHandler {
     name = 'AddonBlockGlossaryRandom';
     blockName = 'glossary_random';
 
-    constructor(private translate: TranslateService) {
+    constructor() {
         super();
     }
 
@@ -42,7 +41,7 @@ export class AddonBlockGlossaryRandomHandler extends CoreBlockBaseHandler {
     getDisplayData(injector: Injector, block: any, contextLevel: string, instanceId: number)
             : CoreBlockHandlerData | Promise<CoreBlockHandlerData> {
         return {
-            title: block.contents.title || this.translate.instant('addon.block_glossaryrandom.pluginname'),
+            title: block.contents.title || 'addon.block_glossaryrandom.pluginname',
             class: 'addon-block-glossary-random',
             component: CoreBlockPreRenderedComponent
         };
diff --git a/src/addon/block/newsitems/providers/block-handler.ts b/src/addon/block/newsitems/providers/block-handler.ts
index 9b6c15cb8..c077474d8 100644
--- a/src/addon/block/newsitems/providers/block-handler.ts
+++ b/src/addon/block/newsitems/providers/block-handler.ts
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import { Injectable, Injector } from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
 import { CoreBlockHandlerData } from '@core/block/providers/delegate';
 import { CoreBlockPreRenderedComponent } from '@core/block/components/pre-rendered-block/pre-rendered-block';
 import { CoreBlockBaseHandler } from '@core/block/classes/base-block-handler';
@@ -26,7 +25,7 @@ export class AddonBlockNewsItemsHandler extends CoreBlockBaseHandler {
     name = 'AddonBlockNewsItems';
     blockName = 'news_items';
 
-    constructor(private translate: TranslateService) {
+    constructor() {
         super();
     }
 
@@ -42,7 +41,7 @@ export class AddonBlockNewsItemsHandler extends CoreBlockBaseHandler {
     getDisplayData(injector: Injector, block: any, contextLevel: string, instanceId: number)
             : CoreBlockHandlerData | Promise<CoreBlockHandlerData> {
         return {
-            title: this.translate.instant('addon.block_newsitems.pluginname'),
+            title: 'addon.block_newsitems.pluginname',
             class: 'addon-block-news-items',
             component: CoreBlockPreRenderedComponent
         };
diff --git a/src/addon/block/onlineusers/providers/block-handler.ts b/src/addon/block/onlineusers/providers/block-handler.ts
index 9967ad6f6..353835c83 100644
--- a/src/addon/block/onlineusers/providers/block-handler.ts
+++ b/src/addon/block/onlineusers/providers/block-handler.ts
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import { Injectable, Injector } from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
 import { CoreBlockHandlerData } from '@core/block/providers/delegate';
 import { CoreBlockPreRenderedComponent } from '@core/block/components/pre-rendered-block/pre-rendered-block';
 import { CoreBlockBaseHandler } from '@core/block/classes/base-block-handler';
@@ -26,7 +25,7 @@ export class AddonBlockOnlineUsersHandler extends CoreBlockBaseHandler {
     name = 'AddonBlockOnlineUsers';
     blockName = 'online_users';
 
-    constructor(private translate: TranslateService) {
+    constructor() {
         super();
     }
 
@@ -42,7 +41,7 @@ export class AddonBlockOnlineUsersHandler extends CoreBlockBaseHandler {
     getDisplayData(injector: Injector, block: any, contextLevel: string, instanceId: number)
             : CoreBlockHandlerData | Promise<CoreBlockHandlerData> {
         return {
-            title: this.translate.instant('addon.block_onlineusers.pluginname'),
+            title: 'addon.block_onlineusers.pluginname',
             class: 'addon-block-online-users',
             component: CoreBlockPreRenderedComponent
         };
diff --git a/src/addon/block/recentactivity/providers/block-handler.ts b/src/addon/block/recentactivity/providers/block-handler.ts
index 043acd495..ac69af02b 100644
--- a/src/addon/block/recentactivity/providers/block-handler.ts
+++ b/src/addon/block/recentactivity/providers/block-handler.ts
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import { Injectable, Injector } from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
 
 import { CoreBlockHandlerData } from '@core/block/providers/delegate';
 import { CoreBlockPreRenderedComponent } from '@core/block/components/pre-rendered-block/pre-rendered-block';
@@ -27,7 +26,7 @@ export class AddonBlockRecentActivityHandler extends CoreBlockBaseHandler {
     name = 'AddonBlockRecentActivity';
     blockName = 'recent_activity';
 
-    constructor(private translate: TranslateService) {
+    constructor() {
         super();
     }
 
@@ -44,7 +43,7 @@ export class AddonBlockRecentActivityHandler extends CoreBlockBaseHandler {
             : CoreBlockHandlerData | Promise<CoreBlockHandlerData> {
 
         return {
-            title: this.translate.instant('addon.block_recentactivity.pluginname'),
+            title: 'addon.block_recentactivity.pluginname',
             class: 'addon-block-recent-activity',
             component: CoreBlockPreRenderedComponent
         };
diff --git a/src/addon/block/rssclient/providers/block-handler.ts b/src/addon/block/rssclient/providers/block-handler.ts
index ce26caba4..8976f2182 100644
--- a/src/addon/block/rssclient/providers/block-handler.ts
+++ b/src/addon/block/rssclient/providers/block-handler.ts
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import { Injectable, Injector } from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
 
 import { CoreBlockHandlerData } from '@core/block/providers/delegate';
 import { CoreBlockPreRenderedComponent } from '@core/block/components/pre-rendered-block/pre-rendered-block';
@@ -27,7 +26,7 @@ export class AddonBlockRssClientHandler extends CoreBlockBaseHandler {
     name = 'AddonBlockRssClient';
     blockName = 'rss_client';
 
-    constructor(private translate: TranslateService) {
+    constructor() {
         super();
     }
 
@@ -44,7 +43,7 @@ export class AddonBlockRssClientHandler extends CoreBlockBaseHandler {
             : CoreBlockHandlerData | Promise<CoreBlockHandlerData> {
 
         return {
-            title: block.contents.title || this.translate.instant('addon.block_rssclient.pluginname'),
+            title: block.contents.title || 'addon.block_rssclient.pluginname',
             class: 'addon-block-rss-client',
             component: CoreBlockPreRenderedComponent
         };
diff --git a/src/addon/block/tags/providers/block-handler.ts b/src/addon/block/tags/providers/block-handler.ts
index 749188709..f1c7d4cd8 100644
--- a/src/addon/block/tags/providers/block-handler.ts
+++ b/src/addon/block/tags/providers/block-handler.ts
@@ -13,7 +13,6 @@
 // limitations under the License.
 
 import { Injectable, Injector } from '@angular/core';
-import { TranslateService } from '@ngx-translate/core';
 
 import { CoreBlockHandlerData } from '@core/block/providers/delegate';
 import { CoreBlockPreRenderedComponent } from '@core/block/components/pre-rendered-block/pre-rendered-block';
@@ -27,7 +26,7 @@ export class AddonBlockTagsHandler extends CoreBlockBaseHandler {
     name = 'AddonBlockTags';
     blockName = 'tags';
 
-    constructor(private translate: TranslateService) {
+    constructor() {
         super();
     }
 
@@ -44,7 +43,7 @@ export class AddonBlockTagsHandler extends CoreBlockBaseHandler {
             : CoreBlockHandlerData | Promise<CoreBlockHandlerData> {
 
         return {
-            title: this.translate.instant('addon.block_tags.pluginname'),
+            title: 'addon.block_tags.pluginname',
             class: 'addon-block-tags',
             component: CoreBlockPreRenderedComponent
         };
diff --git a/src/core/block/components/pre-rendered-block/core-block-pre-rendered.html b/src/core/block/components/pre-rendered-block/core-block-pre-rendered.html
index 84780cabb..84cf2ac52 100644
--- a/src/core/block/components/pre-rendered-block/core-block-pre-rendered.html
+++ b/src/core/block/components/pre-rendered-block/core-block-pre-rendered.html
@@ -1,5 +1,5 @@
 <ion-item-divider text-wrap *ngIf="title">
-    <h2><core-format-text [text]="title"></core-format-text></h2>
+    <h2><core-format-text [text]="title | translate"></core-format-text></h2>
 </ion-item-divider>
 <core-loading [hideUntil]="loaded" class="core-loading-center">
     <ion-item *ngIf="block.contents.content" text-wrap class="core-block-content">
diff --git a/src/core/siteplugins/classes/handlers/block-handler.ts b/src/core/siteplugins/classes/handlers/block-handler.ts
index 8ee9dd059..b4734d36e 100644
--- a/src/core/siteplugins/classes/handlers/block-handler.ts
+++ b/src/core/siteplugins/classes/handlers/block-handler.ts
@@ -15,14 +15,17 @@
 import { Injector } from '@angular/core';
 import { CoreSitePluginsBaseHandler } from './base-handler';
 import { CoreBlockHandler, CoreBlockHandlerData } from '@core/block/providers/delegate';
+import { CoreBlockPreRenderedComponent } from '@core/block/components/pre-rendered-block/pre-rendered-block';
 import { CoreSitePluginsBlockComponent } from '@core/siteplugins/components/block/block';
+import { CoreSitePluginsOnlyTitleBlockComponent } from '@core/siteplugins/components/only-title-block/only-title-block';
 
 /**
  * Handler to support a block using a site plugin.
  */
 export class CoreSitePluginsBlockHandler extends CoreSitePluginsBaseHandler implements CoreBlockHandler {
 
-    constructor(name: string, public blockName: string, protected handlerSchema: any, protected initResult: any) {
+    constructor(name: string, public title: string, public blockName: string, protected handlerSchema: any,
+            protected initResult: any) {
         super(name);
     }
 
@@ -38,23 +41,27 @@ export class CoreSitePluginsBlockHandler extends CoreSitePluginsBaseHandler impl
      */
     getDisplayData(injector: Injector, block: any, contextLevel: string, instanceId: number):
             CoreBlockHandlerData | Promise<CoreBlockHandlerData> {
-        let title,
-            className;
-        if (this.handlerSchema.displaydata && this.handlerSchema.displaydata.title) {
-            title = this.handlerSchema.displaydata.title;
-        } else {
-            title = 'plugins.block_' + block.name + '.pluginname';
-        }
+        let className,
+            component;
+
         if (this.handlerSchema.displaydata && this.handlerSchema.displaydata.class) {
             className = this.handlerSchema.displaydata.class;
         } else {
             className = 'block_' + block.name;
         }
 
+        if (this.handlerSchema.displaydata && this.handlerSchema.displaydata.type == 'title') {
+            component = CoreSitePluginsOnlyTitleBlockComponent;
+        } else if (this.handlerSchema.displaydata && this.handlerSchema.displaydata.type == 'prerendered') {
+            component = CoreBlockPreRenderedComponent;
+        } else {
+            component = CoreSitePluginsBlockComponent;
+        }
+
         return {
-            title: title,
+            title: this.title,
             class: className,
-            component: CoreSitePluginsBlockComponent
+            component: component
         };
     }
 }
diff --git a/src/core/siteplugins/components/block/block.ts b/src/core/siteplugins/components/block/block.ts
index 807bceba3..c3375a90f 100644
--- a/src/core/siteplugins/components/block/block.ts
+++ b/src/core/siteplugins/components/block/block.ts
@@ -53,7 +53,10 @@ export class CoreSitePluginsBlockComponent extends CoreBlockBaseComponent implem
             if (handler) {
                 this.component = handler.plugin.component;
                 this.method = handler.handlerSchema.method;
-                this.args = { };
+                this.args = {
+                    contextlevel: this.contextLevel,
+                    instanceid: this.instanceId,
+                };
                 this.initResult = handler.initResult;
             }
         }
diff --git a/src/core/siteplugins/components/components.module.ts b/src/core/siteplugins/components/components.module.ts
index ebc7d03b9..abba3cd8c 100644
--- a/src/core/siteplugins/components/components.module.ts
+++ b/src/core/siteplugins/components/components.module.ts
@@ -30,12 +30,14 @@ import { CoreSitePluginsAssignFeedbackComponent } from './assign-feedback/assign
 import { CoreSitePluginsAssignSubmissionComponent } from './assign-submission/assign-submission';
 import { CoreSitePluginsWorkshopAssessmentStrategyComponent } from './workshop-assessment-strategy/workshop-assessment-strategy';
 import { CoreSitePluginsBlockComponent } from '@core/siteplugins/components/block/block';
+import { CoreSitePluginsOnlyTitleBlockComponent } from '@core/siteplugins/components/only-title-block/only-title-block';
 
 @NgModule({
     declarations: [
         CoreSitePluginsPluginContentComponent,
         CoreSitePluginsModuleIndexComponent,
         CoreSitePluginsBlockComponent,
+        CoreSitePluginsOnlyTitleBlockComponent,
         CoreSitePluginsCourseOptionComponent,
         CoreSitePluginsCourseFormatComponent,
         CoreSitePluginsUserProfileFieldComponent,
@@ -59,6 +61,7 @@ import { CoreSitePluginsBlockComponent } from '@core/siteplugins/components/bloc
         CoreSitePluginsPluginContentComponent,
         CoreSitePluginsModuleIndexComponent,
         CoreSitePluginsBlockComponent,
+        CoreSitePluginsOnlyTitleBlockComponent,
         CoreSitePluginsCourseOptionComponent,
         CoreSitePluginsCourseFormatComponent,
         CoreSitePluginsUserProfileFieldComponent,
@@ -72,6 +75,7 @@ import { CoreSitePluginsBlockComponent } from '@core/siteplugins/components/bloc
     entryComponents: [
         CoreSitePluginsModuleIndexComponent,
         CoreSitePluginsBlockComponent,
+        CoreSitePluginsOnlyTitleBlockComponent,
         CoreSitePluginsCourseOptionComponent,
         CoreSitePluginsCourseFormatComponent,
         CoreSitePluginsUserProfileFieldComponent,
diff --git a/src/core/siteplugins/components/only-title-block/core-siteplugins-only-title-block.html b/src/core/siteplugins/components/only-title-block/core-siteplugins-only-title-block.html
new file mode 100644
index 000000000..287592371
--- /dev/null
+++ b/src/core/siteplugins/components/only-title-block/core-siteplugins-only-title-block.html
@@ -0,0 +1,3 @@
+<ion-item-divider text-wrap detail-push (click)="gotoBlock($event)">
+    <h2>{{ title | translate }}</h2>
+</ion-item-divider>
\ No newline at end of file
diff --git a/src/core/siteplugins/components/only-title-block/only-title-block.ts b/src/core/siteplugins/components/only-title-block/only-title-block.ts
new file mode 100644
index 000000000..b0ceaa456
--- /dev/null
+++ b/src/core/siteplugins/components/only-title-block/only-title-block.ts
@@ -0,0 +1,69 @@
+// (C) Copyright 2015 Martin Dougiamas
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { Injector, OnInit, Component, Optional } from '@angular/core';
+import { NavController } from 'ionic-angular';
+import { CoreBlockBaseComponent } from '@core/block/classes/base-block-component';
+import { CoreSitePluginsProvider } from '../../providers/siteplugins';
+import { CoreBlockDelegate } from '@core/block/providers/delegate';
+import { CoreSplitViewComponent } from '@components/split-view/split-view';
+
+/**
+ * Component to render blocks with only a title and link.
+ */
+@Component({
+    selector: 'core-siteplugins-only-title-block',
+    templateUrl: 'core-siteplugins-only-title-block.html'
+})
+export class CoreSitePluginsOnlyTitleBlockComponent  extends CoreBlockBaseComponent implements OnInit {
+
+    constructor(injector: Injector, protected sitePluginsProvider: CoreSitePluginsProvider,
+            protected blockDelegate: CoreBlockDelegate, private navCtrl: NavController,
+            @Optional() private svComponent: CoreSplitViewComponent) {
+
+        super(injector, 'CoreSitePluginsOnlyTitleBlockComponent');
+    }
+
+    /**
+     * Component being initialized.
+     */
+    ngOnInit(): void {
+        super.ngOnInit();
+
+        this.fetchContentDefaultError = 'Error getting ' + this.block.contents.title + ' data.';
+    }
+
+    /**
+     * Go to the block page.
+     */
+    gotoBlock(): void {
+        const handlerName = this.blockDelegate.getHandlerName(this.block.name);
+        const handler = this.sitePluginsProvider.getSitePluginHandler(handlerName);
+
+        if (handler) {
+            const navCtrl = this.svComponent ? this.svComponent.getMasterNav() : this.navCtrl;
+
+            navCtrl.push('CoreSitePluginsPluginPage', {
+                title: this.title,
+                component: handler.plugin.component,
+                method: handler.handlerSchema.method,
+                initResult: handler.initResult,
+                args: {
+                    contextlevel: this.contextLevel,
+                    instanceid: this.instanceId,
+                },
+            });
+        }
+    }
+}
diff --git a/src/core/siteplugins/providers/helper.ts b/src/core/siteplugins/providers/helper.ts
index 1ca20e3f2..f046cdbb4 100644
--- a/src/core/siteplugins/providers/helper.ts
+++ b/src/core/siteplugins/providers/helper.ts
@@ -661,10 +661,11 @@ export class CoreSitePluginsHelperProvider {
             string | Promise<string> {
 
         const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
-            blockName = (handlerSchema.moodlecomponent || plugin.component).replace('block_', '');
+            blockName = (handlerSchema.moodlecomponent || plugin.component).replace('block_', ''),
+            prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname');
 
         this.blockDelegate.registerHandler(
-            new CoreSitePluginsBlockHandler(uniqueName, blockName, handlerSchema, initResult));
+            new CoreSitePluginsBlockHandler(uniqueName, prefixedTitle, blockName, handlerSchema, initResult));
 
         return uniqueName;
     }
@@ -709,7 +710,7 @@ export class CoreSitePluginsHelperProvider {
 
         // Create and register the handler.
         const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
-            prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title),
+            prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname'),
             handler = new CoreSitePluginsCourseOptionHandler(uniqueName, prefixedTitle, plugin,
                     handlerSchema, initResult, this.sitePluginsProvider, this.utils);
 
@@ -749,7 +750,7 @@ export class CoreSitePluginsHelperProvider {
 
         // Create and register the handler.
         const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
-            prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title);
+            prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname');
 
         this.mainMenuDelegate.registerHandler(
                 new CoreSitePluginsMainMenuHandler(uniqueName, prefixedTitle, plugin, handlerSchema, initResult));
@@ -778,7 +779,7 @@ export class CoreSitePluginsHelperProvider {
 
         // Create and register the handler.
         const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
-            prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title),
+            prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname'),
             processorName = (handlerSchema.moodlecomponent || plugin.component).replace('message_', '');
 
         this.messageOutputDelegate.registerHandler(new CoreSitePluginsMessageOutputHandler(uniqueName, processorName,
@@ -897,7 +898,7 @@ export class CoreSitePluginsHelperProvider {
 
         // Create and register the handler.
         const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
-            prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title);
+            prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname');
 
         this.settingsDelegate.registerHandler(
                 new CoreSitePluginsSettingsHandler(uniqueName, prefixedTitle, plugin, handlerSchema, initResult));
@@ -926,7 +927,7 @@ export class CoreSitePluginsHelperProvider {
 
         // Create and register the handler.
         const uniqueName = this.sitePluginsProvider.getHandlerUniqueName(plugin, handlerName),
-            prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title),
+            prefixedTitle = this.getPrefixedString(plugin.addon, handlerSchema.displaydata.title || 'pluginname'),
             handler = new CoreSitePluginsUserProfileHandler(uniqueName, prefixedTitle, plugin, handlerSchema,
                     initResult, this.sitePluginsProvider, this.utils);