jenkins-bot has submitted this change and it was merged.

Change subject: Beta: Add the Tags section
......................................................................


Beta: Add the Tags section

* Add a wgMFBrowseTags static map of category name to tag name
* Add the MobileFrontend\Browse\TagService and NullTagService classes
* Render the set of tags returned by the service using a Mustache template
* Only enable the feature when `$wgMFIsBrowseEnabled` is truthy

Bug: T94739
Change-Id: I27e78c22c217b3752894bb4ea2bcf3d8bbd9a436
---
M MobileFrontend.php
M i18n/en.json
M i18n/qqq.json
M includes/Resources.php
A includes/browse/NullTagService.php
A includes/browse/TagService.php
M includes/config/Experimental.php
M includes/skins/MinervaTemplate.php
M includes/skins/MinervaTemplateBeta.php
M includes/skins/SkinMinervaBeta.php
A less/browse/tags.less
A templates/browse/tags.mustache
A tests/phpunit/browse/TagServiceTest.php
13 files changed, 271 insertions(+), 2 deletions(-)

Approvals:
  Siebrand: Looks good to me, but someone else must approve
  Jdlrobson: Looks good to me, approved
  Bmansurov: Looks good to me, but someone else must approve
  jenkins-bot: Verified



diff --git a/MobileFrontend.php b/MobileFrontend.php
index eb8acfe..a67efc9 100644
--- a/MobileFrontend.php
+++ b/MobileFrontend.php
@@ -100,6 +100,9 @@
        'UserLoginAndCreateTemplate' => 'skins/UserLoginAndCreateTemplate',
        'UserLoginMobileTemplate' => 'skins/UserLoginMobileTemplate',
        'UserAccountCreateMobileTemplate' => 
'skins/UserAccountCreateMobileTemplate',
+
+       'MobileFrontend\Browse\TagService' => 'browse/TagService',
+       'MobileFrontend\Browse\NullTagService' => 'browse/NullTagService',
 );
 
 foreach ( $autoloadClasses as $className => $classFilename ) {
diff --git a/i18n/en.json b/i18n/en.json
index 4d03f1d..2c2e6bd 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -408,5 +408,6 @@
        "mobile-frontend-days-ago": "$1 {{PLURAL:$1|day|days}} ago",
        "mobile-frontend-months-ago": "$1 {{PLURAL:$1|month|months}} ago",
        "mobile-frontend-years-ago": "$1 {{PLURAL:$1|year|years}} ago",
-       "mobile-frontend-console-recruit": "\\o/ Hey! This is open source 
software and we need volunteers to help us build this thing, make it better and 
fix any bugs that you might be seeing in this JavaScript console!\n\nYou can 
find our backlog @ https://phabricator.wikimedia.org/project/view/67/";
+       "mobile-frontend-console-recruit": "\\o/ Hey! This is open source 
software and we need volunteers to help us build this thing, make it better and 
fix any bugs that you might be seeing in this JavaScript console!\n\nYou can 
find our backlog @ https://phabricator.wikimedia.org/project/view/67/";,
+       "mobile-frontend-browse-tags-header": "Tags"
 }
diff --git a/i18n/qqq.json b/i18n/qqq.json
index 76b6e5e..e32bc86 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -436,5 +436,6 @@
        "mobile-frontend-days-ago": "Expression of duration of time passed in 
days.\nParameter:\n* $1 - number of days that have passed.",
        "mobile-frontend-months-ago": "Expression of duration of time passed in 
months.\nParameter:\n * $1 - number of months that have passed.",
        "mobile-frontend-years-ago": "Expression of duration of time passed in 
