We run mediawiki internally for all of our documentation. The problem we have is that some users create blank pages, as they do not really know how mediawiki works and also dont have deletion rights.
What i want to do is Automatically add this:
:''This page is unnecessary since it has remained blank since creation''
'''Unless more content is added, this page should be marked for deletion.
[[Category:ForDeletion]]
To all pages that are less than 84 bytes (short pages) or blank pages.
Is this in anyway possible in an easy way.?
That could be solved by using the PageContentSave hook. Here is a short example doing it in an extension:
<?php
public static function onPageContentSave( WikiPage &$wikiPage, User &$user, Content &$content, &$summary,
$isMinor, $isWatch, $section, &$flags, Status&$status
) {
// check, if the content model is wikitext to avoid adding wikitext to pages, that doesn't handle wikitext (e.g.
// some JavaScript/JSON/CSS pages)
if ( $content->getModel() === CONTENT_MODEL_WIKITEXT ) {
// check the size of the _new_ content
if ( $content->getSize() <= 84 ) {
// getNativeData returns the plain wikitext, which this Content object represent..
$data = $content->getNativeData();
// ..so it's possible to simply add/remove/replace wikitext like you want
$data .= ":''This page is unnecessary since it has remained blank since creation'' '''Unless more content is added, this page should be marked for deletion.";
$data .= "[[Category:ForDeletion]]";
// the new wikitext ahs to be saved as a new Content object (Content doesn't support to replace/add content by itself)
$content = new WikitextContent( $data );
}
} else {
// this could be omitted, but would log a debug message to the debug log, if the page couldn't be checked for a smaller edit as 84 bytes.
// Maybe you want to add some more info (Title and/or content model of the Content object
wfDebug( 'Could not check for empty or small remaining size after edit. False content model' );
}
return true;
}
You need to register this hook handler in your extension setup file:
$wgHooks['PageContentSave'][] = 'ExtensionHooksClass::onPageContentSave';
I hope that helps, but please consider the problem, that there are (maybe) pages, that are ok without having more then 84 bytes and the above implementation doesn't allow a any exceptions now ;)
Related
Hello guys I'm new to MediaWiki and trying to build my own extension. Using this extension I'm trying to show some content blow page heading but only to a page specific to a category.
For that, I'm using two hooks:
onArticleViewHeader ( To add my HTML content below the page heading)
onOutputPageMakeCategoryLinks (To get all the category of page being loaded)
From the first hook, I'm able to show my content using the following code:
public static function onArticleViewHeader( &$article, &$outputDone, &$pcache ) {
$article->getContext()->getOutput()->addHTML("Printed from a hook");
}
The above code prints the HTML below every page heading but I want to load HTML only to a specific page category. So for that, I'm trying to load the category and I'm just trying to call my first hook only if the category gets caught.
public static function onOutputPageMakeCategoryLinks( &$out, $categories, &$links ) {
foreach($categories as $category){
if($category=="my_page_category"){
MyExtentionClass::onArticleViewHeader();
}
}
}
I know I'm calling the hook in a bad manner which is not correct. But I just wanted to call my 1st hook 'onArticleViewHeader' from inside of my 2nd hook so that I can print my HTML only to a page with a specific category.
Just use $article->getPage()->getCategories() in the header hook.
Haven't really got the exact solution of the question I asked but has got the way out to solve the problem I have been facing.
I just tried getting the current categories in the "onArticleViewHeader" itself by using some of MediaWiki's global variables.
global $wgOut;
$title = Title::newFromText( $wgOut->getPageTitle() );
$categories = $title->getParentCategories();
if(isset($categories['Category:my_cat_name']){
//formed my logic here
}
This might help some other people facing this kind of issue.
Setup
I want to transfer data from my project to a TYPO3 instance. Assume I have an HTML export that generates about 20 different HTML files inside my TYPO3 directory. These files contain data from a different system and the data updates quite frequently, so I am overwriting them regularly with the newest information.
Problem
I would like to tell TYPO3 to load the HTML contents of each file as its own page. Please note: the pages are not complete html documents (no <html> or <body> tags). Instead, I want whatever code is in those files to be displayed inside the context of a TYPO3 page. Kind of like a TYPO3 HTML PageContent, but I want the source for the HTML to be from a file.
I don't care if I have to manually set up each page, but I haven't found any way to let a TYPO3 Page or PageContent get its data from a file. Do you know of any way this would be possible?
Note: iframe isn't a solution in my case. I am using TYPO3 7.6.23
My answer is based on the following assumptions:
You have you have a "frontend provider extension" EXT:yourext; if not you can change every path like EXT:yourext/Resources/Private/Etcetera with the proper ´fileadmin/etcetera/Resources/Private/Etcetera´
You use backend_layout on database to store the backend layout and use that field to control the frontend template. I don't remember if in version 7 you can also use the filesystem using key.data=pagelayout
of course you have to adjust the IDs of the backend_layout items
the files to include will be partials, stored in the folder EXT:yorext/Resources/Private/Partials/ and will be named
MyFileToIncludeOne.html
MyFileToIncludeTwo.html
et cetera
The basic TypoScript will be something like:
page.10 = FLUIDTEMPLATE
page.10{
templateName= TEXT
templateName.stdWrap {
cObject = CASE
cObject {
key.data = levelfield:-2,backend_layout_next_level,slide
key.override.field = backend_layout
//I assume you already have some templates
1 = TEXT
1.value = Default
2 = TEXT
2.value = Home
//The layouts for the "pages with html files" begin here
10 = TEXT
10.value = MyFileOne
11 =TEXT
11.value = MyFileTwo
}
}
layoutRootPaths {
0 = EXT:yourext/Resouces/Private/Layouts/Page/
}
partialRootPaths {
0 = EXT:yourext/Resouces/Private/Partials/Page/
}
templateRootPaths {
0 = EXT:yourext/Resouces/Private/Template/Page/
}
}
So, in the previous lines,
the template MyFileOne.html will include the partial MyFileToIncludeOne.html, with just writing in it:
<f:render partial="MyFileToIncludeOne"/>
You could also use distinct paths if you want to keep the files separated:
partialRootPaths {
0 = EXT:yourext/Resouces/Private/Partials/Page/
1 = fileadmin/some/other/path/
}
I hope I have not forgotten important passages. Feel free to ask for clarifications
In recent MediaWiki it does not seem possible to enable wikitext in the Sidebar, at least in Vector Skin. Wikitext allows more advanced formatting and insertion of images.
The only solution I have found is to install the CustomNavBlocks extension ( http://www.mediawiki.org/wiki/Extension:CustomNavBlocks ) but in MonoBook skin this forces images inside each box inside the Sidebar.
Is there a better way to enable wikitext globally for all skins?
The Sidebar is entirely the responsibility of the skin, so there is really no guaranteed way of modifying its behaviour across all skins.
However, most skins (and all built in ones) call the SkinBuildSidebar hook at the end of rendering the sidebar, so one way to build an extensions for modifying the sidebar would be to add some parser there, that handles some extra markup that you invent for that very purpose.
$wgHooks["SkinBuildSidebar"][] = "fnSidebarMultiLevel";
function fnSidebarMultiLevel(Skin $skin, &$bar) {
global $wgOut;
$title = Title::makeTitle(NS_MEDIAWIKI, "Sidebar-Custom");
if ( !$title->exists() )
return true;
$text = WikiPage::factory($title)->getContent()->mText;
$firstValue = reset($bar);
$firstKey = key($bar);
unset($bar[$firstKey]);
$bar = array(
$firstKey => $firstValue,
"Custom" => $wgOut->parse($text)
) + $bar;
return true;
}
Add wikitext to wiki.com/wiki/MediaWiki:Sidebar-Custom. "Custom" block will be second.
I have a textarea wherein the user can enter any kind of HTML (and that includes javascript). After that, I allow the user to preview it in his browser. The way that works is by POSTing the content to a page that displays the said content in a "template" kind of thing. The backend's in PHP.
Page 1
an HTML form that simply has a textarea
Page 2 (where the form gets submitted)
PHP code to echo the HTML entered in the textarea unmodified,
with an intention of keeping all HTML formatting as-is
Now, I'm aware of XSS. But my intention here is to only allow that particular user to preview whatever he's written. The content he enters won't be stored or shown to other people.
Since I'll be allowing anonymous users, my idea was to use a simple CSRF-like protection to ensure that only the user who generated the preview can view it.
That's the basic idea. I want the user to be able to preview arbitrary HTML of his choosing, while not opening up potential security holes. Is there any security aspect I'm overlooking?
I assume that in your code, there is an AJAX call submitting the content and it gets converted and comes out. So, in your PHP file, while outputting the code, give this.
Method #1: HTML Safe
<?php
...
$output = /* The final output */;
$output = htmlspecialchars($output);
die ($output);
?>
Method #2: Stripping certain tags
<?php
...
$output = /* The final output */;
$aDisabledAttributes = array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavaible', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragdrop', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterupdate', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmoveout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload')
$output = strip_tags($output, "<p><a><b><i><em><strong><table><ul><ol><li>");
die ($output);
?>
There may be a better way of doing this, but currently I have an nicely encapsulated, JavaScript object which can have some configurable options. I include a chunk of HTML code on a page (via Dreamweaver 'snippets'), and on page load my JS file runs through the DOM and identifies any of those code chunks as a particular functionality, and goes ahead and sets that functionality up.
That's all fine up until I wish to add more than one object on a page, and have them be configurable. The important point here is that you can add as many of these objects onto a page as you like with my current setup - because they're generic at that point, and have no 'id' attribute.
Now I wish to configure these objects, so I thought, "How about an external file containing the config settings, which these objects check for and apply if a config object is found". This works fine too, but the config data feels a bit 'removed' now. I imagine this will be annoying for my other colleagues eventually, it's just another Thing To Remember.
So to my question, I'm happy to insert these code blocks which will still trigger self-instantiating objects on page load - but what I'd like to try is also inserting a script block which contains the config settings. I need a means of that inserted code block knowing that its parent element is the context for configuration.
Example code:
<div class="snippet">
<_contents of this 'snippet'_/>
<script type="text/javascript">
new Snippet().init({
rootElement: REFERENCE_TO_THIS_SCRIPT_TAGS_PARENT_NODE,
configOptionA: true,
configOptionB: false
});
</script>
</div>
Note: The <div class="snippet"> has no 'id' attribute on purpose, because I want to allow for more than one of these to be dropped onto a page.
Other solutions welcome, so long as they adhere to my few restrictions!
My other related question (now answered) addresses this now, essentially I ended up with:
<div class="snippet">
<elements... />
<script type="text/javascript">
var tmpVarName = 'configOb_'+Math.floor(Math.random()*1111111) ;
document[tmpVarName] = {
remainVisible:true,
hoverBehaviour:false
};
</script>
</div>
...and then in a script loaded on every page, which scans for any appropriate elements to instantiate and config:
var snippets = yd.getElementsBy(function(el){
return yd.hasClass(el, "snippet");
},null,document );
for( var i=0; i<snippets.length;i++ )
{
var s = snippets[i] ;
yd.generateId(s, '_snippet_'+i );
var tag = yd.getElementBy(function(el){
return true;
},'script',s );
var ob = new Snippet();
ob.setId( s.id );
ob.init( eval( tag.innerHTML ) );
}
For a more complete context of the above code;
yd = YAHOO.util.Dom
Snippet.init() and Snippet.setId() are exposed methods on a Module object called Snippet()
Now that my inserted 'chunks' of content have no id attribute, and dynamically evaluated, contextual config objects - I am free to add as many variants as I like. My only real concern is performance if a whole bunch of these Snippet() objects are added to my page (not likely).