News:

SMF 2.1.4 has been released! Take it for a spin! Read more.

Main Menu

Integrating SMF with Mediawiki: How-To

Started by Raxx, June 16, 2006, 10:41:54 PM

Previous topic - Next topic

Raxx

Pretext-
I'm sorry, I'm only used to writing tutorials that are art-related, so I didn't really know where to start with a coding-type of tutorial. Plus this isn't really intended to be a tutorial :P So before you get confused, here's what you need to do: Just read until you get to "-----Reading and Creating Information with MySQL". For everything you read before getting to that point, you should only try to understand but not implement. After that point, things should fall together a bit better in the large code imbedded afterwards.

Being part of a community that relies a lot on both a forum and a wiki, it's an obvious choice to integrate one into the other.

Personally, I hate MediaWiki. Its structure sucks, and is hard as crap for me to understand and modify. Therefore, I decided to base most of my work on the SMF side and modify MediaWiki as little as possible. Even though I said the word "integrate", there isn't any real integration done on the user authentication side.

However, what I'm explaining in this post is how you can only modify SMF in order to get integration with MediaWiki, making it so that you don't have to touch MediaWiki's code in order to get results.

Obviously, there's the SMF bridge modification for Mediawiki (you can find it at the mediawiki website), which modifies Mediawiki only and doesn't touch SMF. This seemed like a good choice for me at first, except it was not seamless. No sir, sessions were not transferred between the two software, thus making it so that the user had to login separately to each site even though the accounts were "the same".

So, I threw the bridge away, already having thought up the solution so that it's entirely SMF instead. I noticed that MediaWiki uses cookies just as much as SMF does (obviously, in order to keep sessions), so I figured that by making SMF create the exact same cookies used by Mediawiki, when logging in, the sessions will be maintained between the two software. Well, after a lot of hacking in an assortment of pages (yeah, I'm an artist, not a programmer...I'll do my best to find all the changes I made), I got it to work pretty well, so that's why I'm here. I'm too dumb to be able to make a mod out of my changes, so if possible, someone else could take what I did and turn it into a mod. Even if someone doesn't, I hope that I can talk about it enough here so that newcomers to SMF won't have too much trouble making the changes themselves. I hope veteran users will be able to point out all my mistakes so that this "mod" can be improved upon, as well.

Ok...where to start...From the start, I had no intention of reporting what I've done to this community, so it's really difficult to come back and find all the crap I've done in the past. So, I'll try to describe in words the steps I took first.

-----Creating some Cookies
The first thing I had to do was figure out how the cookies worked, and where the cookie values were coming from. Then I had to figure out how to set those cookies-using LogInOut.php in the Sources folder of SMF. All work is done in LogInOut.php, and for this step of the process, you shouldn't have to touch any other file except LocalSettings.php.

When logging in, MediaWiki creates three main cookies, of which all of their prefixes are the database name that the wiki is using. Therefore, if the database name happened to be "Tootsie", these would be their names-TootsieUserName, TootsieUserID, Tootsie_session.

Before setting cookies, you should unset them just in case. You'd think that this is redundant since they'll be replaced later anyways, but who knows... Do this by inserting the code below first thing before any of the other code (just once, mind). Note that $_COOKIE is a global super variable (or whatever :P) used to get cookie information:

if (isset($_COOKIE['TootsieUserID'])){
setcookie("TootsieUserID", "", 0, "/");
}
if (isset($_COOKIE['TootsieUserName'])){
setcookie("TootsieUserName", "", 0, "/");
}
if (isset($_COOKIE['Tootsie_session'])){
setcookie("Tootsie_session", "", 0, "/");
}


You can find out your database name by looking at the LocalSettings.php file in your MediaWiki directory. Here's the cookies' descriptions:

1. TootsieUserName: Obviously, this is the user name of the current user. This is usually pulled from the Wiki's MySQL database. In LogInOut.php, we get the SMF user name from $user_settings['memberName'] within the Login2() function. In fact, most of the work I did was added to the Login2() function. After getting the user name, I had to place it into the proper cookie so that it could be read by MediaWiki.