years.\nParameter:\n * $1 - number of years that have passed.",
-       "mobile-frontend-console-recruit": "Message that is displayed in the 
JavaScript console aimed at developers in an attempt to recruit volunteers. The 
\\o/ emoticon is a man with his arms in the air with the purpose of drawing 
attention to the message. If this doesn't translate into the destination 
language feel free to omit it or use something more applicable."
+       "mobile-frontend-console-recruit": "Message that is displayed in the 
JavaScript console aimed at developers in an attempt to recruit volunteers. The 
\\o/ emoticon is a man with his arms in the air with the purpose of drawing 
attention to the message. If this doesn't translate into the destination 
language feel free to omit it or use something more applicable.",
+       "mobile-frontend-browse-tags-header": "The header of the \"tags\" 
section of the page, which is part of the Browse experiment."
 }
diff --git a/includes/Resources.php b/includes/Resources.php
index 83cb262..4529f35 100644
--- a/includes/Resources.php
+++ b/includes/Resources.php
@@ -129,6 +129,7 @@
                        'less/pageactions.beta.less',
                        'less/footer.beta.less',
                        'less/content/main.beta.less',
+                       'less/browse/tags.less',
                ),
        ),
        'skins.minerva.beta.images' => $wgMFResourceFileModuleBoilerplate + 
array(
diff --git a/includes/browse/NullTagService.php 
b/includes/browse/NullTagService.php
new file mode 100644
index 0000000..60fbd94
--- /dev/null
+++ b/includes/browse/NullTagService.php
@@ -0,0 +1,16 @@
+<?php
+
+namespace MobileFrontend\Browse;
+
+use Title;
+
+/**
+ * Always returns an empty set of tags for all articles/pages.
+ */
+class NullTagService extends TagService {
+
+       /** @inheritdoc */
+       public function getTags( Title $title ) {
+               return array();
+       }
+}
diff --git a/includes/browse/TagService.php b/includes/browse/TagService.php
new file mode 100644
index 0000000..5ec26be
--- /dev/null
+++ b/includes/browse/TagService.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace MobileFrontend\Browse;
+
+use Title;
+
+/**
+ * Handles the retrieval of tags - in the context of the Browse experiment - 
for pages.
+ */
+class TagService
+{
+       /**
+        * @var array A map of category name to tag name
+        */
+       private $tags;
+
+       /**
+        * @param array $tags A map of category name to tag name
+        */
+       public function __construct( array $tags ) {
+               $this->tags = $tags;
+       }
+
+       /**
+        * Gets the tags associated with the page.
+        *
+        * Only articles in the main namespace can have tags.
+        *
+        * @param Title $title
+        * @return array
+        */
+       public function getTags( Title $title ) {
+               if ( !$title->inNamespace( NS_MAIN ) ) {
+                       return array();
+               }
+
+               $associatedTags = array_intersect_key( $this->tags, 
$title->getParentCategories() );
+
+               return array_values( $associatedTags );
+       }
+}
diff --git a/includes/config/Experimental.php b/includes/config/Experimental.php
index f06a1b8..fdfdb93 100644
--- a/includes/config/Experimental.php
+++ b/includes/config/Experimental.php
@@ -13,3 +13,24 @@
  * Controls whether a message should be logged to the console to attempt to 
recruit volunteers.
  */
 $wgMFEnableJSConsoleRecruitment = false;
+
+// FIXME: Where's the link describing the Browse experiment that I can 
reference
+// when I'm talking about the Browse experiment?
+/**
+ * Whether or not the Browse experiment is enabled.
+ *
+ * @var boolean
+ */
+$wgMFIsBrowseEnabled = false;
+
+/**
+ * A static map of category name to tag name.
+ *
+ * Read this map as follows: if an article is categorised as X, then it is
+ * tagged as Y.
+ *
+ * @var string[]
+ */
+$wgMFBrowseTags = array(
+       // 'Category:English_post-rock_groups' => 'Objectively awesome music',
+);
diff --git a/includes/skins/MinervaTemplate.php 
b/includes/skins/MinervaTemplate.php
index 4ae58cc..5b8e43d 100644
--- a/includes/skins/MinervaTemplate.php
+++ b/includes/skins/MinervaTemplate.php
@@ -277,6 +277,7 @@
                                if ( isset( $data['subject-page'] ) ) {
                                        echo $data['subject-page'];
                                }
+                               $this->renderPostContent( $data );
                                $this->renderSecondaryActions();
                                $this->renderHistoryLinkBottom( $data );
                        ?>
@@ -315,6 +316,14 @@
        }
 
        /**
+        * Renders any content after the main content and before the secondary 
actions.
+        *
+        * @param array $data The data used to build the page
+        */
+       protected function renderPostContent( $data ) {
+       }
+
+       /**
         * Render wrapper for loading content
         * @param array $data Data used to build the page
         */
