Mediawiki inline template creation - mediawiki

Is it possible to create a wiki page, where you mark a single piece of text as a placeholder which can be put anywhere else on the wiki?
Let's say I have a wiki page containing a simple list. The first item in list must be always shown in the Main Page but the editing user should not edit two pages for that, just one page.
The list page:
Pineapples
{{SaveThisText|TodaysMeal|Dumplings}}
Beans
Oranges
Main Page:
Today, we'll have {{GetSavedText|TodaysMeal}}
...Main Page will result to "Today, we'll have Dumplings"
I know that it is possible to do this using templates but I want to avoid them, I want to edit the template like it's a part of page.

You can do this without writing any custom PHP, see:
http://www.mediawiki.org/wiki/Extension:Variables

This is definitely possible if you write a MediaWiki extension for it. This means that you could place a hook on GetSavedText and SaveThisText so their behaviour can be customized.
If you have a small wiki, you could just cycle through every page on the occurance of GetSavedText an search for {{SaveThisText|TodaysMeal|. Getting every page is easy:
// get existing pages
$db = wfGetDB ( DB_MASTER );
$results = $db->resultObject ( $db->query(
"select distinct page_title from {$wgDBprefix}page " )
);
$existing_pages = array();
while ( $r = $results->next() )
$title = Title::newFromText( $r->page_title );
$article = new Article ( $title );
$content = $article->getContent();
A more efficient approach would be to place a hook on the update of a page. If SaveThisText is present, you could update a line in a database table.

Related

List of forward links on mediawiki page

I am using a Mediawiki site as a personal Zettelkasten. The zettelkasten is basically a collection of notes that should be linked to one another, making a wiki a good place to store one. The linking between the notes is the key feature of the zettelkasten. So for each "note" (i.e., page on my wiki), I need a list of 1) how to get to that page and 2) where you can go from that page. The first part is easy, since I can use the built-in {{Special:Whatlinkshere/{{PAGENAME}}}}. However, I can't figure out how to create a similar list of forward links from each page. Is there a way to do this within mediawiki, or an extension that can do this? What is the best way to gather a list of all (internal) links on a given wiki page?
If you install DynamicPageList3, you can use {{#dpl: linksfrom = {{FULLPAGENAME}} }}.
With Scribunto, you can define Module:Links with inner function:
local p = {}
function p.inner (frame)
local wikitext = frame:preprocess (mw.title.new (frame.args [1]):getContent ())
local link_set = {}
-- Find all occurences of [[...]]:
for title in mw.ustring.gmatch (wikitext, '%[%[([^%#|%]]+)%]%]') do
-- Remove #... or |...:
title = mw.text.trim (mw.ustring.gsub (title, '[#|][^%]]*', '', 1))
if title ~= '' then
link_set [title] = true
end
end
local links = {}
for link, _ in pairs (link_set) do
links [#links + 1] = '[[' .. link .. ']]'
end
table.sort (links)
return table.concat (links, ', ')
end
return p
and call it like this: {{#invoke:Links|inner|{{FULLPAGENAME}}}}. But this is expensive, and you mat need to filter titles better, if you have Semantic MediaWiki installed. There also will be issues with synchronisation (the list of links will be one version behind the page it is in, until a purge).

MediaWiki - Searching based on PageID

I'm using MediaWiki at work and creating a Knowledge Base. We've got everything set up but one requirement is to have a unique identifier on each page, then it can be referenced in official documentation. I've done this by using the magic word {{PAGEID}} so it's added to the bottom right of each page.
Another requirement is to be able to find the page based on this unique number but when using the built in search function the page can't be found.
For example, the main page has the text "Page ID:1" in the bottom right corner. When doing a search for "Page ID:1" nothing can be found and the Wiki only gives me the option to create the page.
Does anyone know how you can either search on, or have the search include the Page ID?
Any help would be appreciated.
global $wgHooks;
$wgHooks['SearchGetNearMatchBefore'][] = function ( array $allSearchTerms, &$titleResult ) {
$searchTerm = $allSearchTerms[0];
if ( preg_match( '/^id:\d+$/', $searchTerm ) ) {
$pageId = (int)substr( $searchTerm, 3 );
$titleResult = Title::newFromID( $pageId );
return false;
}
};
will jump to the page with ID 123 when you enter id:123 in the search box. Seems like a silly way to use search though.

Recommendations for populating formatted content pages from the database

I'm working on my first laravel project- a family tree website. Everything's going great with the normal models/controllers/views, but I've gotten to a special case that I'm not sure how to approach. I have about a dozen auxiliary stories that go along with specific people or families- this is extra stuff that most records don't have.
In my previous incarnation of this site, I had a stories table with a headline, source for the material, and a slug, I made an html page for each story, and then I'd link to that page using the slug value.
In Laravel this seems like a really clunky way to go about it (especially as I add more stories), because it's messy to have to make a new route/controller/view for each one.
So I've made a general StoryController and view in hopes of reusing that to display the contents of any story. I've added a 'text' column into my stories table for those contents, and I've copied the HTML (with the problematic characters escaped). But of course when I display this story text on the view, I see all the markup tags displayed themselves (instead of helping to render the actual text in paragraphs, etc).
So two questions: is there a way to treat the field as html itself (instead of a string)? And is my approach off-base and I should do this a different way?
Thanks in advance for any help!
Update: thanks to The Happy Mamba, it works if I call to another function for html_entity_decode and echo out the results, but weirdly it DOESN'T work if I 'return' the results (or do it in the same function). It didn't render the tags until I did it like so (in StoryController):
public function convert($string)
{
echo (html_entity_decode($string));
}
public function show($id)
{
$story = Story::find($id);
$content = StoryController::convert($story->text);
return view ('story/show', compact('story', 'content'));
}
The snag there is that because it's using echo, that field is displayed first no matter what.... so if I can't get around that I'll need to conversion in and out of the database as suggested (still need to get the Connection string working)- but this is a great step forward!
Have you tried pulling it out of the database and then sending the text to htmlentities?
Here's some code to test it. Examples are in postgresql but should work the same with PDO/laravel specific functions:
<?php
$conn = pg_connect('db connection string here');
$text = pg_escape_literal( $conn, htmlentities( '<html><head></head><body><em>test</em></body></html>' ) );
pg_query( $conn, 'TRUNCATE TABLE test' );
pg_query( $conn, "INSERT INTO test VALUES ( {$text} )" );
$result = pg_query( $conn, 'SELECT * FROM test' );
$row = pg_fetch_row( $result );
pg_close( $conn );
$string = $row[0];
echo html_entity_decode($string);
?>
Result:
bolded "test" in browser.
After trying a few things, the solution I like best is to make a partial for each story, and then dynamically include the correct one based on the story.slug. (This way I still need only one story route/show function/view, and I can update the content much more easily than if I'm cramming html into the database)

Delete the div with the contents in from mysql contents

I have this code which gets the contents from a mysql databse.
So basically, what happens is that foreach row in the database, it creates a div with the contents in. However, I want the user to be able to delete the post, but I simply can't get my head around how to do it.
This is the code:
while($row = mysql_fetch_assoc($query))
{
$contents= $row['contents'];
}
echo '<div class = "post" style = "margin-right: 300px;">'.$contents.'<br><p>DELETE -- HOW CAN I DO THIS??</p></div>';
Basically, what this does is get the contents of the row, each time. But I want the user to be able to click on delete it, and it deletes the div which has the contents, and removes it from the database.
I have tried simply to delete the div, but that deletes ALL the divs, not just the one that I clicked delete in.
How can I do this, I don't care how.
Thanks. I am sorry if there is too much info, or I ask too much.
You need to output a [Delete] link that sends the user back to the server to actually perform the delete. The deletion from MySQL will occur as a separate request. The PHP code that handles that request will have to construct a proper DELETE FROM table WHERE id = $id type of SQL statement, and then execute that. Once that is finished, you'll have to refresh the display so that item is no longer listed - easiest way would be to simply redirect back to the page that you already have.
If you add a class say "delete" to the p-tag
<p class="delete">DELETE -- HOW CAN I DO THIS??</p>
Then you could delete the div like this, for instance:
$(".delete").click(function(){ $(this).parent().remove(); });
Note:
You would still need some extra functionality, an AJAX-call for instance, to remove the post from the DB and not just from the DOM.
I have found out what to do.
Here is what I did:
while($row = mysql_fetch_assoc($query))
{
$contents= $row['contents'];
$contentID = $row['contentID'];
}
echo '<div class = "post" style = "margin-right: 300px;">'.$contents.'<br>X</div>';
And on the delete.php I have something like this:
$id = 1;
mysql_query("DELETE FROM table_name WHERE $contentID = $id");

$_SERVER[QUERY_STRING] copying itself

This is the part of the code for paging(when you see page 1,page 2...at the bottom).The $_SERVER[QUERY_STRING] is used to copy what was searched on previous page so that page number 2 displays results for same query.
The problem is that on page 2 the "query string" is added with page number &page=2 so when you click for page 3 the $_SERVER[QUERY_STRING] copies the query(which i need to be copied,eg. ?search=salad)and the page number(which is unnecessary),it looks like this &page=2&page=3
Is there any good way to do this?...it would be nice if something could change only the number of page instead copying whole word.
<a href='$_SERVER[PHP_SELF]?$_SERVER[QUERY_STRING]?start=$back'><font face='Verdana' size='2'>PREV</font></a>
$query = http_build_query(array('page' => $num) + $_GET);
printf('Prev', $_SERVER['PHP_SELF'], $query);
This uses the $_GET array, which contains all the values of $_SERVER['QUERY_STRING'] in a neat array, "overwrites" the page value of that array, then re-assembles it into a URL-encoded query string.