setcookie("TootsieUserName", $username, time()+60*60, "/");

$username was defined somewhere around line 378, so I just used that instead, though it uses $user_settings['memberName']. For pretty much all of my Login2() work, I put everything at around line 384 (past the Bam! comment).

2. TootsieUserID: This is the User ID, pulled from the Wiki's MySQL database. This is where things get tricky. Since I'm not going the route of modifying the Wiki's structure, this integration relies on two separate databases. Therefore I can't just use $user_settings['ID_MEMBER'] from LogInOut.php and expect to get the same ID as in the Wiki (due to users in the forum registering in a different order than in the wiki -- it's possible to install both at the same time and then modify SMF's registration module to insert the proper information into the Wiki's database based on the User's SMF ID, name, and such, but I'm giving a solution for those who have to work with old and currently used installations).

So what do we do? Well, we pull the information from the Wiki database, of course! But only if the information exists. If it doesn't exist, we have to create it. This applies also to the UserName and _session values, so I'll cover how to read and create the information after the setting of cookies is covered. Assuming that $wiki_user_id is the variable that contains what we got from the database, here's the cookie we make:

setcookie("TootsieUserID", $wiki_user_id, time()+60*60, "/");


3. Tootsie_session: I feel that this is one of the more important cookies, and also believe that it's based on a dynamic value created every time a person logs in. Or it should be. I have not yet fixed it so that _session is changed every time a user logs in, in my current "mod". Therefore I'll assume it's fixed in this explanation. The _session value is a randomized, md5'ed value that's compared to the user_token value in the database. Obviously, this is to help prevent those idiots who want to log in as someone else by changing their cookie information. Here's the cookie that we make, assuming that $wiki_session_id is what we stored the information in.

setcookie("Tootsie_session", $wiki_session_id, time()+60*60, "/");


That's all we need to do now with the cookies. There's a few more cookies we'll need to set later on in order to make this trip feel more seamless, however.

-----Reading and Creating Information with MySQL
I am definitely not someone to go to when it comes to MySQL questions. In fact, I knew nothing about MySQL before I undertook this task, and only learned the bare minimum along with a little bit of cheating (thanks, phpMyAdmin, for creating the queries I needed...;)). So if you have MySQL troubles, don't ask me. If you see flaws in my MySQL stuff, don't just tell me, fix it yourself, post it, and save me the headache ;)

We're going to cover reading and writing the MySQL information at the same time, since it's cheaper that way :P Here's all of the code for the MySQL stuff, I'll try to explain what I'm doing the best I can, using comments within the code. Note that I'm including the other code mentioned above, to show where they should be located, and that I haven't yet made it dynamically assign the _session every time the user tries to login. I'll come back and fix that later. The top two lines are found in LogInOut.php, and exists in this code to show you where you should be placing everything:

// Bam!  Cookie set.  A session too, just incase.
setLoginCookie(60 * $modSettings['cookieTime'], $user_settings['ID_MEMBER'], sha1($user_settings['passwd'] . $user_settings['passwordSalt']));

// My Code Begins

if (isset($_COOKIE['TootsieUserID'])){
setcookie("TootsieUserID", "", 0, "/");
}
if (isset($_COOKIE['TootsieUserName'])){
setcookie("TootsieUserName", "", 0, "/");
}
if (isset($_COOKIE['Tootsie_session'])){
setcookie("Tootsie_session", "", 0, "/");
}

//Retrieving information from Wiki Database!!!
$wikiusername="USERNAME";
$wikipassword="PASSWORD";
$wikidatabase="Tootsie";

mysql_connect(localhost,$wikiusername,$wikipassword);
@mysql_select_db($wikidatabase) or die( "Unable to select database");

// Here's the first important part. Basically, we're gathering all the
// information from the "user" row where the user_name column in the database
// contains the value equal to $username.