diff --git a/includes/skins/MinervaTemplateBeta.php 
b/includes/skins/MinervaTemplateBeta.php
index 972bda0..71328e0 100644
--- a/includes/skins/MinervaTemplateBeta.php
+++ b/includes/skins/MinervaTemplateBeta.php
@@ -73,4 +73,37 @@
                        <?php
                }
        }
+
+       /** @inheritdoc */
+       protected function renderPostContent( $data ) {
+               echo $this->renderBrowseTags( $data );
+       }
+
+       /**
+        * Renders the tags assigned to the page as part of the Browse 
experiment.
+        *
+        * @param $data The data used to build the page
+        * @return string The HTML representing the tags section
+        */
+       protected function renderBrowseTags( $data ) {
+               if ( !isset( $data['browse_tags'] ) || !$data['browse_tags'] ) {
+                       return '';
+               }
+
+               // TODO: Create tag entity and view.
+               $tags = array_map( function ( $rawTag ) {
+                       return array(
+                               'msg' => $rawTag,
+                       );
+
+               }, $data['browse_tags'] );
+
+               // FIXME: This should be in MinervaTemplate#getTemplateParser.
+               $templateParser = new TemplateParser( __DIR__ . 
'/../../templates' );
+
+               return $templateParser->processTemplate( 'browse/tags', array(
+                       'headerMsg' => wfMessage( 
'mobile-frontend-browse-tags-header' )->text(),
+                       'tags' => $tags,
+               ) );
+       }
 }
diff --git a/includes/skins/SkinMinervaBeta.php 
b/includes/skins/SkinMinervaBeta.php
index 5c6ab86..0471f39 100644
--- a/includes/skins/SkinMinervaBeta.php
+++ b/includes/skins/SkinMinervaBeta.php
@@ -3,6 +3,9 @@
  * SkinMinervaBeta.php
  */
 
+use MobileFrontend\Browse\TagService;
+use MobileFrontend\Browse\NullTagService;
+
 /**
  * Beta-Implementation of stable class SkinMinerva
  */
@@ -183,4 +186,45 @@
                                Html::closeElement( 'div' ) );
                }
        }
+
+       protected function preparePageContent( QuickTemplate $tpl ) {
+               parent::preparePageContent( $tpl );
+
+               $title = $this->getTitle();
+
+               if ( !$title ) {
+                       return;
+               }
+
+               $browseTags = $this->getBrowseTags( $title );
+               $tpl->set( 'browse_tags', $browseTags );
+       }
+
+       /**
+        * Gets the tags assigned to the page.
+        *
+        * @param Title $title
+        * @return array
+        */
+       private function getBrowseTags( Title $title ) {
+               return $this->getBrowseTagService()
+                       ->getTags( $title );
+       }
+
+       // FIXME: This could be moved to the 
MobileFrontend\Browse\TagServiceFactory class.
+       /**
+        * Gets the service that gets tags assigned to the page.
+        *
+        * @return MobileFrontend\Browse\TagService
+        */
+       private function getBrowseTagService() {
+               $mfConfig = $this->getMFConfig();
+               $tags = $mfConfig->get( 'MFBrowseTags' );
+
+               if ( !$mfConfig->get( 'MFIsBrowseEnabled' ) ) {
+                       return new NullTagService( $tags );
+               }
+
+               return new TagService( $tags );
+       }
 }
diff --git a/less/browse/tags.less b/less/browse/tags.less
new file mode 100644
index 0000000..2294576
--- /dev/null
+++ b/less/browse/tags.less
@@ -0,0 +1,31 @@
+@import "minerva.variables";
+
+.browse-tags {
+       list-style: none;
+
+       .browse-tag {
+               display: inline-block;
+               margin-right: 1em;
+               background-color: @grayLightest;
+               color: @grayMediumDark;
+               padding: 0 .75em;
+               border-radius: .2em;
+
+               &:first-letter {
+                       text-transform: lowercase;
+               }
+
+               a,
+               a:visited {
+                       color: @grayMediumDark;
+               }
+
+               &:last-child {
+                       margin-right: 0;
+               }
+       }
+}
+
+aside {
+       clear: both;
+}
\ No newline at end of file
diff --git a/templates/browse/tags.mustache b/templates/browse/tags.mustache
new file mode 100644
index 0000000..c9ebb46
--- /dev/null
+++ b/templates/browse/tags.mustache
@@ -0,0 +1,8 @@
+<aside>
+       <h4>{{headerMsg}}</h4>
+       <ul class="browse-tags">
+       {{#tags}}
+               <li class="browse-tag"><a href="#">{{msg}}</a></li>
+       {{/tags}}
+       </ul>
+</aside>
diff --git a/tests/phpunit/browse/TagServiceTest.php 
b/tests/phpunit/browse/TagServiceTest.php
new file mode 100644
index 0000000..5895ef5
--- /dev/null
+++ b/tests/phpunit/browse/TagServiceTest.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Tests\MobileFrontend\Browse;
+
+use PHPUnit_Framework_TestCase;
+use MobileFrontend\Browse\TagService;
+use TitleValue;
+use Title;
+
+class StubTitle extends Title {
+       private $mParentCategories;
+
+       public function __construct( $namespace, $parentCategories = array() ) {
+               $this->mNamespace = $namespace;
+               $this->mParentCategories = $parentCategories;
+       }
+
+       public function getParentCategories() {
+               return $this->mParentCategories;
+       }
+}
+
+class TagServiceTest extends PHPUnit_Framework_TestCase {
+       private $tagService;
+
+       public function setUp() {
+               parent::setUp();
+
+               $this->tags = array(
+                       'Category:Castles in Bavaria' => 'Castles in Bavaria',
+                       'Category:Landmarks in Germany' => 'Landmarks in 
Germany',
+               );
+               $this->tagService = new TagService( $this->tags );
+
+       }
+
+       public function 
test_a_title_outside_of_the_main_namespace_shouldnt_have_tags() {
+               $title = new StubTitle( NS_TALK );
+
+               $this->assertEmpty( $this->tagService->getTags( $title ) );
+       }
+
+       public function test_a_title_with_no_categories_shouldnt_have_tags() {
+               $title = new StubTitle( NS_MAIN );
+
+               $this->assertEquals( array(), $this->tagService->getTags( 
$title ) );
+       }
+
+       public function 
test_a_title_with_matching_categories_should_have_tags() {
+               $title = new StubTitle( NS_MAIN, array(
+                       'Category:English post-rock groups' => 'English 
post-rock groups',
+                       'Category:Castles in Bavaria' => 'Castles in Bavaria',
+               ) );
+
+               $this->assertEquals(
+                       array( 'Castles in Bavaria' ),
+                       $this->tagService->getTags( $title )
+               );
+       }
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/204490
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I27e78c22c217b3752894bb4ea2bcf3d8bbd9a436
Gerrit-PatchSet: 10
Gerrit-Project: mediawiki/extensions/MobileFrontend
Gerrit-Branch: master
Gerrit-Owner: Phuedx <[email protected]>
Gerrit-Reviewer: Bmansurov <[email protected]>
Gerrit-Reviewer: Florianschmidtwelzow <[email protected]>
Gerrit-Reviewer: Jdlrobson <[email protected]>
Gerrit-Reviewer: Kaldari <[email protected]>
Gerrit-Reviewer: Phuedx <[email protected]>
Gerrit-Reviewer: Siebrand <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to