Thcipriani has uploaded a new change for review. ( 
https://gerrit.wikimedia.org/r/374879 )

Change subject: Revert to db7507246665e69384c1d92af2aedc62263a5116
......................................................................

Revert to db7507246665e69384c1d92af2aedc62263a5116

Moves function related to display out of PageDisplayHandler

This reverts commit 9e21fdabc8278889ea5f04c62931bdeee1a4db18.
This reverts commit e596fbd97018b2b9c476ec32406e4914d3e583d3
This reverts commit c98a61b1d8517cd6a255f71aaba5ca959bc81002
This reverts commit ab2eaeb9fbd51de38c6e2acf8018430ec7b0a89c
This reverts commit f6ca5179d7eec5ee72c0bd29607e4c0de22b03bc
This reverts commit 24f9d414fe856d21b16f54074d5130e9b9251198
This reverts commit 760d213788061dc8d6dfbc7724dfe4c8ad18ef6a
This reverts commit b48f361d7d606eff5ab48cc2a64c1cae4e794c84.

Bug: T173520
Change-Id: Ia419c028f1578792e1d7dc9c6e14d192d4264f38
(cherry picked from commit db5ee90de0038b528b9448cbd808eb190a66df95)
(cherry picked from commit a7c6487015557c9c2d33633c40f989237f07b46c)
---
M ProofreadPage.body.php
M ProofreadPage.namespaces.php
M composer.json
M extension.json
M i18n/mr.json
M i18n/ug-arab.json
M includes/Context.php
M includes/Pagination/PageList.php
M includes/Pagination/PageNumber.php
M includes/Pagination/Pagination.php
M includes/Parser/PagesTagParser.php
M includes/ProofreadPageInit.php
D includes/index/CustomIndexFieldsParser.php
M includes/index/EditIndexPage.php
M includes/index/IndexContent.php
M includes/index/IndexContentHandler.php
D includes/index/IndexDifferenceEngine.php
M includes/index/ProofreadIndexDbConnector.php
R includes/index/ProofreadIndexEntry.php
M includes/index/ProofreadIndexPage.php
M includes/page/PageContentBuilder.php
M includes/page/PageDifferenceEngine.php
M includes/page/PageDisplayHandler.php
M includes/page/PageLevel.php
M includes/page/ProofreadPageDbConnector.php
M includes/page/ProofreadPagePage.php
M phpcs.xml
M tests/phpunit/ContextTest.php
M tests/phpunit/FileProviderTest.php
M tests/phpunit/Pagination/FilePaginationTest.php
M tests/phpunit/Pagination/PagePaginationTest.php
M tests/phpunit/Pagination/PaginationFactoryTest.php
M tests/phpunit/ProofreadPageInitTest.php
M tests/phpunit/ProofreadPageTestCase.php
D tests/phpunit/index/CustomIndexFieldsParserTest.php
M tests/phpunit/index/IndexContentTest.php
M tests/phpunit/index/IndexRedirectContentTest.php
M tests/phpunit/index/ProofreadIndexPageTest.php
M tests/phpunit/page/PageContentBuilderTest.php
M tests/phpunit/page/PageContentTest.php
M tests/phpunit/page/PageDisplayHandlerTest.php
M tests/phpunit/page/PageLevelTest.php
M tests/phpunit/page/ProofreadPagePageTest.php
43 files changed, 738 insertions(+), 934 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ProofreadPage 
refs/changes/79/374879/1

diff --git a/ProofreadPage.body.php b/ProofreadPage.body.php
index 56b01ed..eda957a 100644
--- a/ProofreadPage.body.php
+++ b/ProofreadPage.body.php
@@ -38,7 +38,7 @@
         *
         * Returns id of Page namespace.
         *
-        * @return int
+        * @return integer
         */
        public static function getPageNamespaceId() {
                return Context::getDefaultContext()->getPageNamespaceId();
@@ -49,7 +49,7 @@
         *
         * Returns id of Index namespace.
         *
-        * @return int
+        * @return integer
         */
        public static function getIndexNamespaceId() {
                return Context::getDefaultContext()->getIndexNamespaceId();
@@ -86,7 +86,7 @@
         *
         * @param Title $title the title page
         * @param string $model the content model for the page
-        * @return bool if we have to continue the research for a content 
handler
+        * @return boolean if we have to continue the research for a content 
handler
         */
        public static function onContentHandlerDefaultModelFor( Title $title, 
&$model ) {
                if ( $title->inNamespace( self::getPageNamespaceId() ) ) {
@@ -104,7 +104,7 @@
         * Set up our custom parser hooks when initializing parser.
         *
         * @param Parser $parser
-        * @return bool hook return value
+        * @return boolean hook return value
         */
        public static function onParserFirstCallInit( Parser $parser ) {
                $parser->setHook(
diff --git a/ProofreadPage.namespaces.php b/ProofreadPage.namespaces.php
index 63216c2..572dcd7 100644
--- a/ProofreadPage.namespaces.php
+++ b/ProofreadPage.namespaces.php
@@ -240,7 +240,7 @@
        'page' => 'ಪುಟ',
        'page_talk' => 'ಪುಟ_ಚರ್ಚೆ',
        'index' => 'ಪರಿವಿಡಿ',
-       'index_talk' => 'ಪರಿವಿಡಿ_ಚರ್ಚೆ'
+       'index_talk' =>  'ಪರಿವಿಡಿ_ಚರ್ಚೆ'
 ];
 
 /** Korean (한국어) */
@@ -264,7 +264,7 @@
        'page' => 'താൾ',
        'page_talk' => 'താളിന്റെ_സംവാദം',
        'index' => 'സൂചിക',
-       'index_talk' => 'സൂചികയുടെ_സംവാദം'
+       'index_talk' =>  'സൂചികയുടെ_സംവാദം'
 ];
 
 /** Marathi (मराठी) */
@@ -272,7 +272,7 @@
        'page' => 'पान',
        'page_talk' => 'पान_चर्चा',
        'index' => 'अनुक्रमणिका',
-       'index_talk' => 'अनुक्रमणिका_चर्चा'
+       'index_talk' =>  'अनुक्रमणिका_चर्चा'
 ];
 
 /** Norwegian (bokmål)‬ (‪norsk (bokmål)‬) */
@@ -320,7 +320,7 @@
        'page' => 'Pagină',
        'page_talk' => 'Discuție_Pagină',
        'index' => 'Index',
-       'index_talk' => 'Discuție_Index'
+       'index_talk' =>  'Discuție_Index'
 ];
 
 /** Russian (русский) */
diff --git a/composer.json b/composer.json
index f9b12ef..c12a316 100644
--- a/composer.json
+++ b/composer.json
@@ -9,7 +9,7 @@
        },
        "require-dev": {
                "jakub-onderka/php-parallel-lint": "0.9.2",
-               "mediawiki/mediawiki-codesniffer": "0.11.0",
+               "mediawiki/mediawiki-codesniffer": "0.10.1",
                "jakub-onderka/php-console-highlighter": "0.3.2"
        },
        "scripts": {
diff --git a/extension.json b/extension.json
index 258a420..2486623 100644
--- a/extension.json
+++ b/extension.json
@@ -47,13 +47,11 @@
                "ProofreadPage\\FileNotFoundException": 
"includes/FileNotFoundException.php",
                "ProofreadPage\\FileProvider": "includes/FileProvider.php",
                "ProofreadPage\\Link": "includes/Link.php",
+               "ProofreadIndexEntry": "includes/index/ProofreadIndexEntry.php",
                "ProofreadIndexPage": "includes/index/ProofreadIndexPage.php",
-               "ProofreadPage\\Index\\CustomIndexField": 
"includes/index/CustomIndexField.php",
-               "ProofreadPage\\Index\\CustomIndexFieldsParser": 
"includes/index/CustomIndexFieldsParser.php",
                "ProofreadPage\\Index\\IndexContent": 
"includes/index/IndexContent.php",
                "ProofreadPage\\Index\\IndexRedirectContent": 
"includes/index/IndexRedirectContent.php",
                "ProofreadPage\\Index\\IndexContentHandler": 
"includes/index/IndexContentHandler.php",
-               "ProofreadPage\\Index\\IndexDifferenceEngine": 
"includes/index/IndexDifferenceEngine.php",
                "ProofreadPage\\Index\\IndexEditAction": 
"includes/index/IndexEditAction.php",
                "ProofreadPage\\Index\\IndexSubmitAction": 
"includes/index/IndexSubmitAction.php",
                "ProofreadPage\\Index\\EditIndexPage": 
"includes/index/EditIndexPage.php",
diff --git a/i18n/mr.json b/i18n/mr.json
index 24892a1..28f9059 100644
--- a/i18n/mr.json
+++ b/i18n/mr.json
@@ -15,7 +15,7 @@
        },
        "nstab-page": "पान",
        "nstab-index": "अनुक्रमणिका",
-       "tooltip-ca-nstab-page": "पुस्तकाचे पान पहा",
+       "tooltip-ca-nstab-page": "पुस्तक पान पहा",
        "tooltip-ca-nstab-index": "पुस्तक निर्देशांक पहा",
        "indexpages": "अनुक्रमणिका पानांची यादी",
        "pageswithoutscans": "छाननी न केलेली पाने",
@@ -33,7 +33,7 @@
        "proofreadpage_nologintext": "पानाच्या प्रामाणिकरणाची   स्थिती 
बदलवण्यासाठी आपणास  [[Special:UserLogin|प्रवेश करणे ]] आवश्यक आहे.",
        "proofreadpage_notallowed": "बदल करण्यास परवानगी नाही",
        "proofreadpage_notallowedtext": "ह्या पानाच्या प्रामाणिकरणाची स्थिती 
बदलवण्याचे आपणास परवानगी नाही",
-       "proofreadpage_dataconfig_badformatted": "डेटा कॉन्फिगरेशनमध्ये गणकदोष",
+       "proofreadpage_dataconfig_badformatted": "डेटा कॉन्फिगरेशनमध्ये दोष",
        "proofreadpage_dataconfig_badformattedtext": "[[Mediawiki:Proofreadpage 
index data config]] हे पान JSON  या योग्य प्रकारात नाही.",
        "proofreadpage_number_expected": "त्रुटि: आकडी संख्या अपेक्षित आहे",
        "proofreadpage_interval_too_large": "त्रुटी: अतिदीर्घ अंतराळ",
@@ -72,7 +72,7 @@
        "proofreadpage_source": "स्रोत",
        "proofreadpage_source_message": "ह्या मजकुरास प्रस्थापित करण्यासाठी 
स्कॅन आवृत्तीचा वापर करण्यात आलेला आहे",
        "right-pagequality": "पृष्ठ गुणवत्ता निशाणास बदला",
-       "right-pagequality-admin": "पृष्ठ गुणवत्ता खूणपताकेसाठी अप्रतिबंधित 
संपादने",
+       "right-pagequality-admin": "पृष्ठ गुणवत्ता ध्वजांकरीता अप्रतिबंधित 
संपादने",
        "proofreadpage-section-tools": "मुद्रितशोधनाची साधने",
        "proofreadpage-group-zoom": "मोठे करा",
        "proofreadpage-group-other": "इतर",
@@ -81,23 +81,23 @@
        "proofreadpage-button-reset-zoom-label": "मूळ आकार",
        "proofreadpage-button-zoom-in-label": "छोटे करा",
        "proofreadpage-button-toggle-layout-label": "उभा/आडवा आराखडा",
-       "proofreadpage-pageinfo-status": "मुद्रितशोधनाची स्थिती",
+       "proofreadpage-pageinfo-status": "प्रूफरीडिंगची स्थिती",
        "proofreadpage-preferences-showheaders-label": "{{ns:page}} या 
नामविश्वात संपादन करताना हेडर आणि फूटर दाखवा",
-       "proofreadpage-preferences-horizontal-layout-label": "{{Ns:page}} 
नामविश्वात संपादन करताना आडवी मांडणी वापरा",
+       "proofreadpage-preferences-horizontal-layout-label": "{{Ns:page}} 
नेमस्पेसमध्ये संपादन करताना आडवे मांडणी वापरा",
        "proofreadpage-indexoai-repositoryName": "पुस्तकाचा मेटाडाटा 
{{SITENAME}} पासून",
-       "proofreadpage-indexoai-eprint-content-text": "मुद्रितशोधित पानाद्वारे 
पुस्तकांचा मेटाडाटा व्यवस्थापित",
+       "proofreadpage-indexoai-eprint-content-text": "प्रूफ्रेडपान द्वारे 
पुस्तके मेटाडेटा व्यवस्थापित",
        "proofreadpage-indexoai-error-schemanotfound": "स्किमा सापडत नाही",
        "proofreadpage-indexoai-error-schemanotfound-text": "$1 स्किमा सापडत 
नाही.",
-       "proofreadpage-disambiguationspage": "Template:नि:संदिग्धी",
-       "proofreadpage-indexquality-alt": "$1 {{PLURAL:$1|पान|पाने}} 
मुल्यांकित, $2 फक्त मुद्रितशोधित {{PLURAL:$2|पान|पाने}} व $3 अ-मुद्रितशोधित 
{{PLURAL:$3|पान|पाने}}",
+       "proofreadpage-disambiguationspage": "Template:disambig",
+       "proofreadpage-indexquality-alt": "$1 प्रमाणित केले 
{{PLURAL:$1|page|pages}}, $2 फक्त प्रूफ्रेड {{PLURAL:$2|page|pages}} आणि $3 
नाही प्रूफ्रेड {{PLURAL:$3|page|pages}}",
        "content-model-proofread-page": "पुस्तकाचे पान",
        "content-model-proofread-index": "पुस्तक निर्देशांक",
-       "apihelp-query+proofread-description": "दिलेल्या पानाची सध्याची 
मुद्रितशोधन स्थितीबाबतची माहिती पुन्हा परत देते.",
-       "apihelp-query+proofreadinfo-example-3": "नामविश्वाबाबतची माहिती परत",
+       "apihelp-query+proofread-description": "सद्या प्रूफ्रेड स्तिथी प्रस्तुत 
पानाची पुन्हा देते",
+       "apihelp-query+proofreadinfo-example-3": "नेमस्पेस माहिती परत करा",
        "proofreadpage-visualeditor-node-pages-inspector-title": "पृष्ठ निवड",
        "proofreadpage-visualeditor-node-pages-inspector-tooltip": "पाने",
        "proofreadpage-visualeditor-node-pages-inspector-description": "$1च्या 
समाप्ती",
-       "proofreadpage-visualeditor-node-pages-inspector-indexselector-yes": 
"होय",
+       "proofreadpage-visualeditor-node-pages-inspector-indexselector-yes": 
"हो",
        "proofreadpage-visualeditor-node-pages-inspector-indexselector-no": 
"नाही",
        "proofreadpage-visualeditor-node-pagequality-inspector-title": 
"मुद्रितशोधनाचा दर्जा",
        "proofreadpage-visualeditor-node-pagequality-inspector-tooltip": 
"मुद्रितशोधनाचा दर्जा"
diff --git a/i18n/ug-arab.json b/i18n/ug-arab.json
index b7c82b0..42bc3d9 100644
--- a/i18n/ug-arab.json
+++ b/i18n/ug-arab.json
@@ -1,8 +1,7 @@
 {
        "@metadata": {
                "authors": [
-                       "Sahran",
-                       "Uzdil"
+                       "Sahran"
                ]
        },
        "proofreadpage_image": "سۈرەت",
@@ -10,12 +9,7 @@
        "proofreadpage_nologin": "تىزىمغا كىرمىدى",
        "proofreadpage_nextpage": "كېيىنكى بەت",
        "proofreadpage_prevpage": "ئالدىنقى بەت",
-       "proofreadpage_quality0_category": "تېكىستسىز",
-       "proofreadpage_quality1_category": "كوررىكتورلانمىدى",
-       "proofreadpage_quality2_category": "مەسىلە بار",
-       "proofreadpage_quality3_category": "ئىملا توغرىلاندى",
-       "proofreadpage_quality4_category": "تەستىقلاندى",
-       "proofreadpage_quality1_message": "بۇ بەت تېخى كوررىكتورلانماپتۇ",
+       "proofreadpage_quality3_category": "تۈزەت",
        "proofreadpage_specialpage_label_orderby": "تەرتىپى:",
        "proofreadpage_specialpage_label_key": "ئىزدە:",
        "proofreadpage_specialpage_label_sortascending": "ئۆسكۈچى تەرتىپ",
diff --git a/includes/Context.php b/includes/Context.php
index 0bbd60d..5393f29 100644
--- a/includes/Context.php
+++ b/includes/Context.php
@@ -2,7 +2,6 @@
 
 namespace ProofreadPage;
 
-use ProofreadPage\Index\CustomIndexFieldsParser;
 use ProofreadPage\Pagination\PaginationFactory;
 use RepoGroup;
 
@@ -33,35 +32,25 @@
        private $fileProvider;
 
        /**
-        * @var CustomIndexFieldsParser
-        */
-       private $customIndexFieldsParser;
-
-       /**
         * @param int $pageNamespaceId
         * @param int $indexNamespaceId
         * @param FileProvider $fileProvider
-        * @param CustomIndexFieldsParser $customIndexFieldsParser
         */
-       public function __construct(
-               $pageNamespaceId, $indexNamespaceId, FileProvider $fileProvider,
-               CustomIndexFieldsParser $customIndexFieldsParser
-       ) {
+       public function __construct( $pageNamespaceId, $indexNamespaceId, 
FileProvider $fileProvider ) {
                $this->pageNamespaceId = $pageNamespaceId;
                $this->indexNamespaceId = $indexNamespaceId;
                $this->fileProvider = $fileProvider;
-               $this->customIndexFieldsParser = $customIndexFieldsParser;
        }
 
        /**
-        * @return int
+        * @return integer
         */
        public function getPageNamespaceId() {
                return $this->pageNamespaceId;
        }
 
        /**
-        * @return int
+        * @return integer
         */
        public function getIndexNamespaceId() {
                return $this->indexNamespaceId;
@@ -82,13 +71,6 @@
        }
 
        /**
-        * @return CustomIndexFieldsParser
-        */
-       public function getCustomIndexFieldsParser() {
-               return $this->customIndexFieldsParser;
-       }
-
-       /**
         * @param bool $purgeFileProvider
         * @return Context
         */
@@ -99,8 +81,7 @@
                        $defaultContext = new self(
                                ProofreadPageInit::getNamespaceId( 'page' ),
                                ProofreadPageInit::getNamespaceId( 'index' ),
-                               new FileProvider( RepoGroup::singleton() ),
-                               new CustomIndexFieldsParser()
+                               new FileProvider( RepoGroup::singleton() )
                        );
                }
                if ( $purgeFileProvider ) {
diff --git a/includes/Pagination/PageList.php b/includes/Pagination/PageList.php
index 0991b00..5bca588 100644
--- a/includes/Pagination/PageList.php
+++ b/includes/Pagination/PageList.php
@@ -29,7 +29,7 @@
        /**
         * Returns the PageNumber for the page number $pageNumber
         *
-        * @param int $pageNumber
+        * @param integer $pageNumber
         * @return PageNumber
         */
        public function getNumber( $pageNumber ) {
@@ -88,8 +88,8 @@
         * Such range may be a single integer or something in the format XXtoYY
         *
         * @param string $range
-        * @param int $number
-        * @return bool
+        * @param integer $number
+        * @return boolean
         */
        protected function numberInRange( $range, $number ) {
                return
diff --git a/includes/Pagination/PageNumber.php 
b/includes/Pagination/PageNumber.php
index f786174..1913518 100644
--- a/includes/Pagination/PageNumber.php
+++ b/includes/Pagination/PageNumber.php
@@ -32,8 +32,8 @@
 
        /**
         * @param string $number the page number
-        * @param string $displayMode the display mode (one of the DISPLAY_* 
constant)
-        * @param bool $isEmpty
+        * @param string  $displayMode the display mode (one of the DISPLAY_* 
constant)
+        * @param boolean $isEmpty
         * @throws InvalidArgumentException
         */
        public function __construct( $number, $displayMode = 
self::DISPLAY_NORMAL, $isEmpty = false ) {
@@ -69,7 +69,7 @@
        }
 
        /**
-        * @return bool
+        * @return boolean
         */
        public function isEmpty() {
                return $this->isEmpty;
diff --git a/includes/Pagination/Pagination.php 
b/includes/Pagination/Pagination.php
index 54da436..6ee77b0 100644
--- a/includes/Pagination/Pagination.php
+++ b/includes/Pagination/Pagination.php
@@ -52,7 +52,7 @@
        /**
         * Returns the page number as it should be displayed from an internal 
page number
         *
-        * @param int $pageNumber
+        * @param integer $pageNumber
         * @return PageNumber
         * @throws OutOfBoundsException
         */
@@ -68,7 +68,7 @@
        /**
         * Returns the page number $pageNumber of the book
         *
-        * @param int $pageNumber page number
+        * @param integer $pageNumber page number
         * @return ProofreadPagePage
         * @throws OutOfBoundsException
         */
@@ -77,7 +77,7 @@
        /**
         * Returns if a page number $pageNumber exits
         *
-        * @param int $pageNumber page number
+        * @param integer $pageNumber page number
         * @return boolean
         */
        abstract protected function pageNumberExists( $pageNumber );
diff --git a/includes/Parser/PagesTagParser.php 
b/includes/Parser/PagesTagParser.php
index e7f5053..90cabe0 100644
--- a/includes/Parser/PagesTagParser.php
+++ b/includes/Parser/PagesTagParser.php
@@ -4,7 +4,6 @@
 
 use OutOfBoundsException;
 use ProofreadIndexPage;
-use ProofreadPage\Context;
 use ProofreadPage\Pagination\FilePagination;
 use ProofreadPageDbConnector;
 use ProofreadPagePage;
@@ -63,7 +62,6 @@
                        return $this->formatError( 'proofreadpage_nosuch_index' 
);
                }
                $indexPage = ProofreadIndexPage::newFromTitle( $indexTitle );
-               $indexContent = $indexPage->getContent();
                $pagination = $this->context->getPaginationFactory()
                        ->getPaginationForIndexPage( $indexPage );
                $language = $this->parser->getTargetLanguage();
@@ -97,7 +95,7 @@
                                // add page selected with $include in pagenums
                                if ( $include ) {
                                        $list = $this->parseNumList( $include );
-                                       if ( $list == null ) {
+                                       if ( $list  == null ) {
                                                return $this->formatError( 
'proofreadpage_invalid_interval' );
                                        }
                                        $pagenums = $list;
@@ -127,7 +125,7 @@
                                // remove excluded pages form $pagenums
                                if ( $exclude ) {
                                        $excluded = $this->parseNumList( 
$exclude );
-                                       if ( $excluded == null ) {
+                                       if ( $excluded  == null ) {
                                                return $this->formatError( 
'proofreadpage_invalid_interval' );
                                        }
                                        $pagenums = array_diff( $pagenums, 
$excluded );
@@ -265,7 +263,7 @@
                        if ( $header == 'toc' ) {
                                $this->parser->getOutput()->is_toc = true;
                        }
-                       $indexLinks = $indexContent->getLinksToNamespace(
+                       $indexLinks = 
$indexPage->getContent()->getLinksToNamespace(
                                NS_MAIN, $indexTitle, true
                        );
                        $pageTitle = $this->parser->getTitle();
@@ -312,8 +310,7 @@
                        if ( isset( $to_pagenum ) ) {
                                $h_out .= "|to=$to_pagenum";
                        }
-                       $attributes = 
$this->context->getCustomIndexFieldsParser()
-                               ->parseCustomIndexFieldsForHeader( 
$indexContent );
+                       $attributes = $indexPage->getIndexEntriesForHeader();
                        foreach ( $attributes as $attribute ) {
                                $key = strtolower( $attribute->getKey() );
                                if ( array_key_exists( $key, $args ) ) {
diff --git a/includes/ProofreadPageInit.php b/includes/ProofreadPageInit.php
index c1b81d9..0f56ea1 100644
--- a/includes/ProofreadPageInit.php
+++ b/includes/ProofreadPageInit.php
@@ -84,7 +84,7 @@
 
        /**
         * Create a namespace and his discussion one
-        * @param int $id the namespace id
+        * @param integer $id the namespace id
         * @param string $key the key of the namespace in the i18n file
         * @return bool false if there is an error, true if not
         */
@@ -158,7 +158,7 @@
         * Warning: It's not the function you search. If you want to know the 
index or page namespace
         * id use ProofreadPage::getIndexNamespaceId() or 
ProofreadPage::getPageNamespaceId()
         * @param string $key the key of the namespace in the i18n file
-        * @return int
+        * @return integer
         */
        public static function getNamespaceId( $key ) {
                global $wgProofreadPageNamespaceIds;
diff --git a/includes/index/CustomIndexFieldsParser.php 
b/includes/index/CustomIndexFieldsParser.php
deleted file mode 100644
index 2a8653f..0000000
--- a/includes/index/CustomIndexFieldsParser.php
+++ /dev/null
@@ -1,236 +0,0 @@
-<?php
-
-namespace ProofreadPage\Index;
-
-use FormatJson;
-use OutOfBoundsException;
-
-/**
- * @licence GNU GPL v2+
- *
- * Returns the custom index entries from an IndexContent
- */
-class CustomIndexFieldsParser {
-
-       private $configuration;
-
-       public function __construct( array $customIndexFieldsConfiguration = 
null ) {
-               $this->configuration = ( $customIndexFieldsConfiguration === 
null )
-                       ? $this->loadCustomIndexFieldsConfiguration()
-                       : $customIndexFieldsConfiguration;
-       }
-
-       /**
-        * @return array the configuration
-        * The configuration is a list of properties like this :
-        * array(
-        *      'ID' => array( //the property id
-        *              'type' => 'string', //the property type (for 
compatibility reasons the values have not
-        *               //to be of this type). Possible values: string, 
number, page
-        *              'size' => 1, //for type = string : the size of the form 
input
-        *              'default' => '', //the default value
-        *              'label' => 'ID', //the label of the property
-        *              'help' => '', //a short help text
-        *              'values' => null, //an array value => label that list 
the possible values
-        *               //(for compatibility reasons the stored values have 
not to be one of these)
-        *              'header' => false, //give the content of this property 
to
-        *               //Mediawiki:Proofreadpage_header_template as template 
parameter
-        *              'hidden' => false //don't show the property in the 
index pages form. Useful for data
-        *               //that have always the same value (as language=en for 
en Wikisource) or are
-        *               //only set at the <pages> tag level.
-        *              )
-        * );
-        *  NB: The values set are the default values
-        */
-       public function getCustomIndexFieldsConfiguration() {
-               return $this->configuration;
-       }
-
-       private function loadCustomIndexFieldsConfiguration() {
-               $data = wfMessage( 'proofreadpage_index_data_config' 
)->inContentLanguage();
-               if ( $data->exists() && $data->plain() != '' ) {
-                       $config = FormatJson::decode( $data->plain(), true );
-                       if ( $config === null ) {
-                               global $wgOut;
-                               $wgOut->showErrorPage(
-                                       'proofreadpage_dataconfig_badformatted',
-                                       
'proofreadpage_dataconfig_badformattedtext'
-                               );
-                               $config = [];
-                       }
-               } else {
-                       $attributes = explode( "\n", wfMessage( 
'proofreadpage_index_attributes' )
-                               ->inContentLanguage()->text() );
-                       $headerAttributes = explode( ' ', wfMessage( 
'proofreadpage_js_attributes' )
-                               ->inContentLanguage()->text() );
-                       $config = [];
-                       foreach ( $attributes as $attribute ) {
-                               $m = explode( '|', $attribute );
-                               $params = [
-                                       'type' => 'string',
-                                       'size' => 1,
-                                       'default' => '',
-                                       'label' => $m[0],
-                                       'help' => '',
-                                       'values' => null,
-                                       'header' => false
-                               ];
-
-                               if ( $m[0] == 'Header' ) {
-                                       $params['default'] = wfMessage( 
'proofreadpage_default_header' )
-                                               ->inContentLanguage()->plain();
-                               }
-                               if ( $m[0] == 'Footer' ) {
-                                       $params['default'] = wfMessage( 
'proofreadpage_default_footer' )
-                                               ->inContentLanguage()->plain();
-                               }
-                               if ( isset( $m[1] ) && $m[1] !== '' ) {
-                                       $params['label'] = $m[1];
-                               }
-                               if ( isset( $m[2] ) ) {
-                                       $params['size'] = intval( $m[2] );
-                               }
-                               $config[$m[0]] = $params;
-                       }
-
-                       foreach ( $headerAttributes as $attribute ) {
-                               if ( isset( $config[$attribute] ) ) {
-                                       $config[$attribute]['header'] = true;
-                               } else {
-                                       $config[$attribute] = [
-                                               'type' => 'string',
-                                               'size' => 1,
-                                               'default' => '',
-                                               'label' => $attribute,
-                                               'values' => null,
-                                               'header' => true,
-                                               'hidden' => true
-                                       ];
-                               }
-                       }
-               }
-
-               if ( !array_key_exists( 'Header', $config ) ) {
-                       $config['Header'] = [
-                               'default' => wfMessage( 
'proofreadpage_default_header' )
-                                       ->inContentLanguage()->plain(),
-                               'header' => true,
-                               'hidden' => true
-                       ];
-               }
-               if ( !array_key_exists( 'Footer', $config ) ) {
-                       $config['Footer'] = [
-                               'default' => wfMessage( 
'proofreadpage_default_footer' )
-                                       ->inContentLanguage()->plain(),
-                               'header' => true,
-                               'hidden' => true
-                       ];
-               }
-
-               return $config;
-       }
-
-       /**
-        * @param IndexContent $content
-        * @return CustomIndexField[]
-        */
-       public function parseCustomIndexFields( IndexContent $content ) {
-               $contentFields = [];
-               foreach ( $content->getFields() as $key => $value ) {
-                       $contentFields[strtolower( $key )] = $value;
-               }
-
-               $values = [];
-               foreach ( $this->configuration as $varName => $property ) {
-                       $key = strtolower( $varName );
-                       if ( array_key_exists( $key, $contentFields ) ) {
-                               $values[$varName] = new CustomIndexField(
-                                       $varName, 
$contentFields[$key]->getNativeData(), $property
-                               );
-                       } else {
-                               $values[$varName] = new CustomIndexField( 
$varName, '', $property );
-                       }
-               }
-               return $values;
-       }
-
-       /*
-        * Return metadata from the index page that have to be given to header 
template.
-        * @return CustomIndexField[]
-        */
-       public function parseCustomIndexFieldsForHeader( IndexContent $content 
) {
-               $entries = $this->parseCustomIndexFields( $content );
-               $headerEntries = [];
-               foreach ( $entries as $entry ) {
-                       if ( $entry->isHeader() ) {
-                               $headerEntries[$entry->getKey()] = $entry;
-                       }
-               }
-               return $headerEntries;
-       }
-
-       /**
-        * Return the index entry with the same name or null if it's not found
-        * Note: the comparison is case insensitive
-        * @return CustomIndexField
-        * @throws OutOfBoundsException
-        */
-       public function parseCustomIndexField( IndexContent $content, 
$fieldName ) {
-               $fieldName = strtolower( $fieldName );
-               $entries = $this->parseCustomIndexFields( $content );
-               foreach ( $entries as $entry ) {
-                       if ( strtolower( $entry->getKey() ) === $fieldName ) {
-                               return $entry;
-                       }
-               }
-               throw new OutOfBoundsException( 'Custom index entry ' . 
$fieldName . ' does not exist.' );
-       }
-
-       /**
-        * Return the value of an entry as wikitext with variable replaced with 
index entries and
-        * $otherParams
-        * Example: if 'header' entry is 'Page of {{title}} number {{pagenum}}' 
with
-        * $otherParams = array( 'pagenum' => 23 )
-        * the function called for 'header' will returns 'Page page my book 
number 23'
-        * @param IndexContent $content
-        * @param $fieldName
-        * @param array $otherParams associative array other possible values to 
replace
-        * @return string the value with variables replaced
-        * @throws OutOfBoundsException
-        */
-       public function 
parseCustomIndexFieldWithVariablesReplacedWithIndexEntries(
-               IndexContent $content, $fieldName, $otherParams
-       ) {
-               $entry = $this->parseCustomIndexField( $content, $fieldName );
-
-               // we can't use the parser here because it replace tags like 
<references /> by strange UIDs
-               $params = $this->parseCustomIndexFieldsAsTemplateParams( 
$content ) + $otherParams;
-               return preg_replace_callback(
-                       '/{\{\{(.*)(\|(.*))?\}\}\}/U',
-                       function ( $matches ) use ( $params ) {
-                               $paramKey = trim( strtolower( $matches[1] ) );
-                               if ( array_key_exists( $paramKey, $params ) ) {
-                                       return $params[$paramKey];
-                               } elseif ( array_key_exists( 3, $matches ) ) {
-                                       return trim( $matches[3] );
-                               } else {
-                                       return $matches[0];
-                               }
-                       },
-                       $entry->getStringValue()
-               );
-       }
-
-       /**
-        * Returns the index entries formatted in order to be transcluded in 
templates
-        * @return string[]
-        */
-       private function parseCustomIndexFieldsAsTemplateParams( IndexContent 
$content ) {
-               $indexEntries = $this->parseCustomIndexFieldsForHeader( 
$content );
-               $params = [];
-               foreach ( $indexEntries as $entry ) {
-                       $params[strtolower( $entry->getKey() )] = 
$entry->getStringValue();
-               }
-               return $params;
-       }
-}
diff --git a/includes/index/EditIndexPage.php b/includes/index/EditIndexPage.php
index 9f0603e..25fb9ea 100644
--- a/includes/index/EditIndexPage.php
+++ b/includes/index/EditIndexPage.php
@@ -2,13 +2,16 @@
 
 namespace ProofreadPage\Index;
 
-use Article;
+use ContentHandler;
 use EditPage;
-use MWException;
+use OOUI\ButtonWidget;
 use OOUI\DropdownInputWidget;
 use OOUI\FieldLayout;
 use OOUI\FieldsetLayout;
+use OOUI\HtmlSnippet;
 use OOUI\TextInputWidget;
+use ProofreadIndexEntry;
+use ProofreadIndexPage;
 use ProofreadPage\Context;
 use Status;
 use WikitextContent;
@@ -17,17 +20,6 @@
  * @licence GNU GPL v2+
  */
 class EditIndexPage extends EditPage {
-
-       /**
-        * @var Context
-        */
-       private $extContext;
-
-       public function __construct( Article $article ) {
-               parent::__construct( $article );
-
-               $this->extContext = Context::getDefaultContext();
-       }
 
        /**
         * @see EditPage::isSectionEditSupported
@@ -55,18 +47,13 @@
                        $inputOptions['readOnly'] = '';
                }
 
-               $content = $this->toEditContent( $this->textbox1 );
-               if ( !( $content instanceof IndexContent ) ) {
-                       throw new MWException( 'EditIndexPage is only able to 
display a form for IndexContent' );
-               }
-
                $fields = [];
                $i = 10;
-               $entries = 
$this->extContext->getCustomIndexFieldsParser()->parseCustomIndexFields( 
$content );
-               foreach ( $entries as $entry ) {
+               /** @var ProofreadIndexEntry $entry */
+               foreach ( $this->getActualContent()->getIndexEntries() as 
$entry ) {
                        $inputOptions['tabIndex'] = $i;
                        if ( !$entry->isHidden() ) {
-                               $fields[] = $this->buildField( $entry, 
$inputOptions );
+                               $fields[] = $this->buildEntry( $entry, 
$inputOptions );
                        }
                        $i++;
                }
@@ -79,15 +66,15 @@
                $out->addModules( 'ext.proofreadpage.index' );
        }
 
-       private function buildField( CustomIndexField $field, $inputOptions ) {
-               $key = $this->getFieldNameForEntry( $field->getKey() );
-               $val = $this->safeUnicodeOutput( $field->getStringValue() );
+       private function buildEntry( ProofreadIndexEntry $entry, $inputOptions 
) {
+               $key = $this->getFieldNameForEntry( $entry->getKey() );
+               $val = $this->safeUnicodeOutput( $entry->getStringValue() );
 
                $inputOptions['name'] = $key;
                $inputOptions['value'] = $val;
                $inputOptions['inputId'] = $key;
 
-               $values = $field->getPossibleValues();
+               $values = $entry->getPossibleValues();
                if ( $values !== null ) {
                        $options = [];
                        foreach ( $values as $data => $label ) {
@@ -100,22 +87,22 @@
                                'options' => $options
                        ] );
                } else {
-                       $inputAttributes['classes'][] = 'prp-input-' . 
$field->getType();
+                       $inputAttributes['classes'][] = 'prp-input-' . 
$entry->getType();
                        $input = new TextInputWidget( $inputOptions + [
-                               'type' => $field->getType() === 'number' && ( 
$val === '' || is_numeric( $val ) )
+                               'type' => $entry->getType() === 'number' && ( 
$val === '' || is_numeric( $val ) )
                                        ? 'number'
                                        : 'text',
-                               'multiline' => $field->getSize() > 1,
-                               'rows' => $field->getSize()
+                               'multiline' => $entry->getSize() > 1,
+                               'rows' => $entry->getSize()
                        ] );
                }
 
                $fieldLayoutArgs = [
-                       'label' => $field->getLabel()
+                       'label' => $entry->getLabel()
                ];
-               if ( $field->getHelp() ) {
+               if ( $entry->getHelp() ) {
                        $fieldLayoutArgs += [
-                               'help' => $field->getHelp(),
+                               'help' => $entry->getHelp(),
                                'infusable' => true,
                                'classes' => [ 'prp-fieldLayout-help' ]
                        ];
@@ -142,12 +129,12 @@
                        return $this->textbox1;
                }
 
-               $config = 
$this->extContext->getCustomIndexFieldsParser()->getCustomIndexFieldsConfiguration();
+               $config = ProofreadIndexPage::getDataConfig();
                $fields = [];
                foreach ( $config as $key => $params ) {
                        $field = $this->getFieldNameForEntry( $key );
                        $value = $this->cleanInputtedContent( 
$this->safeUnicodeInput( $request, $field ) );
-                       $entry = new CustomIndexField( $key, $value, $params );
+                       $entry = new ProofreadIndexEntry( $key, $value, $params 
);
                        if ( !$entry->isHidden() ) {
                                $fields[$entry->getKey()] = new 
WikitextContent( $entry->getStringValue() );
                        }
@@ -196,7 +183,7 @@
                if ( $content instanceof IndexContent ) {
                        // Get list of pages titles
                        $links = $content->getLinksToNamespace(
-                               $this->extContext->getPageNamespaceId(), 
$this->getTitle()
+                               
Context::getDefaultContext()->getPageNamespaceId(), $this->getTitle()
                        );
                        $linksTitle = [];
                        foreach ( $links as $link ) {
@@ -218,4 +205,12 @@
 
                return parent::internalAttemptSave( $result, $bot );
        }
+
+       private function getActualContent() {
+               return new ProofreadIndexPage(
+                       $this->mTitle,
+                       ProofreadIndexPage::getDataConfig(),
+                       $this->toEditContent( $this->textbox1 )
+               );
+       }
 }
diff --git a/includes/index/IndexContent.php b/includes/index/IndexContent.php
index 0e113e4..23f77e4 100644
--- a/includes/index/IndexContent.php
+++ b/includes/index/IndexContent.php
@@ -206,7 +206,7 @@
        /**
         * Returns all links in a given namespace
         *
-        * @param int $namespace the default namespace id
+        * @param integer $namespace the default namespace id
         * @param Title $title the Index: page title
         * @param bool $withPrepossessing apply preprocessor before looking for 
links
         * @return Link[]
diff --git a/includes/index/IndexContentHandler.php 
b/includes/index/IndexContentHandler.php
index 2b1f606..5d18c7f 100644
--- a/includes/index/IndexContentHandler.php
+++ b/includes/index/IndexContentHandler.php
@@ -129,13 +129,6 @@
        }
 
        /**
-        * @see ContentHandler::getDiffEngineClass
-        */
-       protected function getDiffEngineClass() {
-               return '\ProofreadPage\Index\IndexDifferenceEngine';
-       }
-
-       /**
         * @see ContentHandler::makeEmptyContent
         */
        public function makeEmptyContent() {
diff --git a/includes/index/IndexDifferenceEngine.php 
b/includes/index/IndexDifferenceEngine.php
deleted file mode 100644
index ae4488d..0000000
--- a/includes/index/IndexDifferenceEngine.php
+++ /dev/null
@@ -1,98 +0,0 @@
-<?php
-
-namespace ProofreadPage\Index;
-
-use Content;
-use DifferenceEngine;
-use InvalidArgumentException;
-use ProofreadPage\Context;
-use ProofreadPage\DiffFormatterUtils;
-use Title;
-
-/**
- * DifferenceEngine for Index: pages
- */
-class IndexDifferenceEngine extends DifferenceEngine {
-
-       /**
-        * @var DiffFormatterUtils
-        */
-       private $diffFormatterUtils;
-
-       /**
-        * @var CustomIndexFieldsParser
-        */
-       private $customIndexFieldsParser;
-
-       /**
-        * @see DifferenceEngine::__construct
-        */
-       public function __construct(
-               $context = null, $old = 0, $new = 0, $rcid = 0, $refreshCache = 
false, $unhide = false,
-               Context $extContext = null
-       ) {
-               parent::__construct( $context, $old, $new, $rcid, 
$refreshCache, $unhide );
-
-               $this->diffFormatterUtils = new DiffFormatterUtils();
-               $extContext = ( $extContext === null ) ? 
Context::getDefaultContext() : $extContext;
-               $this->customIndexFieldsParser = 
$extContext->getCustomIndexFieldsParser();
-       }
-
-       /**
-        * @see DifferenceEngine::generateContentDiffBody
-        */
-       public function generateContentDiffBody( Content $old, Content $new ) {
-               if ( $old instanceof IndexRedirectContent ) {
-                       if ( $new instanceof IndexRedirectContent ) {
-                               return $this->createRedirectionDiff( 
$old->getRedirectTarget(), $new->getRedirectTarget() );
-                       } elseif ( $new instanceof IndexContent ) {
-                               return $this->createRedirectionDiff( 
$old->getRedirectTarget(), null ) .
-                                       $this->createIndexContentDiff( null, 
$new );
-                       }
-               } elseif ( $old instanceof IndexContent ) {
-                       if ( $new instanceof IndexRedirectContent ) {
-                               return $this->createRedirectionDiff( null, 
$new->getRedirectTarget() ) .
-                                       $this->createIndexContentDiff( $old, 
null );
-                       } elseif ( $new instanceof IndexContent ) {
-                               return $this->createIndexContentDiff( $old, 
$new );
-                       }
-               }
-               throw new InvalidArgumentException(
-                       'IndexDifferenceEngine is only able to output diffs 
between IndexContents'
-               );
-       }
-
-       private function createRedirectionDiff( Title $old = null, Title $new = 
null ) {
-               $old = ( $old === null ) ? '' : $old->getFullText();
-               $new = ( $new === null ) ? '' : $new->getFullText();
-               return $this->createTextDiffOutput( $old, $new,
-                       $this->msg( 'isredirect' )->escaped()
-               );
-       }
-
-       private function createIndexContentDiff( IndexContent $old = null, 
IndexContent $new = null ) {
-               $oldCustomFields = ( $old === null )
-                       ? []
-                       : 
$this->customIndexFieldsParser->parseCustomIndexFields( $old );
-               $newCustomFields = ( $new === null )
-                       ? []
-                       : 
$this->customIndexFieldsParser->parseCustomIndexFields( $new );
-               $diff = '';
-               foreach ( $oldCustomFields as $oldField ) {
-                       $diff .= $this->createTextDiffOutput(
-                               $oldField->getStringValue(),
-                               
$newCustomFields[$oldField->getKey()]->getStringValue(),
-                               $oldField->getLabel()
-                       );
-               }
-               return $diff;
-       }
-
-       private function createTextDiffOutput( $old, $new, $header ) {
-               $diff = parent::generateTextDiffBody( $old, $new );
-               if ( $diff === '' ) {
-                       return '';
-               }
-               return $this->diffFormatterUtils->createHeader( $header ) . 
$diff;
-       }
-}
diff --git a/includes/index/ProofreadIndexDbConnector.php 
b/includes/index/ProofreadIndexDbConnector.php
index 7b452b9..9354771 100644
--- a/includes/index/ProofreadIndexDbConnector.php
+++ b/includes/index/ProofreadIndexDbConnector.php
@@ -43,7 +43,7 @@
 
        /**
         * @param Object $x
-        * @param int $indexId
+        * @param integer $indexId
         * @param WikiPage $article
         */
        public static function replaceIndexById( $x, $indexId, WikiPage 
$article ) {
@@ -110,13 +110,13 @@
        }
 
        /**
-        * @param int $n
-        * @param int $n0
-        * @param int $n1
-        * @param int $n2
-        * @param int $n3
-        * @param int $n4
-        * @param int $indexId
+        * @param integer $n
+        * @param integer $n0
+        * @param integer $n1
+        * @param integer $n2
+        * @param integer $n3
+        * @param integer $n4
+        * @param integer $indexId
         */
        public static function setIndexData( $n, $n0, $n1, $n2, $n3, $n4, 
$indexId ) {
                $dbw = wfGetDB( DB_MASTER );
@@ -138,7 +138,7 @@
 
        /**
         * Remove index data from pr_index table.
-        * @param int $pageId page identifier
+        * @param integer $pageId page identifier
         */
        public static function removeIndexData( $pageId ) {
                $dbw = wfGetDB( DB_MASTER );
@@ -163,7 +163,7 @@
        }
 
        /**
-        * @param int $indexId
+        * @param integer $indexId
         * @return Object
         */
        public static function getIndexDataFromIndexPageId( $indexId ) {
diff --git a/includes/index/CustomIndexField.php 
b/includes/index/ProofreadIndexEntry.php
similarity index 65%
rename from includes/index/CustomIndexField.php
rename to includes/index/ProofreadIndexEntry.php
index 570c8e1..564c035 100644
--- a/includes/index/CustomIndexField.php
+++ b/includes/index/ProofreadIndexEntry.php
@@ -1,13 +1,28 @@
 <?php
-
-namespace ProofreadPage\Index;
+/**
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @file
+ * @ingroup ProofreadPage
+ */
 
 /**
- * @licence GNU GPL v2+
- *
  * An index entry.
  */
-class CustomIndexField {
+class ProofreadIndexEntry {
 
        /**
         * The key of the entry
@@ -69,6 +84,41 @@
        }
 
        /**
+        * Return the values of the entry as string and splitted with the 
delimiter content
+        * @return array string
+        */
+       public function getStringValues() {
+               $value = $this->getStringValue();
+
+               if ( $value === '' ) {
+                       return [];
+               }
+
+               if ( !isset( $this->config['delimiter'] ) || 
!$this->config['delimiter'] ) {
+                       return [ $value ];
+               }
+
+               $delimiters = $this->config['delimiter'];
+               if ( !is_array( $delimiters ) ) {
+                       $delimiters = [ $delimiters ];
+               }
+
+               $values = [ $value ];
+               foreach ( $delimiters as $delimiter ) {
+                       $values2 = [];
+                       foreach ( $values as $val ) {
+                               $values2 = array_merge( $values2, explode( 
$delimiter, $val ) );
+                       }
+                       $values = $values2;
+               }
+
+               foreach ( $values as $id => $value ) {
+                       $values[$id] = trim( $value );
+               }
+               return $values;
+       }
+
+       /**
         * Return the type of the entry
         * @return string
         */
@@ -97,9 +147,7 @@
         * @return int
         */
        public function getSize() {
-               if (
-                       isset( $this->config['size'] ) &&
-                       is_numeric( $this->config['size'] ) &&
+               if ( isset( $this->config['size'] ) && is_numeric( 
$this->config['size'] ) &&
                        $this->config['size'] >= 1
                ) {
                        return (int)$this->config['size'];
diff --git a/includes/index/ProofreadIndexPage.php 
b/includes/index/ProofreadIndexPage.php
index c403b26..f620c83 100644
--- a/includes/index/ProofreadIndexPage.php
+++ b/includes/index/ProofreadIndexPage.php
@@ -19,7 +19,10 @@
  * @ingroup ProofreadPage
  */
 
+use ProofreadPage\Context;
+use ProofreadPage\FileNotFoundException;
 use ProofreadPage\Index\IndexContent;
+use ProofreadPage\Pagination\PageList;
 
 /**
  * An index page
@@ -37,12 +40,19 @@
        protected $content;
 
        /**
+        * @var array configuration array
+        */
+       protected $config = [];
+
+       /**
         * @param Title $title Reference to a Title object.
+        * @param array $config the configuration array (see 
ProofreadIndexPage::getDataConfig)
         * @param IndexContent|null $content content of the page. Warning: only 
done for
         *   EditProofreadIndexPage use.
         */
-       public function __construct( Title $title, IndexContent $content = null 
) {
+       public function __construct( Title $title, $config, IndexContent 
$content = null ) {
                $this->title = $title;
+               $this->config = $config;
                $this->content = $content;
        }
 
@@ -52,7 +62,7 @@
         * @return ProofreadIndexPage
         */
        public static function newFromTitle( Title $title ) {
-               return new self( $title );
+               return new self( $title, self::getDataConfig() );
        }
 
        /**
@@ -67,10 +77,24 @@
         * Check if two ProofreadIndexPage are equals
         *
         * @param ProofreadIndexPage $that
-        * @return bool
+        * @return boolean
         */
        public function equals( ProofreadIndexPage $that ) {
                return $this->title->equals( $that->getTitle() );
+       }
+
+       /**
+        * @deprecated use FileProvider::getForIndexPage
+        *
+        * Return Scan of the book if it exist or false.
+        * @return File|false
+        */
+       public function getImage() {
+               try {
+                       return 
Context::getDefaultContext()->getFileProvider()->getForIndexPage( $this );
+               } catch ( FileNotFoundException $e ) {
+                       return false;
+               }
        }
 
        /**
@@ -95,6 +119,141 @@
        }
 
        /**
+        * @return array the configuration
+        * The configuration is a list of properties like this :
+        * array(
+        *      'ID' => array( //the property id
+        *              'type' => 'string', //the property type (for 
compatibility reasons the values have not
+        *               //to be of this type). Possible values: string, 
number, page
+        *              'size' => 1, //for type = string : the size of the form 
input
+        *              'default' => '', //the default value
+        *              'label' => 'ID', //the label of the property
+        *              'help' => '', //a short help text
+        *              'values' => null, //an array value => label that list 
the possible values
+        *               //(for compatibility reasons the stored values have 
not to be one of these)
+        *              'header' => false, //give the content of this property 
to
+        *               //Mediawiki:Proofreadpage_header_template as template 
parameter
+        *              'hidden' => false //don't show the property in the 
index pages form. Useful for data
+        *               //that have always the same value (as language=en for 
en Wikisource) or are
+        *               //only set at the <pages> tag level.
+        *              )
+        * );
+        *  NB: The values set are the default values
+        */
+       public static function getDataConfig() {
+               static $config = null;
+               if ( $config !== null ) {
+                       return $config;
+               }
+
+               $data = wfMessage( 'proofreadpage_index_data_config' 
)->inContentLanguage();
+               if ( $data->exists() && $data->plain() != '' ) {
+                       $config = FormatJson::decode( $data->plain(), true );
+                       if ( $config === null ) {
+                               global $wgOut;
+                               $wgOut->showErrorPage(
+                                       'proofreadpage_dataconfig_badformatted',
+                                       
'proofreadpage_dataconfig_badformattedtext'
+                               );
+                               $config = [];
+                       }
+               } else {
+                       $attributes = explode( "\n", wfMessage( 
'proofreadpage_index_attributes' )
+                               ->inContentLanguage()->text() );
+                       $headerAttributes = explode( ' ', wfMessage( 
'proofreadpage_js_attributes' )
+                               ->inContentLanguage()->text() );
+                       $config = [];
+                       foreach ( $attributes as $attribute ) {
+                               $m = explode( '|', $attribute );
+                               $params = [
+                                       'type' => 'string',
+                                       'size' => 1,
+                                       'default' => '',
+                                       'label' => $m[0],
+                                       'help' => '',
+                                       'values' => null,
+                                       'header' => false
+                               ];
+
+                               if ( $m[0] == 'Header' ) {
+                                       $params['default'] = wfMessage( 
'proofreadpage_default_header' )
+                                               ->inContentLanguage()->plain();
+                               }
+                               if ( $m[0] == 'Footer' ) {
+                                       $params['default'] = wfMessage( 
'proofreadpage_default_footer' )
+                                               ->inContentLanguage()->plain();
+                               }
+                               if ( isset( $m[1] ) && $m[1] !== '' ) {
+                                       $params['label'] = $m[1];
+                               }
+                               if ( isset( $m[2] ) ) {
+                                       $params['size'] = intval( $m[2] );
+                               }
+                               $config[$m[0]] = $params;
+                       }
+
+                       foreach ( $headerAttributes as $attribute ) {
+                               if ( isset( $config[$attribute] ) ) {
+                                       $config[$attribute]['header'] = true;
+                               } else {
+                                       $config[$attribute] = [
+                                               'type' => 'string',
+                                               'size' => 1,
+                                               'default' => '',
+                                               'label' => $attribute,
+                                               'values' => null,
+                                               'header' => true,
+                                               'hidden' => true
+                                       ];
+                               }
+                       }
+               }
+
+               if ( !array_key_exists( 'Header', $config ) ) {
+                       $config['Header'] = [
+                               'default' => wfMessage( 
'proofreadpage_default_header' )
+                                       ->inContentLanguage()->plain(),
+                               'header' => true,
+                               'hidden' => true
+                       ];
+               }
+               if ( !array_key_exists( 'Footer', $config ) ) {
+                       $config['Footer'] = [
+                               'default' => wfMessage( 
'proofreadpage_default_footer' )
+                                       ->inContentLanguage()->plain(),
+                               'header' => true,
+                               'hidden' => true
+                       ];
+               }
+
+               return $config;
+       }
+
+       /**
+        * Return metadata from an index page.
+        * @return array of ProofreadIndexEntry
+        */
+       public function getIndexEntries() {
+               $contentFields = [];
+               foreach ( $this->getContent()->getFields() as $key => $value ) {
+                       $contentFields[strtolower( $key )] = $value;
+               }
+
+               $values = [];
+               foreach ( $this->config as $varName => $property ) {
+                       $key = strtolower( $varName );
+                       if ( array_key_exists( $key, $contentFields ) ) {
+                               $values[$varName] = new ProofreadIndexEntry(
+                                       $varName, 
$contentFields[$key]->getNativeData(), $property
+                               );
+                       } else {
+                               $values[$varName] = new ProofreadIndexEntry( 
$varName, '', $property );
+                       }
+               }
+               return $values;
+       }
+
+       /**
         * Return mime type of the file linked to the index page
         * @return string|null
         */
@@ -106,4 +265,82 @@
                        return null;
                }
        }
+
+       /*
+        * Return metadata from the index page that have to be given to header 
template.
+        * @return array of ProofreadIndexEntry
+        */
+       public function getIndexEntriesForHeader() {
+               $entries = $this->getIndexEntries();
+               $headerEntries = [];
+               foreach ( $entries as $entry ) {
+                       if ( $entry->isHeader() ) {
+                               $headerEntries[$entry->getKey()] = $entry;
+                       }
+               }
+               return $headerEntries;
+       }
+
+       /*
+        * Return the index entry with the same name or null if it's not found
+        * Note: the comparison is case insensitive
+        * @return ProofreadIndexEntry|null
+        */
+       public function getIndexEntry( $name ) {
+               $name = strtolower( $name );
+               $entries = $this->getIndexEntries();
+               foreach ( $entries as $entry ) {
+                       if ( strtolower( $entry->getKey() ) === $name ) {
+                               return $entry;
+                       }
+               }
+               return null;
+       }
+
+       /**
+        * Return the value of an entry as wikitext with variable replaced with 
index entries and
+        * $otherParams
+        * Example: if 'header' entry is 'Page of {{title}} number {{pagenum}}' 
with
+        * $otherParams = array( 'pagenum' => 23 )
+        * the function called for 'header' will returns 'Page page my book 
number 23'
+        * @param string $name entry name
+        * @param array $otherParams associative array other possible values to 
replace
+        * @return string|null the value with variables replaced or null if the 
entry does not exists
+        */
+       public function getIndexEntryWithVariablesReplacedWithIndexEntries( 
$name, $otherParams ) {
+               $entry = $this->getIndexEntry( $name );
+               if ( $entry === null ) {
+                       return null;
+               }
+
+               // we can't use the parser here because it replace tags like 
<references /> by strange UIDs
+               $params = $this->getIndexEntriesForHeaderAsTemplateParams() + 
$otherParams;
+               return preg_replace_callback(
+                       '/{\{\{(.*)(\|(.*))?\}\}\}/U',
+                       function ( $matches ) use ( $params ) {
+                               $paramKey = trim( strtolower( $matches[1] ) );
+                               if ( array_key_exists( $paramKey, $params ) ) {
+                                       return $params[$paramKey];
+                               } elseif ( array_key_exists( 3, $matches ) ) {
+                                       return trim( $matches[3] );
+                               } else {
+                                       return $matches[0];
+                               }
+                       },
+                       $entry->getStringValue()
+               );
+       }
+
+       /**
+        * Returns the index entries formatted in order to be transcluded in 
templates
+        * @return string[]
+        */
+       protected function getIndexEntriesForHeaderAsTemplateParams() {
+               $indexEntries = $this->getIndexEntriesForHeader();
+               $params = [];
+               foreach ( $indexEntries as $entry ) {
+                       $params[strtolower( $entry->getKey() )] = 
$entry->getStringValue();
+               }
+               return $params;
+       }
 }
diff --git a/includes/page/PageContentBuilder.php 
b/includes/page/PageContentBuilder.php
index 0755e74..e7c0382 100644
--- a/includes/page/PageContentBuilder.php
+++ b/includes/page/PageContentBuilder.php
@@ -58,12 +58,11 @@
                        } catch ( OutOfBoundsException $e ) {
                        } // should not happen
 
-                       $indexFieldsParser = 
$this->context->getCustomIndexFieldsParser();
-                       $header = 
$indexFieldsParser->parseCustomIndexFieldWithVariablesReplacedWithIndexEntries(
-                                       $index->getContent(), 'header', $params
-                               );
-                       $footer = 
$indexFieldsParser->parseCustomIndexFieldWithVariablesReplacedWithIndexEntries(
-                               $index->getContent(), 'footer', $params
+                       $header = 
$index->getIndexEntryWithVariablesReplacedWithIndexEntries(
+                               'header', $params
+                       );
+                       $footer = 
$index->getIndexEntryWithVariablesReplacedWithIndexEntries(
+                               'footer', $params
                        );
                } else {
                        $header = $this->contextSource->msg( 
'proofreadpage_default_header' )
@@ -104,7 +103,7 @@
         * @param string $header
         * @param string $body
         * @param string $footer
-        * @param int $level
+        * @param integer $level
         * @param PageContent $oldContent the old content used as base for the 
new content
         * @return PageContent
         */
diff --git a/includes/page/PageDifferenceEngine.php 
b/includes/page/PageDifferenceEngine.php
index 2f9c77c..3e180e7 100644
--- a/includes/page/PageDifferenceEngine.php
+++ b/includes/page/PageDifferenceEngine.php
@@ -17,7 +17,7 @@
        /**
         * @var DiffFormatterUtils
         */
-       private $diffFormatterUtils;
+       protected $diffFormatterUtils;
 
        /**
         * @see DifferenceEngine::__construct
@@ -56,7 +56,7 @@
         * @param PageLevel $new
         * @return string
         */
-       private function createLevelDiffs( PageLevel $old, PageLevel $new ) {
+       protected function createLevelDiffs( PageLevel $old, PageLevel $new ) {
                if ( $old->equals( $new ) ) {
                        return '';
                }
@@ -82,7 +82,7 @@
         * @param string $headerMsg the message to use for header
         * @return string
         */
-       private function createTextDiffOutput( TextContent $old, TextContent 
$new, $headerMsg ) {
+       protected function createTextDiffOutput( TextContent $old, TextContent 
$new, $headerMsg ) {
                $diff = parent::generateContentDiffBody( $old, $new );
                if ( $diff === '' ) {
                        return '';
diff --git a/includes/page/PageDisplayHandler.php 
b/includes/page/PageDisplayHandler.php
index 9f76a17..b84cc14 100644
--- a/includes/page/PageDisplayHandler.php
+++ b/includes/page/PageDisplayHandler.php
@@ -3,7 +3,6 @@
 namespace ProofreadPage\Page;
 
 use Html;
-use OutOfBoundsException;
 use ProofreadPage\Context;
 use ProofreadPage\FileNotFoundException;
 use ProofreadPagePage;
@@ -41,15 +40,12 @@
        public function getImageWidth( ProofreadPagePage $page ) {
                $index = $page->getIndex();
                if ( $index ) {
-                       try {
-                               $width = 
$this->context->getCustomIndexFieldsParser()->parseCustomIndexField(
-                                       $index->getContent(), 'width'
-                               )->getStringValue();
+                       $width = $index->getIndexEntry( 'width' );
+                       if ( $width !== null ) {
+                               $width = $width->getStringValue();
                                if ( is_numeric( $width ) ) {
                                        return $width;
                                }
-                       } catch ( OutOfBoundsException $e ) {
-                               return self::DEFAULT_IMAGE_WIDTH;
                        }
                }
                return self::DEFAULT_IMAGE_WIDTH;
@@ -63,19 +59,15 @@
         */
        public function getCustomCss( ProofreadPagePage $page ) {
                $index = $page->getIndex();
-               if ( !$index ) {
-                       return '';
+               if ( $index ) {
+                       $css = $index->getIndexEntry( 'css' );
+                       if ( $css !== null ) {
+                               return Sanitizer::escapeHtmlAllowEntities(
+                                       Sanitizer::checkCss( 
$css->getStringValue() )
+                               );
+                       }
                }
-               try {
-                       $css = 
$this->context->getCustomIndexFieldsParser()->parseCustomIndexField(
-                               $index->getContent(), 'css'
-                       );
-                       return Sanitizer::escapeHtmlAllowEntities(
-                               Sanitizer::checkCss( $css->getStringValue() )
-                       );
-               } catch ( OutOfBoundsException $e ) {
-                       return '';
-               }
+               return '';
        }
 
        /**
diff --git a/includes/page/PageLevel.php b/includes/page/PageLevel.php
index 39951ea..d1f5b43 100644
--- a/includes/page/PageLevel.php
+++ b/includes/page/PageLevel.php
@@ -24,7 +24,7 @@
 
        /**
         * Constructor
-        * @param int $level
+        * @param integer $level
         * @param User|null $user
         */
        public function __construct( $level = 1, User $user = null ) {
@@ -34,7 +34,7 @@
 
        /**
         * returns the proofreading level
-        * @return int
+        * @return integer
         */
        public function getLevel() {
                return $this->level;
@@ -51,7 +51,7 @@
        /**
         * Returns if the level is valid
         *
-        * @return bool
+        * @return boolean
         */
        public function isValid() {
                return is_integer( $this->level ) && 0 <= $this->level && 
$this->level <= 4;
@@ -61,7 +61,7 @@
         * Returns if the level is the same as the level $that
         *
         * @param PageLevel $that
-        * @return bool
+        * @return boolean
         */
        public function equals( PageLevel $that = null ) {
                if ( $that === null ) {
@@ -79,7 +79,7 @@
         * Returns if the change of level to level $to is allowed
         *
         * @param PageLevel $to
-        * @return bool
+        * @return boolean
         */
        public function isChangeAllowed( PageLevel $to ) {
                if ( $this->level !== $to->getLevel() && ( $to->getUser() === 
null ||
diff --git a/includes/page/ProofreadPageDbConnector.php 
b/includes/page/ProofreadPageDbConnector.php
index fc89a83..0df99d8 100644
--- a/includes/page/ProofreadPageDbConnector.php
+++ b/includes/page/ProofreadPageDbConnector.php
@@ -59,7 +59,7 @@
        /**
         * @param array $query
         * @param string $cat
-        * @return int
+        * @return integer
         */
        public static function queryCount( $query, $cat ) {
                $dbr = wfGetDB( DB_SLAVE );
@@ -103,7 +103,7 @@
        }
 
        /**
-        * @param int $id
+        * @param integer $id
         * @return string|null
         */
        public static function  getIndexTitleForPageId( $id ) {
@@ -136,7 +136,7 @@
        }
 
        /**
-        * @param int $id
+        * @param integer $id
         * @return integer|null
         */
        public static function countTransclusionFromPageId( $id ) {
diff --git a/includes/page/ProofreadPagePage.php 
b/includes/page/ProofreadPagePage.php
index e179544..1bbce82 100644
--- a/includes/page/ProofreadPagePage.php
+++ b/includes/page/ProofreadPagePage.php
@@ -59,7 +59,7 @@
         * Check if two ProofreadPagePage are equals
         *
         * @param ProofreadPagePage $that
-        * @return bool
+        * @return boolean
         */
        public function equals( ProofreadPagePage $that ) {
                return $this->title->equals( $that->getTitle() );
diff --git a/phpcs.xml b/phpcs.xml
index 46d4aa9..868ce12 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -1,17 +1,9 @@
 <?xml version="1.0"?>
 <ruleset name="ProofreadPage">
        <rule ref="./vendor/mediawiki/mediawiki-codesniffer/MediaWiki">
-               <exclude 
name="MediaWiki.Commenting.FunctionComment.MissingDocumentationProtected" />
-               <exclude 
name="MediaWiki.Commenting.FunctionComment.MissingDocumentationPublic" />
-               <exclude 
name="MediaWiki.Commenting.FunctionComment.MissingParamComment" />
-               <exclude 
name="MediaWiki.Commenting.FunctionComment.MissingParamName" />
-               <exclude 
name="MediaWiki.Commenting.FunctionComment.MissingParamTag" />
-               <exclude 
name="MediaWiki.Commenting.FunctionComment.MissingReturn" />
-               <exclude 
name="MediaWiki.Commenting.FunctionComment.ParamNameNoCaseMatch" />
-               <exclude 
name="MediaWiki.Commenting.FunctionComment.ParamNameNoMatch" />
-               <exclude name="MediaWiki.Commenting.FunctionComment.WrongStyle" 
/>
                <exclude 
name="MediaWiki.ControlStructures.AssignmentInControlStructures.AssignmentInControlStructures"
 />
                <exclude 
name="MediaWiki.WhiteSpace.SpaceBeforeSingleLineComment.NewLineComment"/>
+               <exclude name="MediaWiki.Commenting.FunctionComment"/>
        </rule>
        <rule ref="MediaWiki.NamingConventions.ValidGlobalName">
                <properties>
diff --git a/tests/phpunit/ContextTest.php b/tests/phpunit/ContextTest.php
index 84b2dbd..3aa19b4 100644
--- a/tests/phpunit/ContextTest.php
+++ b/tests/phpunit/ContextTest.php
@@ -2,7 +2,6 @@
 
 namespace ProofreadPage;
 
-use ProofreadPage\Index\CustomIndexFieldsParser;
 use ProofreadPageTestCase;
 
 /**
@@ -12,31 +11,24 @@
 class ContextTest extends ProofreadPageTestCase {
 
        public function testGetPageNamespaceId() {
-               $context = new Context( 42, 44, new FileProviderMock( [] ), new 
CustomIndexFieldsParser() );
+               $context = new Context( 42, 44, new FileProviderMock( [] ) );
                $this->assertEquals( 42, $context->getPageNamespaceId() );
        }
 
        public function testGetIndexNamespaceId() {
-               $context = new Context( 42, 44, new FileProviderMock( [] ), new 
CustomIndexFieldsParser() );
+               $context = new Context( 42, 44, new FileProviderMock( [] ) );
                $this->assertEquals( 44, $context->getIndexNamespaceId() );
        }
 
        public function testGetFileProvider() {
-               $context = new Context( 42, 44, new FileProviderMock( [] ), new 
CustomIndexFieldsParser() );
+               $context = new Context( 42, 44, new FileProviderMock( [] ) );
                $this->assertInstanceOf( '\ProofreadPage\FileProvider', 
$context->getFileProvider() );
        }
 
        public function testGetPaginationFactory() {
-               $context = new Context( 42, 44, new FileProviderMock( [] ), new 
CustomIndexFieldsParser() );
+               $context = new Context( 42, 44, new FileProviderMock( [] ) );
                $this->assertInstanceOf(
                        '\ProofreadPage\Pagination\PaginationFactory', 
$context->getPaginationFactory()
-               );
-       }
-
-       public function testCustomIndexFieldsParser() {
-               $context = new Context( 42, 44, new FileProviderMock( [] ), new 
CustomIndexFieldsParser() );
-               $this->assertInstanceOf(
-                       '\ProofreadPage\Index\CustomIndexFieldsParser', 
$context->getCustomIndexFieldsParser()
                );
        }
 }
diff --git a/tests/phpunit/FileProviderTest.php 
b/tests/phpunit/FileProviderTest.php
index 85d5786..3ebcdf4 100644
--- a/tests/phpunit/FileProviderTest.php
+++ b/tests/phpunit/FileProviderTest.php
@@ -37,7 +37,7 @@
 
                return [
                        [
-                               $this->newIndexPage( 'LoremIpsum.djvu' ),
+                               ProofreadIndexPage::newFromTitle( 
Title::makeTitle( 252, 'LoremIpsum.djvu' ) ),
                                $this->getFileFromName( 'LoremIpsum.djvu' ),
                                $fileProvider
                        ],
@@ -62,11 +62,11 @@
 
                return [
                        [
-                               $this->newIndexPage( 'LoremIpsum2.djvu' ),
+                               ProofreadIndexPage::newFromTitle( 
Title::makeTitle( 252, 'LoremIpsum2.djvu' ) ),
                                $fileProvider
                        ],
                        [
-                               $this->newIndexPage( 'Test' ),
+                               ProofreadIndexPage::newFromTitle( 
Title::makeTitle( 252, 'Test' ) ),
                                $fileProvider
                        ],
                ];
@@ -89,22 +89,24 @@
 
                return [
                        [
-                               $this->newPagePage( 'LoremIpsum.djvu/4' ),
+                               ProofreadPagePage::newFromTitle( 
Title::makeTitle( 250, 'LoremIpsum.djvu/4' ) ),
                                $this->getFileFromName( 'LoremIpsum.djvu' ),
                                $fileProvider
                        ],
                        [
-                               $this->newPagePage( 'LoremIpsum.djvu/djvu/1' ),
+                               ProofreadPagePage::newFromTitle(
+                                       Title::makeTitle( 250, 
'LoremIpsum.djvu/djvu/1' )
+                               ),
                                $this->getFileFromName( 'LoremIpsum.djvu' ),
                                $fileProvider
                        ],
                        [
-                               $this->newPagePage( 'LoremIpsum.djvu' ),
+                               ProofreadPagePage::newFromTitle( 
Title::makeTitle( 250, 'LoremIpsum.djvu' ) ),
                                $this->getFileFromName( 'LoremIpsum.djvu' ),
                                $fileProvider
                        ],
                        [
-                               $this->newPagePage( 'Test.jpg' ),
+                               ProofreadPagePage::newFromTitle( 
Title::makeTitle( 250, 'Test.jpg' ) ),
                                $this->getFileFromName( 'Test.jpg' ),
                                $fileProvider
                        ],
@@ -129,11 +131,11 @@
 
                return [
                        [
-                               $this->newPagePage( 'LoremIpsum2.djvu/4' ),
+                               ProofreadPagePage::newFromTitle( 
Title::makeTitle( 252, 'LoremIpsum2.djvu/4' ) ),
                                $fileProvider
                        ],
                        [
-                               $this->newPagePage( 'Test' ),
+                               ProofreadPagePage::newFromTitle( 
Title::makeTitle( 252, 'Test' ) ),
                                $fileProvider
                        ],
                ];
diff --git a/tests/phpunit/Pagination/FilePaginationTest.php 
b/tests/phpunit/Pagination/FilePaginationTest.php
index dadd19a..b17be7f 100644
--- a/tests/phpunit/Pagination/FilePaginationTest.php
+++ b/tests/phpunit/Pagination/FilePaginationTest.php
@@ -5,6 +5,7 @@
 use InvalidArgumentException;
 use MediaHandler;
 use OutOfBoundsException;
+use ProofreadIndexPageTest;
 use ProofreadPagePage;
 use ProofreadPageTestCase;
 use Title;
@@ -16,7 +17,7 @@
 class FilePaginationTest extends ProofreadPageTestCase {
 
        public function testGetPageNumber() {
-               $index = $this->newIndexPage( 'LoremIpsum.djvu' );
+               $index = ProofreadIndexPageTest::newIndexPage( 
'LoremIpsum.djvu' );
                $pagination = new FilePagination(
                        $index,
                        new PageList( [] ),
@@ -26,7 +27,7 @@
                        $this->getContext()
                );
                $this->assertEquals( 2, $pagination->getPageNumber(
-                       $this->newPagePage( 'LoremIpsum.djvu/2', $index )
+                       new ProofreadPagePage( Title::makeTitle( 250, 
'LoremIpsum.djvu/2' ), $index )
                ) );
        }
 
@@ -41,7 +42,7 @@
        }
 
        public function getPageNumberWithFailureProvider() {
-               $index = $this->newIndexPage( 'LoremIpsum.djvu' );
+               $index = ProofreadIndexPageTest::newIndexPage( 
'LoremIpsum.djvu' );
                $pagination = new FilePagination(
                        $index, new PageList( [] ),
                        
$this->getContext()->getFileProvider()->getFileFromTitle(
@@ -52,15 +53,15 @@
                return [
                        [
                                $pagination,
-                               $this->newPagePage( 'Test.djvu/2' )
+                               new ProofreadPagePage( Title::makeTitle( 250, 
'Test.djvu/2' ) )
                        ],
                        [
                                $pagination,
-                               $this->newPagePage( 'Test2.djvu/2' )
+                               new ProofreadPagePage( Title::makeTitle( 250, 
'Test2.djvu/2' ) )
                        ],
                        [
                                $pagination,
-                               $this->newPagePage( '42.jpg' )
+                               new ProofreadPagePage( Title::makeTitle( 250, 
'42.jpg' ), $index )
                        ],
                ];
        }
@@ -69,7 +70,7 @@
                if ( MediaHandler::getHandler( 'image/vnd.djvu' ) === false ) {
                        $this->markTestSkipped( 'There is no support for DjVu 
files, please enable it.' );
                }
-               $index = $this->newIndexPage( 'LoremIpsum.djvu' );
+               $index = ProofreadIndexPageTest::newIndexPage( 
'LoremIpsum.djvu' );
                $pageNumber = new PageNumber( 'TOC' );
                $pagination = new FilePagination(
                        $index, new PageList( [ '1' => 'TOC' ] ),
@@ -85,7 +86,7 @@
                if ( MediaHandler::getHandler( 'image/vnd.djvu' ) === false ) {
                        $this->markTestSkipped( 'There is no support for DjVu 
files, please enable it.' );
                }
-               $index = $this->newIndexPage( 'LoremIpsum.djvu' );
+               $index = ProofreadIndexPageTest::newIndexPage( 
'LoremIpsum.djvu' );
                $pageNumber = new PageNumber( 1 );
                $pagination = new FilePagination(
                        $index, new PageList( [] ),
@@ -101,7 +102,7 @@
         * @expectedException OutOfBoundsException
         */
        public function testGetDisplayedPageNumberWithFailure() {
-               $index = $this->newIndexPage();
+               $index = ProofreadIndexPageTest::newIndexPage();
                $pagination = new PagePagination( $index, [], [] );
                $pagination->getDisplayedPageNumber( 3 );
        }
@@ -110,7 +111,7 @@
                if ( MediaHandler::getHandler( 'image/vnd.djvu' ) === false ) {
                        $this->markTestSkipped( 'There is no support for DjVu 
files, please enable it.' );
                }
-               $index = $this->newIndexPage( 'LoremIpsum.djvu' );
+               $index = ProofreadIndexPageTest::newIndexPage( 
'LoremIpsum.djvu' );
                $pagination = new FilePagination(
                        $index, new PageList( [] ),
                        
$this->getContext()->getFileProvider()->getFileFromTitle(
@@ -125,8 +126,8 @@
                if ( MediaHandler::getHandler( 'image/vnd.djvu' ) === false ) {
                        $this->markTestSkipped( 'There is no support for DjVu 
files, please enable it.' );
                }
-               $index = $this->newIndexPage( 'LoremIpsum.djvu' );
-               $page = $this->newPagePage( 'LoremIpsum.djvu/2', $index );
+               $index = ProofreadIndexPageTest::newIndexPage( 
'LoremIpsum.djvu' );
+               $page = new ProofreadPagePage( Title::makeTitle( 250, 
'LoremIpsum.djvu/2' ), $index );
                $pagination = new FilePagination(
                        $index, new PageList( [] ),
                        
$this->getContext()->getFileProvider()->getFileFromTitle(
@@ -144,7 +145,7 @@
                if ( MediaHandler::getHandler( 'image/vnd.djvu' ) === false ) {
                        $this->markTestSkipped( 'There is no support for DjVu 
files, please enable it.' );
                }
-               $index = $this->newIndexPage( 'LoremIpsum.djvu' );
+               $index = ProofreadIndexPageTest::newIndexPage( 
'LoremIpsum.djvu' );
                $pagination = new FilePagination(
                        $index, new PageList( [] ),
                        
$this->getContext()->getFileProvider()->getFileFromTitle(
@@ -159,9 +160,9 @@
                if ( MediaHandler::getHandler( 'image/vnd.djvu' ) === false ) {
                        $this->markTestSkipped( 'There is no support for DjVu 
files, please enable it.' );
                }
-               $index = $this->newIndexPage( 'LoremIpsum.djvu' );
-               $page1 = $this->newPagePage( 'LoremIpsum.djvu/1', $index );
-               $page2 = $this->newPagePage( 'LoremIpsum.djvu/2', $index );
+               $index = ProofreadIndexPageTest::newIndexPage( 
'LoremIpsum.djvu' );
+               $page1 = new ProofreadPagePage( Title::makeTitle( 250, 
'LoremIpsum.djvu/1' ), $index );
+               $page2 = new ProofreadPagePage( Title::makeTitle( 250, 
'LoremIpsum.djvu/2' ), $index );
                $pagination = new FilePagination(
                        $index, new PageList( [] ),
                        
$this->getContext()->getFileProvider()->getFileFromTitle(
diff --git a/tests/phpunit/Pagination/PagePaginationTest.php 
b/tests/phpunit/Pagination/PagePaginationTest.php
index 677e8cc..5e46275 100644
--- a/tests/phpunit/Pagination/PagePaginationTest.php
+++ b/tests/phpunit/Pagination/PagePaginationTest.php
@@ -4,6 +4,7 @@
 
 use InvalidArgumentException;
 use OutOfBoundsException;
+use ProofreadIndexPageTest;
 use ProofreadPagePage;
 use ProofreadPageTestCase;
 use Title;
@@ -15,7 +16,7 @@
 class PagePaginationTest extends ProofreadPageTestCase {
 
        public function testGetPageNumber() {
-               $index = $this->newIndexPage();
+               $index = ProofreadIndexPageTest::newIndexPage();
                $page = new ProofreadPagePage( Title::newFromText( 'Page:Test 
2.tiff' ), $index );
                $pagination = new PagePagination(
                        $index,
@@ -39,7 +40,7 @@
         * @expectedException InvalidArgumentException
         */
        public function testGetPageNumberWithFailure() {
-               $index = $this->newIndexPage();
+               $index = ProofreadIndexPageTest::newIndexPage();
                $pagination = new PagePagination( $index, [], [] );
                $pagination->getPageNumber(
                        new ProofreadPagePage( Title::newFromText( 'Page:Test 
2.tiff' ), $index )
@@ -47,7 +48,7 @@
        }
 
        public function testGetDisplayedPageNumber() {
-               $index = $this->newIndexPage();
+               $index = ProofreadIndexPageTest::newIndexPage();
                $pageNumber = new PageNumber( 'TOC' );
                $pagination = new PagePagination(
                        $index,
@@ -61,13 +62,13 @@
         * @expectedException OutOfBoundsException
         */
        public function testGetDisplayedPageNumberWithFailure() {
-               $index = $this->newIndexPage();
+               $index = ProofreadIndexPageTest::newIndexPage();
                $pagination = new PagePagination( $index, [], [] );
                $pagination->getDisplayedPageNumber( 3 );
        }
 
        public function testGetNumberOfPages() {
-               $index = $this->newIndexPage();
+               $index = ProofreadIndexPageTest::newIndexPage();
                $pagination = new PagePagination(
                        $index,
                        [
@@ -85,7 +86,7 @@
        }
 
        public function testGetPage() {
-               $index = $this->newIndexPage();
+               $index = ProofreadIndexPageTest::newIndexPage();
                $page = new ProofreadPagePage( Title::newFromText( 'Page:Test 
1.jpg' ), $index );
                $pagination = new PagePagination(
                        $index,
@@ -107,13 +108,13 @@
         * @expectedException OutOfBoundsException
         */
        public function testGetPageWithFailure() {
-               $index = $this->newIndexPage();
+               $index = ProofreadIndexPageTest::newIndexPage();
                $pagination = new PagePagination( $index, [], [] );
                $pagination->getPage( 3 );
        }
 
        public function testIterator() {
-               $index = $this->newIndexPage();
+               $index = ProofreadIndexPageTest::newIndexPage();
                $page1 = new ProofreadPagePage( Title::newFromText( 'Page:Test 
1.jpg' ), $index );
                $page2 = new ProofreadPagePage( Title::newFromText( 'Page:Test 
2.jpg' ), $index );
                $pagination = new PagePagination(
diff --git a/tests/phpunit/Pagination/PaginationFactoryTest.php 
b/tests/phpunit/Pagination/PaginationFactoryTest.php
index ddf0627..752a5f0 100644
--- a/tests/phpunit/Pagination/PaginationFactoryTest.php
+++ b/tests/phpunit/Pagination/PaginationFactoryTest.php
@@ -3,6 +3,7 @@
 namespace ProofreadPage\Pagination;
 
 use MediaHandler;
+use ProofreadIndexPageTest;
 use ProofreadPagePage;
 use ProofreadPageTestCase;
 use Title;
@@ -17,7 +18,7 @@
                if ( MediaHandler::getHandler( 'image/vnd.djvu' ) === false ) {
                        $this->markTestSkipped( 'There is no support for DjVu 
files, please enable it.' );
                }
-               $page = $this->newIndexPage(
+               $page = ProofreadIndexPageTest::newIndexPage(
                        'LoremIpsum.djvu',
                        "{{\n|Pages=<pagelist 1to2=-/> <pagelist 3=1 4to5=roman 
/>\n|Author=[[Author:Me]]\n}}"
                );
@@ -37,7 +38,7 @@
        }
 
        public function testGetPaginationWithoutPagelist() {
-               $page = $this->newIndexPage(
+               $page = ProofreadIndexPageTest::newIndexPage(
                        'Test',
                        "{{\n|Pages=[[Page:Test 1.jpg|TOC]] [[Page:Test 
2.tiff|1]] " .
                        "[[Page:Test:3.png|2]]\n|Author=[[Author:Me]]\n}}"
diff --git a/tests/phpunit/ProofreadPageInitTest.php 
b/tests/phpunit/ProofreadPageInitTest.php
index 78b9fec..2064857 100644
--- a/tests/phpunit/ProofreadPageInitTest.php
+++ b/tests/phpunit/ProofreadPageInitTest.php
@@ -12,14 +12,8 @@
        public function 
testInitNamespaceThrowsExceptionWhenNamespaceValueIsNotNumeric() {
                global $wgProofreadPageNamespaceIds;
 
-               $oldValue = $wgProofreadPageNamespaceIds;
-
-               try {
-                       $wgProofreadPageNamespaceIds['page'] = 'quux';
-                       ProofreadPageInit::initNamespaces();
-               } finally {
-                       $wgProofreadPageNamespaceIds = $oldValue;
-               }
+               $wgProofreadPageNamespaceIds['page'] = 'quux';
+               ProofreadPageInit::initNamespaces();
        }
 
        /**
@@ -28,13 +22,8 @@
        public function testGetNamespaceIdThrowsExceptionWhenKeyDoesNotExist() {
                global $wgProofreadPageNamespaceIds;
 
-               $oldValue = $wgProofreadPageNamespaceIds;
-               try {
-                       $wgProofreadPageNamespaceIds = [];
-                       ProofreadPageInit::getNamespaceId( 'page' );
-               } finally {
-                       $wgProofreadPageNamespaceIds = $oldValue;
-               }
+               $wgProofreadPageNamespaceIds = [];
+               ProofreadPageInit::getNamespaceId( 'page' );
        }
 
 }
diff --git a/tests/phpunit/ProofreadPageTestCase.php 
b/tests/phpunit/ProofreadPageTestCase.php
index b038ff3..7a1eb7e 100644
--- a/tests/phpunit/ProofreadPageTestCase.php
+++ b/tests/phpunit/ProofreadPageTestCase.php
@@ -3,88 +3,11 @@
 use ProofreadPage\Context;
 use ProofreadPage\FileProvider;
 use ProofreadPage\FileProviderMock;
-use ProofreadPage\Index\CustomIndexFieldsParser;
-use ProofreadPage\Index\IndexContent;
-use ProofreadPage\Page\PageContent;
-use ProofreadPage\ProofreadPageInit;
 
 /**
  * @group ProofreadPage
  */
 abstract class ProofreadPageTestCase extends MediaWikiLangTestCase {
-
-       protected static $customIndexFieldsConfiguration = [
-               'Title' => [
-                       'type' => 'string',
-                       'size' => 1,
-                       'default' => '',
-                       'label' => 'Title',
-                       'values' => null,
-                       'header' => true,
-                       'data' => 'title'
-               ],
-               'Author' => [
-                       'type' => 'page',
-                       'size' => 1,
-                       'default' => '',
-                       'label' => 'Author',
-                       'values' => null,
-                       'header' => true,
-                       'data' => 'author'
-               ],
-               'Year' => [
-                       'type' => 'number',
-                       'size' => 1,
-                       'default' => '',
-                       'label' => 'Year of publication',
-                       'values' => null,
-                       'header' => false,
-                       'data' => 'year'
-               ],
-               'Pages' => [
-                       'type' => 'string',
-                       'size' => 20,
-                       'default' => '',
-                       'label' => 'Pages',
-                       'values' => null,
-                       'header' => false
-               ],
-               'Header' => [
-                       'type' => 'string',
-                       'size' => 10,
-                       'default' => 'head',
-                       'label' => 'Header',
-                       'values' => null,
-                       'header' => false
-               ],
-               'Footer' => [
-                       'default' => '<references />',
-                       'header' => true,
-                       'hidden' => true
-               ],
-               'TOC' => [
-                       'type' => 'string',
-                       'size' => 1,
-                       'default' => '',
-                       'label' => 'Table of content',
-                       'values' => null,
-                       'header' => false
-               ],
-               'Comment' => [
-                       'header' => true,
-                       'hidden' => true
-               ],
-               'width' => [
-                       'type' => 'number',
-                       'label' => 'Image width',
-                       'header' => false
-               ],
-               'CSS' => [
-                       'type' => 'string',
-                       'label' => 'CSS',
-                       'header' => false
-               ],
-       ];
 
        /**
         * @var Context
@@ -92,11 +15,14 @@
        private $context;
 
        protected function setUp() {
+               global $wgProofreadPageNamespaceIds, $wgNamespacesWithSubpages;
                parent::setUp();
 
-               global $wgNamespacesWithSubpages;
+               $wgProofreadPageNamespaceIds = [
+                       'page' => 250,
+                       'index' => 252
+               ];
                $wgNamespacesWithSubpages[NS_MAIN] = true;
-               ProofreadPageInit::initNamespaces();
        }
 
        /**
@@ -105,58 +31,13 @@
        protected function getContext() {
                if ( $this->context === null ) {
                        $this->context = new Context(
-                               ProofreadPageInit::getNamespaceId( 'page' ),
-                               ProofreadPageInit::getNamespaceId( 'index' ),
-                               $this->getFileProvider(),
-                               new CustomIndexFieldsParser( 
self::$customIndexFieldsConfiguration )
+                               250,
+                               252,
+                               $this->getFileProvider()
                        );
                }
 
                return $this->context;
-       }
-
-       /**
-        * Constructor of a new ProofreadPagePage
-        * @param Title|string $title
-        * @param ProofreadIndexPage|null $index
-        * @return ProofreadPagePage
-        */
-       public function newPagePage( $title = 'test.jpg', ProofreadIndexPage 
$index = null ) {
-               if ( is_string( $title ) ) {
-                       $title = Title::makeTitle( $this->getPageNamespaceId(), 
$title );
-               }
-               return new ProofreadPagePage( $title, $index );
-       }
-
-       /**
-        * Constructor of a new ProofreadIndexPage
-        * @param Title|string $title
-        * @param string|IndexContent|null $content
-        * @return ProofreadIndexPage
-        */
-       protected function newIndexPage( $title = 'test.djvu', $content = null 
) {
-               if ( is_string( $title ) ) {
-                       $title = Title::makeTitle( 
$this->getIndexNamespaceId(), $title );
-               }
-               if ( is_string( $content ) ) {
-                       $content = ContentHandler::getForModelID( 
CONTENT_MODEL_PROOFREAD_INDEX )
-                               ->unserializeContent( $content );
-               }
-               return new ProofreadIndexPage( $title, $content );
-       }
-
-       /**
-        * @return int
-        */
-       protected function getPageNamespaceId() {
-               return $this->getContext()->getPageNamespaceId();
-       }
-
-       /**
-        * @return int
-        */
-       protected function getIndexNamespaceId() {
-               return $this->getContext()->getIndexNamespaceId();
        }
 
        /**
diff --git a/tests/phpunit/index/CustomIndexFieldsParserTest.php 
b/tests/phpunit/index/CustomIndexFieldsParserTest.php
deleted file mode 100644
index 4cead40..0000000
--- a/tests/phpunit/index/CustomIndexFieldsParserTest.php
+++ /dev/null
@@ -1,189 +0,0 @@
-<?php
-
-namespace ProofreadPage\Index;
-
-use ContentHandler;
-use OutOfBoundsException;
-use ProofreadPageTestCase;
-
-/**
- * @group ProofreadPage
- * @covers CustomIndexFieldsParser
- */
-class CustomIndexFieldsParserTest extends ProofreadPageTestCase {
-       /**
-        * @param string $content
-        * @return IndexContent
-        */
-       private static function buildContent( $content ) {
-               return ContentHandler::getForModelID( 
CONTENT_MODEL_PROOFREAD_INDEX )
-                               ->unserializeContent( $content );
-       }
-
-       public function testParseCustomIndexFields() {
-               $content = self::buildContent(
-                       "{{\n|Title=Test 
book\n|Author=[[Author:Me]]\n|Year=2012 or 2013\n|Header={{{Title}}}" .
-                               "\n|Pages=<pagelist />\n|TOC=* [[Test/Chapter 
1|Chapter 1]]" .
-                               "\n* [[Test/Chapter 2|Chapter 2]]\n}}"
-               );
-               $entries = [
-                       'Title' => new CustomIndexField(
-                               'Title', 'Test book', 
self::$customIndexFieldsConfiguration['Title']
-                       ),
-                       'Author' => new CustomIndexField(
-                               'Author', '[[Author:Me]]', 
self::$customIndexFieldsConfiguration['Author']
-                       ),
-                       'Year' => new CustomIndexField(
-                               'Year', '2012 or 2013', 
self::$customIndexFieldsConfiguration['Year']
-                       ),
-                       'Pages' => new CustomIndexField(
-                               'Pages', '<pagelist />', 
self::$customIndexFieldsConfiguration['Pages']
-                       ),
-                       'Header' => new CustomIndexField(
-                               'Header', '{{{Title}}}', 
self::$customIndexFieldsConfiguration['Header']
-                       ),
-                       'Footer' => new CustomIndexField(
-                               'Footer', '', 
self::$customIndexFieldsConfiguration['Footer']
-                       ),
-                       'TOC' => new CustomIndexField(
-                               'TOC',
-                               "* [[Test/Chapter 1|Chapter 1]]\n* 
[[Test/Chapter 2|Chapter 2]]",
-                               self::$customIndexFieldsConfiguration['TOC']
-                       ),
-                       'Comment' => new CustomIndexField(
-                               'Comment', '', 
self::$customIndexFieldsConfiguration['Comment']
-                       ),
-                       'width' => new CustomIndexField(
-                               'width', '', 
self::$customIndexFieldsConfiguration['width']
-                       ),
-                       'CSS' => new CustomIndexField(
-                               'CSS', '', 
self::$customIndexFieldsConfiguration['CSS']
-                       )
-               ];
-               $this->assertEquals(
-                       $entries, 
$this->getContext()->getCustomIndexFieldsParser()->parseCustomIndexFields( 
$content )
-               );
-       }
-
-       public function testParseCustomIndexFieldsForHeader() {
-               $content = self::buildContent(
-                       "{{\n|Title=Test 
book\n|Author=[[Author:Me]]\n|Year=2012 or 2013\n|Pages=<pagelist />" .
-                               "\n|TOC=* [[Test/Chapter 1|Chapter 1]]\n* 
[[Test/Chapter 2|Chapter 2]]\n}}"
-               );
-               $entries = [
-                       'Title' => new CustomIndexField(
-                               'Title', 'Test book', 
self::$customIndexFieldsConfiguration['Title']
-                       ),
-                       'Author' => new CustomIndexField(
-                               'Author', '[[Author:Me]]', 
self::$customIndexFieldsConfiguration['Author']
-                       ),
-                       'Comment' => new CustomIndexField(
-                               'Comment', '', 
self::$customIndexFieldsConfiguration['Comment']
-                       ),
-                       'Header' => new CustomIndexField(
-                               'Header', '', 
self::$customIndexFieldsConfiguration['Header']
-                       ),
-                       'Footer' => new CustomIndexField(
-                               'Footer', '', 
self::$customIndexFieldsConfiguration['Footer']
-                       ),
-                       'width' => new CustomIndexField(
-                               'width', '', 
self::$customIndexFieldsConfiguration['width']
-                       ),
-                       'CSS' => new CustomIndexField(
-                               'CSS', '', 
self::$customIndexFieldsConfiguration['CSS']
-                       )
-               ];
-               $this->assertEquals(
-                       $entries,
-                       
$this->getContext()->getCustomIndexFieldsParser()->parseCustomIndexFieldsForHeader(
 $content )
-               );
-       }
-
-       public function testParseCustomIndexField() {
-               $content = self::buildContent( "{{\n|Year=2012 or 2013\n}}" );
-               $parser = $this->getContext()->getCustomIndexFieldsParser();
-               $entry = new CustomIndexField(
-                       'Year', '2012 or 2013', 
self::$customIndexFieldsConfiguration['Year']
-               );
-               $this->assertEquals( $entry, $parser->parseCustomIndexField( 
$content, 'year' ) );
-       }
-
-       /**
-        * @expectedException OutOfBoundsException
-        */
-       public function testParseCustomIndexFieldThatDoesNotExist() {
-               $content = self::buildContent( "{{\n|Year=2012 or 2013\n}}" );
-               $parser = $this->getContext()->getCustomIndexFieldsParser();
-               $parser->parseCustomIndexField( $content, 'years' );
-       }
-
-       public function replaceVariablesWithIndexEntriesProvider() {
-               return [
-                       [
-                               "{{\n|Title=Test book\n|Header={{{title}}}\n}}",
-                               'Test book',
-                               'header',
-                               []
-                       ],
-                       [
-                               "{{\n|Title=Test book\n|Header={{{ Pagenum 
}}}\n}}",
-                               '22',
-                               'header',
-                               [ 'pagenum' => 22 ]
-                       ],
-                       [
-                               "{{\n|Title=Test 
book\n|Header={{{authors}}}\n}}",
-                               '{{{authors}}}',
-                               'header',
-                               []
-                       ],
-                       [
-                               "{{\n|Title=Test book\n|Header={{{authors 
|a}}}\n}}",
-                               'a',
-                               'header',
-                               []
-                       ],
-                       [
-                               "{{\n|Title=Test 
book\n|Header={{template|a=b}}\n}}",
-                               '{{template|a=b}}',
-                               'header',
-                               []
-                       ],
-                       [
-                               "{{\n|Title=Test 
book\n|Header={{template|a={{{Title |}}}}}\n}}",
-                               '{{template|a=Test book}}',
-                               'header',
-                               []
-                       ],
-                       [
-                               "{{\n|Title=Test 
book\n|Header=<references/>\n}}",
-                               '<references/>',
-                               'header',
-                               []
-                       ],
-               ];
-       }
-
-       /**
-        * @dataProvider replaceVariablesWithIndexEntriesProvider
-        */
-       public function testReplaceVariablesWithIndexEntries(
-               $pageContent, $result, $entry, $extraparams
-       ) {
-               $content = self::buildContent( $pageContent );
-               $this->assertEquals(
-                       $result,
-                       $this->getContext()->getCustomIndexFieldsParser()
-                               
->parseCustomIndexFieldWithVariablesReplacedWithIndexEntries( $content, $entry, 
$extraparams )
-               );
-       }
-
-       /**
-        * @expectedException OutOfBoundsException
-        */
-       public function testReplaceVariablesWithIndexEntriesThatDoesNotExist() {
-               $content = self::buildContent( "{{\n|Title=Test 
book\n|Header={{{Pagenum}}}\n}}" );
-               $this->getContext()->getCustomIndexFieldsParser()
-                       
->parseCustomIndexFieldWithVariablesReplacedWithIndexEntries( $content, 
'headers', [] );
-       }
-}
diff --git a/tests/phpunit/index/IndexContentTest.php 
b/tests/phpunit/index/IndexContentTest.php
index d2a4081..3dd0172 100644
--- a/tests/phpunit/index/IndexContentTest.php
+++ b/tests/phpunit/index/IndexContentTest.php
@@ -28,7 +28,7 @@
                parent::setUp();
 
                $this->requestContext = new RequestContext( new FauxRequest() );
-               $this->requestContext->setTitle( Title::makeTitle( 
$this->getIndexNamespaceId(), 'Test.pdf' ) );
+               $this->requestContext->setTitle( Title::makeTitle( 252, 
'Test.pdf' ) );
                $this->requestContext->setUser( new User() );
        }
 
@@ -218,7 +218,7 @@
                        $links,
                        $content->getLinksToNamespace(
                                
Context::getDefaultContext()->getPageNamespaceId(),
-                               Title::makeTitle( $this->getIndexNamespaceId(), 
'Test' )
+                               Title::makeTitle( 252, 'Test' )
                        )
                );
        }
@@ -259,7 +259,7 @@
                        [
                                new IndexContent( [
                                        'Pages' => new WikitextContent( '' ),
-                                       'Author' => new WikitextContent( 
'[[Author:Me]]' )
+                                       'Author'=> new WikitextContent( 
'[[Author:Me]]' )
                                ] ),
                                null
                        ]
diff --git a/tests/phpunit/index/IndexRedirectContentTest.php 
b/tests/phpunit/index/IndexRedirectContentTest.php
index 5969f5b..27faf20 100644
--- a/tests/phpunit/index/IndexRedirectContentTest.php
+++ b/tests/phpunit/index/IndexRedirectContentTest.php
@@ -24,7 +24,7 @@
                parent::setUp();
 
                $this->requestContext = new RequestContext( new FauxRequest() );
-               $this->requestContext->setTitle( Title::makeTitle( 
$this->getIndexNamespaceId(), 'Test.pdf' ) );
+               $this->requestContext->setTitle( Title::makeTitle( 252, 
'Test.pdf' ) );
                $this->requestContext->setUser( new User() );
        }
 
diff --git a/tests/phpunit/index/ProofreadIndexPageTest.php 
b/tests/phpunit/index/ProofreadIndexPageTest.php
index 416170e..496c5fa 100644
--- a/tests/phpunit/index/ProofreadIndexPageTest.php
+++ b/tests/phpunit/index/ProofreadIndexPageTest.php
@@ -1,4 +1,5 @@
 <?php
+use ProofreadPage\Index\IndexContent;
 
 /**
  * @group ProofreadPage
@@ -6,10 +7,100 @@
  */
 class ProofreadIndexPageTest extends ProofreadPageTestCase {
 
+       protected static $config = [
+               'Title' => [
+                       'type' => 'string',
+                       'size' => 1,
+                       'default' => '',
+                       'label' => 'Title',
+                       'values' => null,
+                       'header' => true,
+                       'data' => 'title'
+               ],
+               'Author' => [
+                       'type' => 'page',
+                       'size' => 1,
+                       'default' => '',
+                       'label' => 'Author',
+                       'values' => null,
+                       'header' => true,
+                       'data' => 'author'
+               ],
+               'Year' => [
+                       'type' => 'number',
+                       'size' => 1,
+                       'default' => '',
+                       'label' => 'Year of publication',
+                       'values' => null,
+                       'header' => false,
+                       'data' => 'year'
+               ],
+               'Pages' => [
+                       'type' => 'string',
+                       'size' => 20,
+                       'default' => '',
+                       'label' => 'Pages',
+                       'values' => null,
+                       'header' => false
+               ],
+               'Header' => [
+                       'type' => 'string',
+                       'size' => 10,
+                       'default' => 'head',
+                       'label' => 'Header',
+                       'values' => null,
+                       'header' => false
+               ],
+               'Footer' => [
+                       'default' => '<references />',
+                       'header' => true,
+                       'hidden' => true
+               ],
+               'TOC' => [
+                       'type' => 'string',
+                       'size' => 1,
+                       'default' => '',
+                       'label' => 'Table of content',
+                       'values' => null,
+                       'header' => false
+               ],
+               'Comment' => [
+                       'header' => true,
+                       'hidden' => true
+               ],
+               'width' => [
+                       'type' => 'number',
+                       'label' => 'Image width',
+                       'header' => false
+               ],
+               'CSS' => [
+                       'type' => 'string',
+                       'label' => 'CSS',
+                       'header' => false
+               ],
+       ];
+
+       /**
+        * Constructor of a new ProofreadIndexPage
+        * @param Title|string $title
+        * @param string|IndexContent|null $content
+        * @return ProofreadIndexPage
+        */
+       public static function newIndexPage( $title = 'test.djvu', $content = 
null ) {
+               if ( is_string( $title ) ) {
+                       $title = Title::makeTitle( 252, $title );
+               }
+               if ( is_string( $content ) ) {
+                       $content = ContentHandler::getForModelID( 
CONTENT_MODEL_PROOFREAD_INDEX )
+                               ->unserializeContent( $content );
+               }
+               return new ProofreadIndexPage( $title, self::$config, $content 
);
+       }
+
        public function testEquals() {
-               $page = $this->newIndexPage( 'Test.djvu' );
-               $page2 = $this->newIndexPage( 'Test.djvu' );
-               $page3 = $this->newIndexPage( 'Test2.djvu' );
+               $page = self::newIndexPage( 'Test.djvu' );
+               $page2 = self::newIndexPage( 'Test.djvu' );
+               $page3 = self::newIndexPage( 'Test2.djvu' );
                $this->assertTrue( $page->equals( $page2 ) );
                $this->assertTrue( $page2->equals( $page ) );
                $this->assertFalse( $page->equals( $page3 ) );
@@ -17,9 +108,37 @@
        }
 
        public function testGetTitle() {
-               $title = Title::makeTitle( $this->getIndexNamespaceId(), 
'Test.djvu' );
+               $title = Title::makeTitle( 252, 'Test.djvu' );
                $page = ProofreadIndexPage::newFromTitle( $title );
                $this->assertEquals( $title, $page->getTitle() );
+       }
+
+       public function testGetIndexEntries() {
+               $page = self::newIndexPage(
+                       'Test.djvu',
+                       "{{\n|Title=Test 
book\n|Author=[[Author:Me]]\n|Year=2012 or 2013\n|Header={{{Title}}}" .
+                               "\n|Pages=<pagelist />\n|TOC=* [[Test/Chapter 
1|Chapter 1]]" .
+                               "\n* [[Test/Chapter 2|Chapter 2]]\n}}"
+               );
+               $entries = [
+                       'Title' => new ProofreadIndexEntry( 'Title', 'Test 
book', self::$config['Title'] ),
+                       'Author' => new ProofreadIndexEntry(
+                               'Author', '[[Author:Me]]', 
self::$config['Author']
+                       ),
+                       'Year' => new ProofreadIndexEntry( 'Year', '2012 or 
2013', self::$config['Year'] ),
+                       'Pages' => new ProofreadIndexEntry( 'Pages', '<pagelist 
/>', self::$config['Pages'] ),
+                       'Header' => new ProofreadIndexEntry( 'Header', 
'{{{Title}}}', self::$config['Header'] ),
+                       'Footer' => new ProofreadIndexEntry( 'Footer', '', 
self::$config['Footer'] ),
+                       'TOC' => new ProofreadIndexEntry(
+                               'TOC',
+                               "* [[Test/Chapter 1|Chapter 1]]\n* 
[[Test/Chapter 2|Chapter 2]]",
+                               self::$config['TOC']
+                       ),
+                       'Comment' => new ProofreadIndexEntry( 'Comment', '', 
self::$config['Comment'] ),
+                       'width' => new ProofreadIndexEntry( 'width', '', 
self::$config['width'] ),
+                       'CSS' => new ProofreadIndexEntry( 'CSS', '', 
self::$config['CSS'] )
+               ];
+               $this->assertEquals( $entries, $page->getIndexEntries() );
        }
 
        public function mimeTypesProvider() {
@@ -34,6 +153,101 @@
         * @dataProvider mimeTypesProvider
         */
        public function testGetMimeType( $mime, $name ) {
-               $this->assertEquals( $mime, $this->newIndexPage( $name 
)->getMimeType() );
+               $this->assertEquals( $mime, self::newIndexPage( $name 
)->getMimeType() );
+       }
+
+       public function testGetIndexEntriesForHeader() {
+               $page = self::newIndexPage(
+                       'Test.djvu',
+                       "{{\n|Title=Test 
book\n|Author=[[Author:Me]]\n|Year=2012 or 2013\n|Pages=<pagelist />" .
+                               "\n|TOC=* [[Test/Chapter 1|Chapter 1]]\n* 
[[Test/Chapter 2|Chapter 2]]\n}}"
+               );
+               $entries = [
+                       'Title' => new ProofreadIndexEntry( 'Title', 'Test 
book', self::$config['Title'] ),
+                       'Author' => new ProofreadIndexEntry(
+                               'Author', '[[Author:Me]]', 
self::$config['Author']
+                       ),
+                       'Comment' => new ProofreadIndexEntry( 'Comment', '', 
self::$config['Comment'] ),
+                       'Header' => new ProofreadIndexEntry( 'Header', '', 
self::$config['Header'] ),
+                       'Footer' => new ProofreadIndexEntry( 'Footer', '', 
self::$config['Footer'] ),
+                       'width' => new ProofreadIndexEntry( 'width', '', 
self::$config['width'] ),
+                       'CSS' => new ProofreadIndexEntry( 'CSS', '', 
self::$config['CSS'] )
+               ];
+               $this->assertEquals( $entries, 
$page->getIndexEntriesForHeader() );
+       }
+
+       public function testGetIndexEntry() {
+               $page = self::newIndexPage( 'Test.djvu', "{{\n|Year=2012 or 
2013\n}}" );
+
+               $entry = new ProofreadIndexEntry( 'Year', '2012 or 2013', 
self::$config['Year'] );
+               $this->assertEquals( $entry, $page->getIndexEntry( 'year' ) );
+
+               $this->assertNull( $page->getIndexEntry( 'years' ) );
+       }
+
+       public function replaceVariablesWithIndexEntriesProvider() {
+               return [
+                       [
+                               "{{\n|Title=Test book\n|Header={{{title}}}\n}}",
+                               'Test book',
+                               'header',
+                               []
+                       ],
+                       [
+                               "{{\n|Title=Test book\n|Header={{{ Pagenum 
}}}\n}}",
+                               '22',
+                               'header',
+                               [ 'pagenum' => 22 ]
+                       ],
+                       [
+                               "{{\n|Title=Test 
book\n|Header={{{authors}}}\n}}",
+                               '{{{authors}}}',
+                               'header',
+                               []
+                       ],
+                       [
+                               "{{\n|Title=Test book\n|Header={{{authors 
|a}}}\n}}",
+                               'a',
+                               'header',
+                               []
+                       ],
+                       [
+                               "{{\n|Title=Test 
book\n|Header={{template|a=b}}\n}}",
+                               '{{template|a=b}}',
+                               'header',
+                               []
+                       ],
+                       [
+                               "{{\n|Title=Test 
book\n|Header={{template|a={{{Title |}}}}}\n}}",
+                               '{{template|a=Test book}}',
+                               'header',
+                               []
+                       ],
+                       [
+                               "{{\n|Title=Test 
book\n|Header=<references/>\n}}",
+                               '<references/>',
+                               'header',
+                               []
+                       ],
+                       [
+                               "{{\n|Title=Test 
book\n|Header={{{Pagenum}}}\n}}",
+                               null,
+                               'headers',
+                               []
+                       ],
+               ];
+       }
+
+       /**
+        * @dataProvider replaceVariablesWithIndexEntriesProvider
+        */
+       public function testReplaceVariablesWithIndexEntries(
+               $pageContent, $result, $entry, $extraparams
+       ) {
+               $page = self::newIndexPage( 'Test.djvu', $pageContent );
+               $this->assertEquals(
+                       $result,
+                       
$page->getIndexEntryWithVariablesReplacedWithIndexEntries( $entry, $extraparams 
)
+               );
        }
 }
diff --git a/tests/phpunit/page/PageContentBuilderTest.php 
b/tests/phpunit/page/PageContentBuilderTest.php
index 8688f79..c97d48e 100644
--- a/tests/phpunit/page/PageContentBuilderTest.php
+++ b/tests/phpunit/page/PageContentBuilderTest.php
@@ -4,9 +4,11 @@
 
 use IContextSource;
 use MediaHandler;
-use ProofreadPage\FileNotFoundException;
+use ProofreadIndexPageTest;
 use ProofreadPagePage;
+use ProofreadPagePageTest;
 use ProofreadPageTestCase;
+use ProofreadPage\FileNotFoundException;
 use RequestContext;
 use User;
 
@@ -52,24 +54,24 @@
        public function buildDefaultContentForPageProvider() {
                return [
                        [
-                               $this->newPagePage(
+                               ProofreadPagePageTest::newPagePage(
                                        'Test.djvu/1',
-                                       $this->newIndexPage(
+                                       ProofreadIndexPageTest::newIndexPage(
                                                'Test.djvu', "{{\n|Title=Test 
book\n|Header={{{title}}}\n}}"
                                        )
                                ),
                                PageContentTest::newContent( 'Test book', '', 
'<references />', 1 ),
                        ],
                        [
-                               $this->newPagePage(
+                               ProofreadPagePageTest::newPagePage(
                                        'LoremIpsum.djvu/2'
                                ),
                                PageContentTest::newContent( '', "Lorem ipsum 
\n2 \n", '<references/>', 1 ),
                        ],
                        [
-                               $this->newPagePage(
+                               ProofreadPagePageTest::newPagePage(
                                        'LoremIpsum.djvu/2',
-                                       $this->newIndexPage(
+                                       ProofreadIndexPageTest::newIndexPage(
                                                'LoremIpsum.djvu',
                                                "{{\n|Title=Test 
book\n|Pages=<pagelist/>\n|Header={{{pagenum}}}\n}}"
                                        )
@@ -77,9 +79,9 @@
                                PageContentTest::newContent( '2', "Lorem ipsum 
\n2 \n", '<references />', 1 ),
                        ],
                        [
-                               $this->newPagePage(
+                               ProofreadPagePageTest::newPagePage(
                                        'LoremIpsum.djvu/2',
-                                       $this->newIndexPage(
+                                       ProofreadIndexPageTest::newIndexPage(
                                                'LoremIpsum.djvu',
                                                "{{\n|Title=Test 
book\n|Pages=<pagelist 1to5=roman />\n" .
                                                        
"|Header={{{pagenum}}}\n}}"
diff --git a/tests/phpunit/page/PageContentTest.php 
b/tests/phpunit/page/PageContentTest.php
index 14894a8..75b342b 100644
--- a/tests/phpunit/page/PageContentTest.php
+++ b/tests/phpunit/page/PageContentTest.php
@@ -36,7 +36,7 @@
                ] );
 
                $this->requestContext = new RequestContext( new FauxRequest() );
-               $this->requestContext->setTitle( Title::makeTitle( 
$this->getPageNamespaceId(), 'Test.jpg' ) );
+               $this->requestContext->setTitle( Title::makeTitle( 250, 
'Test.jpg' ) );
                $this->requestContext->setUser( $user );
        }
 
diff --git a/tests/phpunit/page/PageDisplayHandlerTest.php 
b/tests/phpunit/page/PageDisplayHandlerTest.php
index 9a0983a..6f975e8 100644
--- a/tests/phpunit/page/PageDisplayHandlerTest.php
+++ b/tests/phpunit/page/PageDisplayHandlerTest.php
@@ -2,6 +2,8 @@
 
 namespace ProofreadPage\Page;
 
+use ProofreadIndexPageTest;
+use ProofreadPagePageTest;
 use ProofreadPageTestCase;
 
 /**
@@ -13,32 +15,32 @@
        public function testGetImageWidth() {
                $handler = new PageDisplayHandler( $this->getContext() );
 
-               $index = $this->newIndexPage( 'Test', "{{\n|width= 500 \n}}" );
-               $page = $this->newPagePage( 'Test.jpg', $index );
+               $index = ProofreadIndexPageTest::newIndexPage( 'Test', 
"{{\n|width= 500 \n}}" );
+               $page = ProofreadPagePageTest::newPagePage( 'Test.jpg', $index 
);
                $this->assertEquals( 500, $handler->getImageWidth( $page ) );
 
-               $index = $this->newIndexPage( 'Test', "{{\n|title=500\n}}" );
-               $page = $this->newPagePage( 'Test.jpg', $index );
+               $index = ProofreadIndexPageTest::newIndexPage( 'Test', 
"{{\n|title=500\n}}" );
+               $page = ProofreadPagePageTest::newPagePage( 'Test.jpg', $index 
);
                $this->assertEquals( PageDisplayHandler::DEFAULT_IMAGE_WIDTH, 
$handler->getImageWidth( $page ) );
        }
 
        public function testGetCustomCss() {
                $handler = new PageDisplayHandler( $this->getContext() );
 
-               $index = $this->newIndexPage( 'Test', "{{\n|CSS= width:300px; 
\n}}" );
-               $page = $this->newPagePage( 'Test.jpg', $index );
+               $index = ProofreadIndexPageTest::newIndexPage( 'Test', 
"{{\n|CSS= width:300px; \n}}" );
+               $page = ProofreadPagePageTest::newPagePage( 'Test.jpg', $index 
);
                $this->assertEquals( 'width:300px;', $handler->getCustomCss( 
$page ) );
 
-               $index = $this->newIndexPage(
+               $index = ProofreadIndexPageTest::newIndexPage(
                        'Test', "{{\n|CSS= background: 
url('/my-bad-url.jpg');\n}}"
                );
-               $page = $this->newPagePage( 'Test.jpg', $index );
+               $page = ProofreadPagePageTest::newPagePage( 'Test.jpg', $index 
);
                $this->assertEquals( '/* insecure input */', 
$handler->getCustomCss( $page ) );
 
-               $index = $this->newIndexPage(
+               $index = ProofreadIndexPageTest::newIndexPage(
                        'Test', "{{\n|CSS= width:300px;<style> \n}}"
                );
-               $page = $this->newPagePage( 'Test.jpg', $index );
+               $page = ProofreadPagePageTest::newPagePage( 'Test.jpg', $index 
);
                $this->assertEquals( 'width:300px;&lt;style&gt;', 
$handler->getCustomCss( $page ) );
        }
 }
diff --git a/tests/phpunit/page/PageLevelTest.php 
b/tests/phpunit/page/PageLevelTest.php
index 1105909..e91c609 100644
--- a/tests/phpunit/page/PageLevelTest.php
+++ b/tests/phpunit/page/PageLevelTest.php
@@ -68,10 +68,10 @@
                $testUser = User::newFromName( 'Test' );
                $testUser->addToDatabase();
                $testUser->addGroup( 'user' );
-               $test2User = User::newFromName( 'Test2' );
+               $test2User =  User::newFromName( 'Test2' );
                $test2User->addToDatabase();
                $test2User->addGroup( 'user' );
-               $test3User = User::newFromName( 'Test3' );
+               $test3User =  User::newFromName( 'Test3' );
                $test3User->addToDatabase();
                $test3User->addGroup( 'sysop' );
                $ipUser = User::newFromName( '172.16.254.7', false );
diff --git a/tests/phpunit/page/ProofreadPagePageTest.php 
b/tests/phpunit/page/ProofreadPagePageTest.php
index 86b8d34..56f46be 100644
--- a/tests/phpunit/page/ProofreadPagePageTest.php
+++ b/tests/phpunit/page/ProofreadPagePageTest.php
@@ -1,15 +1,31 @@
 <?php
 
+use ProofreadPage\Page\PageContent;
+
 /**
  * @group ProofreadPage
  * @covers ProofreadPagePage
  */
 class ProofreadPagePageTest extends ProofreadPageTestCase {
 
+       /**
+        * Constructor of a new ProofreadPagePage
+        * @param Title|string $title
+        * @param PageContent|null $content
+        * @param ProofreadIndexPage|null $index
+        * @return ProofreadPagePage
+        */
+       public static function newPagePage( $title = 'test.jpg', 
ProofreadIndexPage $index = null ) {
+               if ( is_string( $title ) ) {
+                       $title = Title::makeTitle( 250, $title );
+               }
+               return new ProofreadPagePage( $title, $index );
+       }
+
        public function testEquals() {
-               $page = $this->newPagePage( 'Test.djvu' );
-               $page2 = $this->newPagePage( 'Test.djvu' );
-               $page3 = $this->newPagePage( 'Test2.djvu' );
+               $page = self::newPagePage( 'Test.djvu' );
+               $page2 = self::newPagePage( 'Test.djvu' );
+               $page3 = self::newPagePage( 'Test2.djvu' );
                $this->assertTrue( $page->equals( $page2 ) );
                $this->assertTrue( $page2->equals( $page ) );
                $this->assertFalse( $page->equals( $page3 ) );
@@ -17,19 +33,19 @@
        }
 
        public function testGetTitle() {
-               $title = Title::makeTitle( $this->getPageNamespaceId(), 
'Test.djvu' );
-               $page = $this->newPagePage( $title );
+               $title = Title::makeTitle( 250, 'Test.djvu' );
+               $page = ProofreadPagePage::newFromTitle( $title );
                $this->assertEquals( $title, $page->getTitle() );
        }
 
        public function testGetPageNumber() {
-               $this->assertEquals( 1, $this->newPagePage( 'Test.djvu/1' 
)->getPageNumber() );
+               $this->assertEquals( 1, self::newPagePage( 'Test.djvu/1' 
)->getPageNumber() );
 
-               $this->assertNull( $this->newPagePage( 'Test.djvu' 
)->getPageNumber() );
+               $this->assertNull( self::newPagePage( 'Test.djvu' 
)->getPageNumber() );
        }
 
        public function testGetIndex() {
-               $index = $this->newIndexPage();
-               $this->assertEquals( $index, $this->newPagePage( 'Test.jpg', 
$index )->getIndex() );
+               $index = ProofreadIndexPageTest::newIndexPage();
+               $this->assertEquals( $index, self::newPagePage( 'Test.jpg', 
$index )->getIndex() );
        }
 }

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ia419c028f1578792e1d7dc9c6e14d192d4264f38
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/ProofreadPage
Gerrit-Branch: wmf/1.30.0-wmf.16
Gerrit-Owner: Thcipriani <tcipri...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to