$result = mysql_query("SELECT * FROM user WHERE user_name='" . $username . "'");

if(!$result)die("Query Failed.");
while($row = mysql_fetch_assoc($result)) {

// Here, we're taking the information from that row, and assigning them to the
// variables that are going to be used in the cookies. We don't need the user
// name since we already have it from SMF, but we do need to toss the user name
// into a variable for the next step...

$wiki_user_id = $row['user_id'];
$wiki_session_id = $row['user_token'];
$wiki_user_namez = $row['user_name'];
}

// This is the only successful method I could use in order to see if the row exists
// or not. The If statement is basically saying that if the value we got from the
// database doesn't equal the value from SMF, then the row does not exist. Therefore
// we need to create the bare minimum information so that the wiki account exists and
// we can authenticate the session using it.

if ($wiki_user_namez !== $username){

// Here, we have to create the user's new Wiki ID. It has to be an ID not used
// by anyone else, so we simply find the highest value in the user_id column,
// and raise it by one.

$result2 = mysql_query("SELECT `user_id` FROM `user` ORDER BY `user_id` DESC LIMIT 0, 1");
if(!$result2) die("Query Failed.");
while($row2 = mysql_fetch_row($result2))
{
$wiki_last_user_id = $row2[0];
$wiki_last_user_id++;
}

// $tokenz is mimmicking how the _session and user_token values are created.
// Everything is pretty much exactly how the wiki creates it, except that the
// long "45cef36..." value is unique to each installation (I think :P), assigned
// to $wgProxyKey in LocalSettings.php in your wiki directory. Find the value and
// plug it in instead of the one I'm using. It should be 32 digits long. Tootsie
// should be replaced by the name of your database (or really, anything actually,
// but let's keep it consistent with the way the wiki does it, for now). $ID_MEMBER
// was assigned earlier by Login2() so don't worry about it.

$tokenz = md5( '45cef36c3157932446d4a112499626ccac431637226a44f0d29356b3346a3' . mt_rand( 0, 0x7fffffff ) . 'Tootsie' . $ID_MEMBER );

// Now we're inserting the information we've gathered into the database. There's
// a variety of ways to do this in mysql, but I decided to do it this way. I'm not
// gonna explain much. If you want to replace some of those blank values with ones
// taken from SMF, you'll have to figure it out yourself.

$sql = "INSERT INTO `user` (`user_id`, `user_name`, `user_real_name`, `user_password`, `user_newpassword`, `user_email`, `user_options`, `user_touched`, `user_token`, `user_email_authenticated`, `user_email_token`, `user_email_token_expires`, `user_registration`) VALUES (" . $wiki_last_user_id . ", '" . $username . "', '" . $context['user']['email'] . "', '', '', '', '', '', '" . $tokenz . "', NULL, NULL, NULL, NULL);";
mysql_query($sql);

// Um, yeah. I don't know if calling those variables as global is important or not,
// or if I just forgot to delete that line. So it's stayin' in there :P Otherwise,
// in the third line down, we're assigning $wiki_session_id with the proper value
// so that we can authenticate off of new accounts correctly.

global $wiki_last_user_id, $wiki_user_id;
$wiki_user_id = $wiki_last_user_id;
     $wiki_session_id = $tokenz;
}

mysql_close();

//This is the actual place you should insert your cookie code

setcookie("TootsieUserID", $wiki_user_id, time()+60*60, "/");
setcookie("TootsieUserName", $username, time()+60*60, "/");
setcookie("Tootsie_session", $wiki_session_id, time()+60*60, "/");


That's pretty much everything for now. There'll be some things to add to this code later, of course. Completely seamless integration is far from complete. Oh, btw, if you don't like the way I write PHP, don't waste time complaining about it; make it prettier yourself and post it here ;)

Now, when you visit your forum with your browser and log in, you should find that three cookies are created in your browser (so long as you have cookies turned on). When you visit the wiki, you should find that you're logged in.

