diff --git a/README.md b/README.md
index 2c53709..b19f2c5 100644
--- a/README.md
+++ b/README.md
@@ -138,6 +138,23 @@ Example with parameters
Overrides the value of the $wgPageNetworkLabelMaxLength
configuration variable.
+
+ AllowOnlyLinksToPages |
+ true |
+ false |
+
+ When set to true, during initialization nodes have only links drawn between the listed pages (from page or pages parameter).
+ |
+
+
+ AllowLinkExpansion |
+ true |
+ false |
+
+ When set to true, when holding the left mouse button over graph node the links from node will be drawn.
+ Otherwise (when set to false) this behaviour is supressed.
+ |
+
There is also an includable special page, Special:Network, that can be used to construct graphs interactively. The
@@ -315,6 +332,32 @@ Wrong: `"font.color": "red"`, right: `"font": { "color": "red" }`, also right: `
Where `NetworkPages` contains `Page1 | Page2 | Page3` and `NetworkOptions` contains `{ "nodes": { "shape": "box" } } `
+#### Using with Semantic Mediawiki inline queries
+
+```
+{{#network:
+{{#ask: [[NextPage::+]]
+| format=list
+| headers=show
+| link=none
+| order=ascending
+| merge=true
+|limit=50
+|searchlabel=|
+|sep={{!}}
+|template=ReturnTemplatesFirstArgument
+|outro={{!}}
+|intro={{!}}
+}}
+| class = col-lg-3 mt-0
+|AllowOnlyLinksToPages = true
+|AllowLinkExpansion = false
+|enableDisplayTitle = true
+}}
+```
+
+where "ReturnTemplatesFirstArgument" contains only "{{{1}}}". Resulting graph will show only pages with NextPage property and how they are interlinked.
+
## Performance / caching
This extension bypasses the MediaWiki page cache. This means that your network graphs will always be up to date,
diff --git a/extension.json b/extension.json
index 8aa04aa..72a4240 100644
--- a/extension.json
+++ b/extension.json
@@ -89,6 +89,12 @@
},
"PageNetworkLabelMaxLength": {
"value": 20
+ },
+ "PageNetworkAllowOnlyLinksToPages": {
+ "value": false
+ },
+ "PageNetworkAllowLinkExpansion": {
+ "value": true
}
},
@@ -174,7 +180,11 @@
"pagenetwork-labelMaxLength-field-label",
"pagenetwork-labelMaxLength-field-help",
"pagenetwork-basic-tab-label",
- "pagenetwork-advanced-tab-label"
+ "pagenetwork-advanced-tab-label",
+ "pagenetwork-AllowOnlyLinksToPages-field-label",
+ "pagenetwork-AllowOnlyLinksToPages-field-help",
+ "pagenetwork-AllowLinkExpansion-field-label",
+ "pagenetwork-AllowLinkExpansion-field-help"
],
"targets": [ "desktop", "mobile" ]
}
diff --git a/i18n/de.json b/i18n/de.json
index 3240cf1..b661dda 100644
--- a/i18n/de.json
+++ b/i18n/de.json
@@ -13,5 +13,9 @@
"network-aria": "Die Netzwerkvisualisierung zeigt eingehende und ausgehende Links der {{PLURAL:$1|Seite|Seiten}} $2",
"pagenetwork-pages-field-label": "Seiten",
"pagenetwork-class-field-label": "CSS-Klassen",
- "pagenetwork-basic-tab-label": "Basisoptionen"
-}
+ "pagenetwork-basic-tab-label": "Basisoptionen",
+ "pagenetwork-AllowOnlyLinksToPages-field-label": "Nur Links zu Seiten zulassen",
+ "pagenetwork-AllowOnlyLinksToPages-field-help": "Wenn wahr, werden nur die angegebenen Seiten als Knoten angezeigt",
+ "pagenetwork-AllowLinkExpansion-field-label": "Linkerweiterung zulassen",
+ "pagenetwork-AllowLinkExpansion-field-help": "Wenn wahr, ist eine Linkerweiterung beim Halten des Knotens möglich"
+ }
diff --git a/i18n/en.json b/i18n/en.json
index 39af399..0be97ea 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -24,5 +24,9 @@
"pagenetwork-labelMaxLength-field-label": "Maximum Label Length",
"pagenetwork-labelMaxLength-field-help": "The maximum text length of a node's label or 0 if unlimited. If the node label must be truncated, an ellipsis (…) will appended.",
"pagenetwork-basic-tab-label": "Basic Options",
- "pagenetwork-advanced-tab-label": "Advanced Options"
+ "pagenetwork-advanced-tab-label": "Advanced Options",
+ "pagenetwork-AllowOnlyLinksToPages-field-label": "Allow Only Links To Pages",
+ "pagenetwork-AllowOnlyLinksToPages-field-help": "If true only specified pages will be displayed as nodes",
+ "pagenetwork-AllowLinkExpansion-field-label": "Allow Link Expansion",
+ "pagenetwork-AllowLinkExpansion-field-help": "If true Link Expansion when holding the node is possible"
}
diff --git a/i18n/pl.json b/i18n/pl.json
index bc46156..bccc40a 100644
--- a/i18n/pl.json
+++ b/i18n/pl.json
@@ -1,9 +1,32 @@
{
"@metadata": {
"authors": [
- "Rail"
+ "Rail",
+ "pw"
]
},
+ "network": "Sieć",
+ "network-name": "Sieć",
"network-desc": "Umożliwia dodawanie interaktywnych wizualizacji sieci do stron na wiki",
- "network-aria": "Wizualizacja sieci pokazująca wychodzące i przychodzące połączenia dla {{PLURAL:$1|strony|stron}} $2"
-}
+ "network-aria": "Wizualizacja sieci pokazująca wychodzące i przychodzące połączenia dla {{PLURAL:$1|strony|stron}} $2",
+ "pagenetwork-pages-field-label": "Strony",
+ "pagenetwork-pages-field-help": "Nazwa jednej lub wielu stron których połączenia mają zostać zwizualizowane, jedna na linię. Domyślnie to strona główna.",
+ "pagenetwork-exclude-field-label": "Wykluczone strony",
+ "pagenetwork-exclude-field-help": "Strony które mają zostać wykluczone z wizualizacji sieci połączeń, jedna na linię.",
+ "pagenetwork-excludedNamespaces-field-label": "Wykluczone przestrzenie nazw",
+ "pagenetwork-excludedNamespaces-field-help": "Przestrzenie nazw które mają zostać wykluczone z wizualizacji.",
+ "pagenetwork-class-field-label": "Klasy CSS",
+ "pagenetwork-class-field-help": "Dodatkowa klasa lub klasy które mają zostać dodane do wizualizacji, separowane znakiem spacji.",
+ "pagenetwork-options-field-label": "Opcje wizualizacji",
+ "pagenetwork-options-field-help": "Struktura JSON z opcjami wizualizacji vis.js.",
+ "pagenetwork-enableDisplayTitle-field-label": "Włącz wyświetlanie tytułu strony",
+ "pagenetwork-enableDisplayTitle-field-help": "Czy tytuł strony czy tytuł wyświetlania powinien być wyświetlany jako etykieta węzła?",
+ "pagenetwork-labelMaxLength-field-label": "Maksymalna długość etykiety",
+ "pagenetwork-labelMaxLength-field-help": "Maksymalna ilość znaków etykiety węzła lub zero dla braku ograniczenia. Jeżeli etkieta węzła zostanie obcięta to zostanie dodany wielokropek (…).",
+ "pagenetwork-basic-tab-label": "Opcje Podstawowe",
+ "pagenetwork-advanced-tab-label": "Opcje Zaawansowane",
+ "pagenetwork-AllowOnlyLinksToPages-field-label": "Wizualizuj tylko strony z listy",
+ "pagenetwork-AllowOnlyLinksToPages-field-help": "Wizualizuj tylko połączenia stron z listy",
+ "pagenetwork-AllowLinkExpansion-field-label": "Zezwalaj na dodawanie połączeń",
+ "pagenetwork-AllowLinkExpansion-field-help": "Umożliwia dodawanie połączeń ze strony poprzez przytrzymanie jej węzła"
+ }
diff --git a/resources/js/Network.js b/resources/js/Network.js
index b8ebcdd..ae1683d 100644
--- a/resources/js/Network.js
+++ b/resources/js/Network.js
@@ -7,20 +7,25 @@ module.Network = (function (vis, NetworkData) {
* @param {module.PageExclusionManager} pageExclusionManager
* @param {object} options
* @param {int} labelMaxLength
+ * @param {string[]} pageNamesOrig
+ * @param {bool} startWithPageNamesOrigOnly
+ * @param {bool} allowNodeExpansion
*/
let Network = function(
divId,
pageConnectionRepo,
pageExclusionManager,
options,
- labelMaxLength
+ labelMaxLength,
+ pageNamesOrig,
+ startWithPageNamesOrigOnly,
+ allowNodeExpansion
) {
this._pageConnectionRepo = pageConnectionRepo;
- this._data = new NetworkData(pageExclusionManager, labelMaxLength);
+ this._data = new NetworkData(pageExclusionManager, labelMaxLength, pageNamesOrig, startWithPageNamesOrigOnly, allowNodeExpansion);
this._options = options;
this._network = this._newNetwork(divId);
this._lastZoomPosition = {x:0, y:0}
-
this._bindEvents();
};
@@ -28,12 +33,12 @@ module.Network = (function (vis, NetworkData) {
* @param {string[]} pageNames
* @return {Promise}
*/
- Network.prototype.showPages = function(pageNames) {
+ Network.prototype.showPages = function(pageNames, allowOnly_pageNamesOrigList=true) {
let promise = this._pageConnectionRepo.addConnections(pageNames);
promise.then(
connections => {
- this._data.addPages(connections.pages);
+ this._data.addPages(connections.pages, allowOnly_pageNamesOrigList);
this._data.addLinks(connections.links);
}
);
@@ -42,7 +47,7 @@ module.Network = (function (vis, NetworkData) {
};
Network.prototype._addPage = function(pageName) {
- return this.showPages([pageName]);
+ return this.showPages([pageName], !this._data._allowNodeExpansion );
};
Network.prototype._newNetwork = function(divId) {
diff --git a/resources/js/NetworkData.js b/resources/js/NetworkData.js
index f1cdd91..4c3ebc2 100644
--- a/resources/js/NetworkData.js
+++ b/resources/js/NetworkData.js
@@ -3,19 +3,21 @@
*/
module.NetworkData = ( function ( vis, mw ) {
"use strict"
-
- let NetworkData = function(pageExclusionManager, labelMaxLength) {
+ let NetworkData = function(pageExclusionManager, labelMaxLength, pageNamesOrig, startWithPageNamesOrigOnly, allowNodeExpansion) {
this.nodes = new vis.DataSet();
this.edges = new vis.DataSet();
this._pageExclusionManager = pageExclusionManager;
this._labelMaxLength = labelMaxLength;
+ this._pageNamesOrig = pageNamesOrig;
+ this._startWithPageNamesOrigOnly = startWithPageNamesOrigOnly;
+ this._allowNodeExpansion = allowNodeExpansion;
};
- NetworkData.prototype.addPages = function(pages) {
+ NetworkData.prototype.addPages = function(pages, allowOnly_pageNamesOrigList=true) {
var maxlength = this._labelMaxLength;
this.nodes.update(
pages
- .filter(page => this._pageTitleIsAllowed(page.title))
+ .filter(page => { return this._pageTitleIsAllowed(page.title) && (!allowOnly_pageNamesOrigList||this._pageNamesOrig.includes(page.title)) })
.map(function(page) {
if (maxlength > 0 && page.displayTitle.length > maxlength) {
page.label = page.displayTitle.slice(0, maxlength) + '\u2026';
diff --git a/resources/js/SpecialForm.js b/resources/js/SpecialForm.js
index 1b600a3..b5821eb 100644
--- a/resources/js/SpecialForm.js
+++ b/resources/js/SpecialForm.js
@@ -115,6 +115,32 @@
helpInline: true
} );
+ let AllowOnlyLinksToPagesInput = new OO.ui.CheckboxInputWidget({
+ name: 'AllowOnlyLinksToPages',
+ selected: defaultValues['AllowOnlyLinksToPages'],
+ });
+ let AllowOnlyLinksToPagesField = new OO.ui.FieldLayout(
+ AllowOnlyLinksToPagesInput,
+ {
+ label: mw.message('pagenetwork-AllowOnlyLinksToPages-field-label').text(),
+ align: 'inline',
+ help: mw.message('pagenetwork-AllowOnlyLinksToPages-field-help').text(),
+ helpInline: true
+ } );
+
+ let AllowLinkExpansionInput = new OO.ui.CheckboxInputWidget({
+ name: 'AllowLinkExpansion',
+ selected: defaultValues['AllowLinkExpansion'],
+ });
+ let AllowLinkExpansionField = new OO.ui.FieldLayout(
+ AllowLinkExpansionInput,
+ {
+ label: mw.message('pagenetwork-AllowLinkExpansion-field-label').text(),
+ align: 'inline',
+ help: mw.message('pagenetwork-AllowLinkExpansion-field-help').text(),
+ helpInline: true
+ } );
+
let submitButton = new OO.ui.ButtonInputWidget( {
label: mw.message('htmlform-submit').text(),
type: 'submit',
@@ -159,7 +185,9 @@
classField,
optionsField,
enableDisplayTitleField,
- labelMaxLengthField
+ labelMaxLengthField,
+ AllowOnlyLinksToPagesField,
+ AllowLinkExpansionField
]
} ),
] )
diff --git a/resources/js/index.js b/resources/js/index.js
index e4fdfc7..3c166e4 100644
--- a/resources/js/index.js
+++ b/resources/js/index.js
@@ -15,10 +15,13 @@
mw.config.get('networkExcludeTalkPages')
),
$this.data('options'),
- $this.data('labelmaxlength')
+ $this.data('labelmaxlength'),
+ $this.data('pages'),
+ $this.data('allowonlylinkstopages'),
+ $this.data('allowlinkexpansion')
);
- network.showPages($this.data('pages')).then(function() {
+ network.showPages($this.data('pages'),$this.data('allowonlylinkstopages')).then(function() {
$this.find('canvas:first').attr(
'aria-label',
mw.message(
diff --git a/src/EntryPoints/NetworkFunction.php b/src/EntryPoints/NetworkFunction.php
index db103e1..a249628 100644
--- a/src/EntryPoints/NetworkFunction.php
+++ b/src/EntryPoints/NetworkFunction.php
@@ -45,6 +45,8 @@ public function handleParserFunctionCall( Parser $parser, string ...$arguments )
$requestModel->excludedNamespaces = $this->config->getExcludedNamespaces();
$requestModel->enableDisplayTitle = $this->config->getEnableDisplayTitle();
$requestModel->labelMaxLength = $this->config->getLabelMaxLength();
+ $requestModel->AllowOnlyLinksToPages = $this->config->getAllowOnlyLinksToPages();
+ $requestModel->AllowLinkExpansion = $this->config->getAllowLinkExpansion();
/**
* @psalm-suppress PossiblyNullReference
diff --git a/src/EntryPoints/SpecialNetwork.php b/src/EntryPoints/SpecialNetwork.php
index 04669da..cac360e 100644
--- a/src/EntryPoints/SpecialNetwork.php
+++ b/src/EntryPoints/SpecialNetwork.php
@@ -82,6 +82,32 @@ private function parseParams( WebRequest $request, NetworkConfig $config ) : arr
$params['labelMaxLength'] = $request->getInt( 'labelMaxLength', $config->getLabelMaxLength() );
+ if ( $this->including() ) {
+ $params['AllowOnlyLinksToPages'] =
+ filter_var(
+ $request->getText( 'AllowOnlyLinksToPages', strval( $config->getAllowOnlyLinksToPages() ) ),
+ FILTER_VALIDATE_BOOL,
+ FILTER_NULL_ON_FAILURE
+ );
+ } elseif ( $request->getCheck( 'pages' ) ) {
+ $params['AllowOnlyLinksToPages'] = $request->getCheck('AllowOnlyLinksToPages');
+ } else {
+ $params['AllowOnlyLinksToPages'] = $config->getAllowOnlyLinksToPages();
+ }
+
+ if ( $this->including() ) {
+ $params['AllowLinkExpansion'] =
+ filter_var(
+ $request->getText( 'AllowLinkExpansion', strval( $config->getAllowLinkExpansion() ) ),
+ FILTER_VALIDATE_BOOL,
+ FILTER_NULL_ON_FAILURE
+ );
+ } elseif ( $request->getCheck( 'pages' ) ) {
+ $params['AllowLinkExpansion'] = $request->getCheck('AllowLinkExpansion');
+ } else {
+ $params['AllowLinkExpansion'] = $config->getAllowLinkExpansion();
+ }
+
return $params;
}
@@ -109,6 +135,10 @@ private function formatParams( array $params ) : array {
$formattedParams['enableDisplayTitle'] = 'enableDisplayTitle=' .
( $params['enableDisplayTitle'] ? 'true' : 'false' );
$formattedParams['labelMaxLength'] = 'labelMaxLength=' . strval( $params['labelMaxLength'] );
+ $formattedParams['AllowOnlyLinksToPages'] = 'AllowOnlyLinksToPages=' .
+ ( $params['AllowOnlyLinksToPages'] ? 'true' : 'false' );
+ $formattedParams['AllowLinkExpansion'] = 'AllowLinkExpansion=' .
+ ( $params['AllowLinkExpansion'] ? 'true' : 'false' );
return $formattedParams;
}
@@ -127,6 +157,9 @@ public function showGraph( array $arguments, NetworkConfig $config) : string {
$requestModel->excludedNamespaces = $config->getExcludedNamespaces();
$requestModel->enableDisplayTitle = $config->getEnableDisplayTitle();
$requestModel->labelMaxLength = $config->getLabelMaxLength();
+ $requestModel->AllowOnlyLinksToPages = $config->getAllowOnlyLinksToPages();
+ $requestModel->AllowLinkExpansion = $config->getAllowLinkExpansion();
+
/**
* @psalm-suppress PossiblyNullReference
diff --git a/src/NetworkFunction/AbstractNetworkPresenter.php b/src/NetworkFunction/AbstractNetworkPresenter.php
index 3778d5a..ab104f7 100644
--- a/src/NetworkFunction/AbstractNetworkPresenter.php
+++ b/src/NetworkFunction/AbstractNetworkPresenter.php
@@ -28,6 +28,8 @@ public function setHtml( ResponseModel $viewModel ): void {
'data-options' => json_encode( $viewModel->visJsOptions ),
'data-enabledisplaytitle' => json_encode( $viewModel->enableDisplayTitle ),
'data-labelmaxlength' => json_encode( $viewModel->labelMaxLength ),
+ 'data-allowonlylinkstopages' => json_encode( $viewModel->AllowOnlyLinksToPages),
+ 'data-allowlinkexpansion' => json_encode( $viewModel->AllowLinkExpansion),
]
);
}
diff --git a/src/NetworkFunction/NetworkConfig.php b/src/NetworkFunction/NetworkConfig.php
index 63d28f1..4c32710 100644
--- a/src/NetworkFunction/NetworkConfig.php
+++ b/src/NetworkFunction/NetworkConfig.php
@@ -26,6 +26,8 @@ class NetworkConfig {
* @var bool
*/
private $enableDisplayTitle;
+ private $AllowOnlyLinksToPages;
+ private $AllowLinkExpansion;
/**
* @var int
@@ -39,6 +41,8 @@ public function __construct() {
$this->excludedNamespaces = array_map( 'strval', $config->get( 'PageNetworkExcludedNamespaces' ) );
$this->enableDisplayTitle = (bool)$config->get( 'PageNetworkEnableDisplayTitle' );
$this->labelMaxLength = (int)$config->get( 'PageNetworkLabelMaxLength' );
+ $this->AllowOnlyLinksToPages = (bool)$config->get( 'PageNetworkAllowOnlyLinksToPages');
+ $this->AllowLinkExpansion = (bool)$config->get( 'PageNetworkAllowLinkExpansion');
}
public function getOptions(): array {
@@ -60,4 +64,12 @@ public function getEnableDisplayTitle(): bool {
public function getLabelMaxLength(): int {
return $this->labelMaxLength;
}
+
+ public function getAllowOnlyLinksToPages(): bool {
+ return $this->AllowOnlyLinksToPages;
+ }
+
+ public function getAllowLinkExpansion(): bool {
+ return $this->AllowLinkExpansion;
+ }
}
diff --git a/src/NetworkFunction/NetworkUseCase.php b/src/NetworkFunction/NetworkUseCase.php
index dd32476..61c2535 100644
--- a/src/NetworkFunction/NetworkUseCase.php
+++ b/src/NetworkFunction/NetworkUseCase.php
@@ -31,6 +31,8 @@ public function run( RequestModel $request ): void {
$response->enableDisplayTitle = $this->getEnableDisplayTitle( $keyValuePairs, $request->enableDisplayTitle );
$response->labelMaxLength = $this->getLabelMaxLength( $keyValuePairs, $request->labelMaxLength );
$response->visJsOptions = $this->getVisJsOptions( $keyValuePairs );
+ $response->AllowOnlyLinksToPages = $this->getAllowOnlyLinksToPages($keyValuePairs, $request->AllowOnlyLinksToPages);
+ $response->AllowLinkExpansion = $this->getAllowLinkExpansion($keyValuePairs, $request->AllowLinkExpansion);
$this->presenter->buildGraph( $response );
}
@@ -163,4 +165,27 @@ private function getEnableDisplayTitle(array $arguments, bool $enableDisplayTitl
private function getLabelMaxLength(array $arguments, int $labelMaxLength ): int {
return isset( $arguments['labelMaxLength'] ) ? (int)$arguments['labelMaxLength'] : $labelMaxLength;
}
+
+ /**
+ * @param string[] $arguments
+ * @param bool $AllowOnlyLinksToPages
+ * @return bool
+ */
+ private function getAllowOnlyLinksToPages(array $arguments, bool $AllowOnlyLinksToPages ): bool {
+ return isset( $arguments['AllowOnlyLinksToPages'] )
+ ? filter_var( $arguments['AllowOnlyLinksToPages'], FILTER_VALIDATE_BOOLEAN )
+ : $AllowOnlyLinksToPages;
+ }
+
+ /**
+ * @param string[] $arguments
+ * @param bool $AllowLinkExpansion
+ * @return bool
+ */
+ private function getAllowLinkExpansion(array $arguments, bool $AllowLinkExpansion ): bool {
+ return isset( $arguments['AllowLinkExpansion'] )
+ ? filter_var( $arguments['AllowLinkExpansion'], FILTER_VALIDATE_BOOLEAN )
+ : $AllowLinkExpansion;
+ }
+
}
diff --git a/src/NetworkFunction/RequestModel.php b/src/NetworkFunction/RequestModel.php
index 2f040f1..de6a3f2 100644
--- a/src/NetworkFunction/RequestModel.php
+++ b/src/NetworkFunction/RequestModel.php
@@ -11,5 +11,8 @@ class RequestModel {
public /* int[] */ $excludedNamespaces;
public /* bool */ $enableDisplayTitle;
public /* int */ $labelMaxLength;
+ public /* bool */ $AllowOnlyLinksToPages;
+ public /* bool */ $AllowLinkExpansion;
+
}
diff --git a/src/NetworkFunction/ResponseModel.php b/src/NetworkFunction/ResponseModel.php
index a6e3bef..2c842a6 100644
--- a/src/NetworkFunction/ResponseModel.php
+++ b/src/NetworkFunction/ResponseModel.php
@@ -13,5 +13,7 @@ class ResponseModel {
public /* bool */ $enableDisplayTitle;
public /* int */ $labelMaxLength;
public /* array */ $visJsOptions;
+ public /* bool */ $AllowOnlyLinksToPages;
+ public /* bool */ $AllowLinkExpansion;
}
diff --git a/tests/php/NetworkFunction/NetworkUseCaseTest.php b/tests/php/NetworkFunction/NetworkUseCaseTest.php
index 9758a2d..2a0b686 100644
--- a/tests/php/NetworkFunction/NetworkUseCaseTest.php
+++ b/tests/php/NetworkFunction/NetworkUseCaseTest.php
@@ -49,7 +49,8 @@ private function newBasicRequestModel(): RequestModel {
$request->excludedNamespaces = [];
$request->enableDisplayTitle = true;
$request->labelMaxLength = 20;
-
+ $request->AllowOnlyLinksToPages=false;
+ $request->AllowLinkExpansion=false;
return $request;
}