I've gone on and done a whole lot more by modifying MediaWiki and SMF both:

1.Removed the login/logout links in Mediawiki, making it so that you can't login with MediaWiki's system at all (adding a quick login function using SSI.php is easy enough, however).
2. Added the menu bar using SSI.php and modified the logout function it uses so that it logs out the user correctly and redirects the user to the last page he visited (regardless of it's in the wiki or forum), and deletes the cookies in the process.
3. I added the MediaWiki link to the top menu bar and modified the menu bar function so that it detects if the active page is the MediaWiki, thus highlighting the MediaWiki menu item.
4. I've gone so far as to almost completely mimmick the forum's skin (a heavily modified bluBlur skin) and header in the Wiki so that it seems seamless visually.

-----I would show you the site I'm working on, but there's also a few other "mods" that aren't perfect yet, so I'd rather have a completely finished site without flaws to showcase. The other mods are art-related, and basically implement the features found in CGTalk and more:

1. Image banner above the content area, the top horizontal image strip contains 5 images like seen at cgtalk.com, showcasing users' works that are outstanding. The user who owns the topic that the image links to receives an interface above the first post where he can change/update the image, of which it obviously gets reflected in the image strip.
2. Underneath that strip are 12 or so smaller thumbnail images showcasing any user's artwork that they post as attachments. Underneath that strip will be even smaller ones showcasing 35 or so User's galleries that they create using the Mediawiki. Each image links to the proper pages automatically, and the images are ordered so that the most recent are listed first, with older ones dropping out.
3. In the topic display page(s), the message icons are replaced by a thumbnail version of the user's avatar, if the user has one, fitted so that it doesn't work against the message icon column. In art-related boards, the avatars are superceded by a thumbnail version of the latest image the Author attached to that topic, otherwise it shows the avatar, and if that doesn't exist, then it shows the message icon.

All images and thumbnails are overlayed by graphics that frame the image and match the current theme, automatically using GD or ImageMagick. I've also tested automatically embedding text based on the user information onto the image and frames, and it works well (such as embedding the name of the author and the topic's title onto the image in a fancy and effective font, rasterized of course).

There's more mods that I plan on implementing as well. For all these mods, I'd like to post topics about like the way I'm doing it for this one. I find that a lot of professional art-related sites use vbulletin (commercial) as their forum software, but with a little bit of work I believe SMF can match vbulletin any time.

Anyways, I ain't done with this topic yet. I'll explain the other Mediawiki/SMF modifications as soon as I can. I don't care if these methods have already been used/covered or denounced in the past, what harm can more information do? Feel free to post your thoughts, I'm pretty sure there's cleaner ways of doing this.

Raxx

#1
Oh darn, people were actually offering money for this kind of mod. If I brushed it up, I could have been paid :P

Anyways, to make this post more useful, here's how to remove the login/logout links in Mediawiki, making it so that you can't log in or out with MediaWiki's system at all (this is with the mindset of using SMF's menu bar to log in or out instead -- If you're not going to use the menu bar or logout via SMF, you'll have to figure out how to modify the Wiki's logging in and out functions).

Go to line 490 of /includes/SkinTemplate.php in your Wiki directory and delete this code:

$personal_urls['logout'] = array(
'text' => wfMsg('userlogout'),
'href' => $this->makeSpecialUrl( 'Userlogout',
$wgTitle->getNamespace() === NS_SPECIAL && $wgTitle->getText() === 'Preferences' ? '' : "returnto={$this->thisurl}"
)
);


Go to line 513 and delete this code:

$personal_urls['anonlogin'] = array(
'text' => wfMsg('userlogin'),
'href' => $this->makeSpecialUrl('Userlogin', 'returnto=' . $this->thisurl ),
'active' => ( NS_SPECIAL == $wgTitle->getNamespace() && 'Userlogin' == $wgTitle->getDBkey() )
);
} else {

$personal_urls['login'] = array(
'text' => wfMsg('userlogin'),
'href' => $this->makeSpecialUrl('Userlogin', 'returnto=' . $this->thisurl ),
'active' => ( NS_SPECIAL == $wgTitle->getNamespace() && 'Userlogin' == $wgTitle->getDBkey() )
);


That's it! Next will be how work the menu bar properly.

Dannii

Have you got the themes integrated? I was planning on doing this, but since mediawiki's code is so horrid I change to dokuwiki.
"Never imagine yourself not to be otherwise than what it might appear to others that what you were or might have been was not otherwise than what you had been would have appeared to them to be otherwise."

Raxx

#3
Regarding theme integration, I don't think it's possible to program MediaWiki's skinning system to automagically adapt to any SMF theme out there. I feel that if someone has to integrate forum software with wiki software, then their site is a rather large and important project; therefore the theme would probably need to be customized, making low-level automation impractical.

It does take a bit of work and messing around. As I stated before, however, I've almost completely finished transferring the modified bluBlur theme over from SMF to Mediawiki ("almost" because I had to take a bit of a break from it). This may seem like a chore to some people, but considering that I have had no real prior experience with MySQL, PHP, and CSS (and even javascript...), I was able to make it almost seamless with a transferred theme in a matter of days.

MediaWiki relies more heavily on CSS than SMF does, but it's relatively easy to take, say, the content block of the Wiki and place it into a div, and then move that div anywhere you need to (or even place it in a table), and then take the navigation menus and place those as needed, etc. All it takes is a little logic and a little tinkering around for beginners. The main files you need to modify in the Mediawiki are "/skins/Monobook.php" and "/skins/monobook/main.css", where you replace "monobook" with the name of the skin MediaWiki is using (optionally, you could copy and paste the main.css data into MediaWiki:Monobook.css, delete main.css, and thus be able to modify the css within the Wiki itself), should the current installation not use Monobook by default (doesn't matter what skin you pick to modify, since you'll be changing it almost completely).

The next topics I will be covering will demonstrate some of the ways to transfer the SMF features over to MediaWiki using SSI.php and cookies.

Raxx

#4
A member of this community brought to light one of the more obvious features users might want when using SMF and MediaWiki combined together: The ability to call up SMF information from within articles themselves.

Now, I'm not going to tell you how to do this until after I create the MediaWiki extension for all the SSI.php functions and publicly release them; simply because, well...I prefer to avoid avoidable questions :P

Before I modified this post, it was just a simple matter of including SSI.php in the <head> tag of Monobook.php. With the MediaWiki extension on the horizon, this method will have to be scrapped for a more flexible one. This is a good thing, however, since the new method is skin independant.

Ok, on to how to integrate SMF's features using SSI.php.

Now then, here's how it works: We need to include SSI.php somewhere so that when we need to display content anywhere in the page, the information will be there ready for us. Those of you that are familiar with MediaWiki would probably have already tried including SSI.php into your LocalSettings.php file. It should be obvious when you try it out, but doing so gives you an ini_set error that can't be ignored. The php function, ini_set can't be modified after session_start() is called. SSI.php makes this call from Load.php on the SMF side of things, therefore creating the error.

What then? Well, we have to delve deeper into the includes directory, picking out User.php.

You should find a function, SetupSession(), somewhere around line 615, that looks like this:

function SetupSession() {
global $wgSessionsInMemcached, $wgCookiePath, $wgCookieDomain;
if( $wgSessionsInMemcached ) {
require_once( 'MemcachedSessions.php' );
} elseif( 'files' != ini_get( 'session.save_handler' ) ) {
# If it's left on 'user' or another setting from another
# application, it will end up failing. Try to recover.
ini_set ( 'session.save_handler', 'files' );
}
session_set_cookie_params( 0, $wgCookiePath, $wgCookieDomain );
session_cache_limiter( 'private, must-revalidate' );
@session_start();
}


Fortunately for us, SetupSession() is used only once every page load (or should be), and also is set up so that it's fairly easy to modify to our needs.

What we'll want to do is comment out the line, @session_start();, and right before it insert the line, include("SSI.php");. Here's what it should look like:

function SetupSession() {
global $wgSessionsInMemcached, $wgCookiePath, $wgCookieDomain;
if( $wgSessionsInMemcached ) {
require_once( 'MemcachedSessions.php' );
} elseif( 'files' != ini_get( 'session.save_handler' ) ) {
# If it's left on 'user' or another setting from another
# application, it will end up failing. Try to recover.
ini_set ( 'session.save_handler', 'files' );
}
session_set_cookie_params( 0, $wgCookiePath, $wgCookieDomain );
session_cache_limiter( 'private, must-revalidate' );
include("SSI.php");
# @session_start();
}


This should fix the problem, and also make it so that SSI.php's features can be accessed from anywhere inside the page. If you get results otherwise, please say so.

Well, that is pretty much it, if this was a barebones tutorial. I'll try to explain a little bit more on how you can make use of the new slew of SSI.php content that awaits you.

I would like to make it clear to you that including SSI.php doesn't just mean you only get functions, you get almost all the information and variables that are stacked in the SMF forum. This means that you can simply echo "$context['user']['name']", and it'll give you your logged in name. If you want to test to make sure SSI.php is being called correctly, try placing this slip of code right before the </body> tag in Monobook.php (or whatever skin_name.php file you're using):

<?php
                  
global $context;
 if ($context['user']['is_guest']) {
  $smf_name "Guest";
 }
 else {
  $smf_name $context['user']['name'];
 }
  echo 'Hello! Mr. ' $smf_name;
?>



Now, at the bottom of the wiki, you should see either "Hello! Mr. Guest" if you're not logged in, or "Hello! Mr. [yourname]" if you are logged in. This little test is just for those of you who are stuck on only using functions rather than anything else.

Now, here's a big, fat notice:

NOTICE: If you want to call up variables and information from SSI.php, you must declare them as a global first. An example of this working is seen in the code above, "global $context;". This makes sure that you can access the anything within the $context array, such as $context['user']['name'].

This does not apply to the actual functions themselves. An easy way to test if SSI.php's functions are working would be to simply place this:

<?php   ssi_menubar(); ?>

Right before </body> and expect to see the menu bar in the bottom of the page. Obviously, it will only look like a row of links unless you copy over or include the css properties.

So, what next?

Well, I'll try to explain about how the wiki lays out its content. Everything is pretty much placed in <divs>, at least in the Monobook.php skin (which really, you should just modify that skin for your needs). You have your personal toolbar items, which gives you options related to your account (or if logged out, a link to log in and an ip address thingy). You have your side menu bar items, one for navigation, one for searching, and one for your toolbox. And then you have your article area, which displays the wiki article's content. (yes, there's also a footer area, but deal with that whatever way you want :P).

Basically, it's all about slicing out the lines of code that display this content, and sticking them into whatever divs, tables, forms, or menus that you need them to appear at. Or, if you don't want them at all, just delete 'em.

How does this relate to SSI.php? Well, you need to understand the way the content works in order to place SMF stuff into new divs, tables, forms, or menus, or appended to already existing ones.

Here's some lines of code to watch out for, if you want to edit the wiki content and put them wherever you want. Remember that the skin relies heavily on main.css, located in 'skins/monobook/'. So you'll probably have to edit that and Monobook.php (again, skin_name.php if you're not using Monobook) if you wish to modify the way the content is displayed.

Personal Toolbar

<h5><?php $this->msg('personaltools'?></h5>
<ul>
<?php  foreach($this->data['personal_urls'] as $key => $item) { ?>
<li id="pt-<?php echo htmlspecialchars($key?>"<?php
if ($item['active']) { ?>
class="active"<?php ?>><a href="<?php
echo htmlspecialchars($item['href']) ?>
"<?php
if(!empty($item['class'])) { ?>
class="<?php
echo htmlspecialchars($item['class']) ?>
"<?php ?>><?php
echo htmlspecialchars($item['text']) ?>
</a></li>
<?php ?>
</ul>


Navigation Panel

<script type="<?php $this->text('jsmimetype'?>"> if (window.isMSIE55) fixalpha(); </script>
<?php foreach ($this->data['sidebar'] as $bar => $cont) { ?>
<h5><?php $out wfMsg$bar ); if (wfEmptyMsg($bar$out)) echo $bar; else echo $out?></h5>
<ul>
<?php  foreach($cont as $key => $val) { ?>
<li id="<?php echo htmlspecialchars($val['id']) ?>"<?php
if ( $val['active'] ) { ?>
class="active" <?php }
?>
>sss<a href="<?php echo htmlspecialchars($val['href']) ?>"><?php echo htmlspecialchars($val['text']) ?></a></li>
<?php ?>
</ul>

<?php ?>


Views

<h5><?php $this->msg('views'?></h5>
<ul>
<?php foreach($this->data['content_actions'] as $key => $tab) { ?>
<li id="ca-<?php echo htmlspecialchars($key?>"<?php
  if($tab['class']) { ?>
class="<?php echo htmlspecialchars($tab['class']) ?>"<?php }
 ?>
><a href="<?php echo htmlspecialchars($tab['href']) ?>"><?php
 echo htmlspecialchars($tab['text']) ?>
</a></li>
<?php  } ?>
</ul>


Search Panel

<h5><label for="searchInput"><?php $this->msg('search'?></label></h5>

<form action="<?php $this->text('searchaction'?>" id="searchform">
<input id="searchInput" name="search" type="text" <?php
if($this->haveMsg('accesskey-search')) {
?>
accesskey="<?php $this->msg('accesskey-search'?>"<?php }
if( isset( $this->data['search'] ) ) {
?>
value="<?php $this->text('search'?>"<?php ?> />
<input type='submit' name="go" class="searchButton" id="searchGoButton" value="<?php $this->msg('go'?>" />&nbsp;
<input type='submit' name="fulltext" class="searchButton" value="<?php $this->msg('search'?>" />
</form>


Toolbox

<h5><?php $this->msg('toolbox'?></h5>

<ul>
<?php
if($this->data['notspecialpage']) { ?>

<li id="t-whatlinkshere"><a href="<?php
echo htmlspecialchars($this->data['nav_urls']['whatlinkshere']['href'])
?>
"><?php $this->msg('whatlinkshere'?></a></li>
<?php
if( $this->data['nav_urls']['recentchangeslinked'] ) { ?>

<li id="t-recentchangeslinked"><a href="<?php
echo htmlspecialchars($this->data['nav_urls']['recentchangeslinked']['href'])
?>
"><?php $this->msg('recentchangeslinked'?></a></li>
<?php  }
}
if(isset($this->data['nav_urls']['trackbacklink'])) { ?>

<li id="t-trackbacklink"><a href="<?php
echo htmlspecialchars($this->data['nav_urls']['trackbacklink']['href'])
?>
"><?php $this->msg('trackbacklink'?></a></li>
<?php  }
if($this->data['feeds']) { ?>

<li id="feedlinks"><?php foreach($this->data['feeds'] as $key => $feed) {
?>
<span id="feed-<?php echo htmlspecialchars($key?>"><a href="<?php
echo htmlspecialchars($feed['href']) ?>
"><?php echo htmlspecialchars($feed['text'])?></a>&nbsp;</span>
<?php ?></li><?php
}

foreach( array('contributions''blockip''emailuser''upload''specialpages') as $special ) {

if($this->data['nav_urls'][$special]) {
?>
<li id="t-<?php echo $special ?>"><a href="<?php echo htmlspecialchars($this->data['nav_urls'][$special]['href'])
?>
"><?php $this->msg($special?></a></li>
<?php }
}

if(!empty($this->data['nav_urls']['print']['href'])) { ?>

<li id="t-print"><a href="<?php echo htmlspecialchars($this->data['nav_urls']['print']['href'])
?>
"><?php $this->msg('printableversion'?></a></li><?php
}

if(!empty($this->data['nav_urls']['permalink']['href'])) { ?>

<li id="t-permalink"><a href="<?php echo htmlspecialchars($this->data['nav_urls']['permalink']['href'])
?>
"><?php $this->msg('permalink'?></a></li><?php
} elseif ($this->data['nav_urls']['permalink']['href'] === '') { ?>

<li id="t-ispermalink"><?php $this->msg('permalink'?></li><?php
}

wfRunHooks'MonoBookTemplateToolboxEnd', array( &$this ) );
?>

</ul>


Article Content

<div id="content">
<a name="top" id="top"></a>
<div id="bodyContent">
<h3 id="siteSub"><?php $this->msg('tagline'?></h3>
<div id="contentSub"><?php $this->html('subtitle'?></div>
<?php if($this->data['undelete']) { ?><div id="contentSub2"><?php     $this->html('undelete'?></div><?php ?>
<?php if($this->data['newtalk'] ) { ?><div class="usermessage"><?php $this->html('newtalk')  ?></div><?php ?>
<?php if($this->data['showjumplinks']) { ?><div id="jump-to-nav"><?php $this->msg('jumpto'?> <a href="#column-one"><?php $this->msg('jumptonavigation'?></a>, <a href="#searchInput"><?php $this->msg('jumptosearch'?></a></div><?php ?>
<!-- start content -->
<?php $this->html('bodytext'?>
<?php if($this->data['catlinks']) { ?><div id="catlinks"><?php       $this->html('catlinks'?></div><?php ?>
<!-- end content -->
</div>
</div>


Ok, wrapping it up...

If you want to add a new panel containing some sort of SMF feature, perhaps above the navigation panel, simply copy and paste the navigation panel code, swap out the content within the <divs>, modifying it to your liking, and also copy and paste the CSS properties that it uses and give them unique names that only the new panel uses, and then touch up and edit to your liking. That is the easiest way to learn how things work.

Some day soon, I'll have an extension posted here, and also a tutorial on how to get started using it, so that you can access your lovely SMF stuff from within an article ;) Remember though, if you enable php parsing for mediawiki, then you can call things from SSI.php without needing the extension. This is a big security risk, however, so it'd be best to wait for the extension (or if you're an uber php programmer that can program at the speed of light, make your own extension before mine is released :P)

Remember to back up your work often, save often, and try before you cry.

Raxx

Just a small notice, I made a huge edit to the previous post, so those who read it before should take another look at it.

Mr. Doug

I'm looking for something similar with PMWiki that would only allow users in a certain group, or with a number of posts to edit pages.

eg:

Users in the "Wiki Editor" group would be allowed to ADD wiki pages.
Users with more than 100 posts would be able to EDIT wiki pages.
(Alternatively "Wiki User" group would also be able to edit pages as well.)
--
Doug Hardman
doug (at) puttertalk (dot) com

Dragooon

ok one extremely uber-noob question do i have to install mediawiki before using this method???Like what they have said in Installation guide....

Jim R

Anyone having any luck extending SSI functions over MediaWiki pages??? 

I've had success at restricting who can see my Wiki pages using SSI, but as far as extending stuff like Board News or Recent Topic, I can't make heads or tails of it. 

URPG

Is there a Site, where i could have a look at an integrated forum? Currently i am working with MediaWiki mod for user integration and putting my SMF into an iFrame. All in all it sucks and this does - at least at first - look better. Like to see it in action, please!

Incognitus

Tried the solution you speak about on your second page, it removes the init_set error, but when I use a SSI function from a MediaWiki extension, it blows up with this error:

Fatal error: Call to undefined function I() in /home/thinkfnw/public_html/forumbolsa/SSI.php on line 370

Advertisement: