Perhaps this is hokey, but what about adding a "tags" element to a post like del.icio.us? Then, use the tags for the keywords field. It wouldn't add much bloat really, and you could let admins turn it on/off. Just an idea.

OPML, or Outline Processor Markup Language, is an xml standard for creating nested outlines. It is used by rss news-readers to index and import a list of rss feeds. To make it open in a news-reader, you should try

<a href="feed:opml.php">OPML</a>

According to my research, opml files will only open properly in newsreaders if the extension is opml. So the recomendation here is after you have finished your forums outline, you copy the output from opml.php into a text file and upload it to your server with extension ".opml" and add the feed link to your forums.

OPML can also be added to the header tag of you forums template using the <link rel="">

<link rel="opml" type="application/opml+xml" title="Forums" href="http://myweb.com/forums/opml.php" />

That should work for auto-discovery.

If you have more rss feeds, a blog, etc., you can create a second opml by copying the other opml, and adding the links at the top

copy & paste head from /forums/opml.php here
<outline text="Blog" type="rss" url="http://myweb.com/">
  <outline text="Topic 1" type="rss" url="">
</outline>
The rest of your forums/opml.php file copied here

Then you can save it as whatever.opml and put a feed:whatever.opml link to it on the front page of your site and in the header of your page.

OPML can be used for a lot more. I would love to see you use it it the Wiki plugin you are working on. The entire outline of the wiki could be entered/imported/exported in OPML. By using the type="" reference, you can refer to images, video, etc. There is also a desc tag for adding more text descriptions text.

More fun with punbb and xml comming soon :-)

shinko_metsuo wrote:

What would I need to edit to get avatars in the news page?

Disclaimer: I haven't used the mini-portal yet, but I'm making a little news blog for the front page of my site, and I wanted avatars to appear in news posts, so this is a hack of my hack for your use. I also assume that since you have the user-name of the person who posted, you have access to the user-id from the post. I will assume this is loaded into $id.

$rel_path="http://path-to-your-forums.com/forums/";
$user_avatar = '';     

        if ($img_size = @getimagesize($rel_path.$pun_config['o_avatars_dir'].'/'.$id.'.gif'))
                $user_avatar = '<img src="'.$rel_path.$pun_config['o_avatars_dir'].'/'.$id.'.gif" '.$img_size[3].' alt="" />';
        else if ($img_size = @getimagesize($rel_path.$pun_config['o_avatars_dir'].'/'.$id.'.jpg'))
                $user_avatar = '<img src="'.$rel_path.$pun_config['o_avatars_dir'].'/'.$id.'.jpg" '.$img_size[3].' alt="" />';
        else if ($img_size = @getimagesize($rel_path.$pun_config['o_avatars_dir'].'/'.$id.'.png'))
                $user_avatar = '<img src="'.$rel_path.$pun_config['o_avatars_dir'].'/'.$id.'.png" '.$img_size[3].' alt="" />';

To display the avatar, simply use

echo $user_avatar;

If there is no avatar for this user, $user_avatar will still equal a null string ("") and therefor display nothing.

You can probably get rid of the $rel_path as long as you are in the forums root, but this will make sure it will work if called from another directory which is my needs. :-)

This is a simple mod to this existing mod to add categories to your messages based on your Category/Forums structure. Category will be in the form:

<category>Category/Forum</category>

TO DO: add a category listing to the <channel> header function, so when you do a rss.php?cid=3 or rss.php?fid=1, the appropriate category/forum is listed, otherwise the default category is picked.

Other possible mod: add an array to translate your cat_id's and forum_id's to standardized category descriptions


after:

    $data = "Topic: ".parse_message($cur['subject'],0)."\n\nMessage: ".parse_message($cur['message'],0);
    echo "<description>".encode_xml($data)."</description>\n";
//    echo "<content:encoded><![CDATA[".$data."]]></content:encoded>\n";
    echo "<pubDate>".strval(date("r",$cur['postposted']))."</pubDate>\n";

add:


    $cat2=trim(preg_replace('/\s\s+/', ' ', $cur['forum_name']));
    $cat2=str_replace("&", "and", $cat2);
    echo "<category>".$cur['cat_name']."/".$cat2."</category>\n";

Here is the code I used to generate an OPML page from my forums. It creates an outline of the categories and forum structure and is loosely based on the rss 2.0 mod.

You need to change the variable $rot (root) to be the url to your forums. In the function putHeader you must edit the owner name and email. If you are not using the rss 2.0 script with forums and category feeds, you will need to make many changes so I recomend you just install the mod.

Copy & paste the code below, make the changes above and save as "opml.php" or something similar in your PUN_ROOT directory.

KNOWN PROBLEMS: I am not that great with sql, and somebody could probably make this use a single query to save time, but OPML files shouldn't be pinged as often as rss feeds, so there shouldn't be a problem. There are probably some global declarations that can be deleted from the functions, too.

Live example

<?php
// use cashing, prevents header problems
ob_start();

define('PUN_ROOT', './');
@include PUN_ROOT.'config.php';

// If PUN isn't defined, config.php is missing or corrupt
if (!defined('PUN'))
    exit('The file \'config.php\' doesn\'t exist or is corrupt. Please run install.php to install PunBB first.');

// Disable error reporting for uninitialized variables
error_reporting(E_ERROR | E_WARNING | E_PARSE);

// Turn off magic_quotes_runtime
set_magic_quotes_runtime(0);

// change this variable now!

$rot="http://www.path.to.you.forums.com/forums/";


// Load the functions script
require PUN_ROOT.'include/functions.php';
require PUN_ROOT.'include/parser.php';

// Load DB abstraction layer and try to connect
require PUN_ROOT.'include/dblayer/common_db.php';

// Get the forum config
$result = $db->query('SELECT * FROM '.$db->prefix.'config') or error('Unable to fetch forum config', __FILE__, __LINE__, $db->error());
while ($cur_config_item = $db->fetch_row($result))
    $pun_config[$cur_config_item[0]] = $cur_config_item[1];

// Make sure we (guests) have permission to read the forums
$result = $db->query('SELECT g_read_board FROM '.$db->prefix.'groups WHERE g_id=3') or error('Unable to fetch group info', __FILE__, __LINE__, $db->error());
if ($db->result($result) == '0')
    exit('No permission');


// Attempt to load the common language file
@include PUN_ROOT.'lang/'.$pun_config['o_default_lang'].'/common.php';
if (!isset($lang_common)) exit('There is no valid language pack \''.$pun_config['o_default_lang'].'\' installed. Please reinstall a language of that name.');



    
putHeader();

$result = $db->query("SELECT id, cat_name, disp_position
         FROM ".$db->prefix."categories ORDER BY disp_position ASC") 
     or error('Unable to fetch categories', __FILE__, __LINE__, $db->error());;

echo "<body>\n";


while ($cur = $db->fetch_row($result)) {
    putCat($cur);
}

echo "</body>\n";
echo "</opml>\n";

// get feed into $feed
$feed = ob_get_contents();
ob_end_clean();

// create ETAG (hash of feed)
$eTag = '"'.md5($feed).'"';
header('Etag: '.$eTag);

// compare Etag to what we got
if ($eTag == $_SERVER['HTTP_IF_NONE_MATCH']) {    
    header("HTTP/1.0 304 Not Modified");
    header('Content-Length: 0');
} else {
    // dump feed
    header('Content-type: application/xml; charset=ISO-8859-1');
    header("Cache-Control: no-store, no-cache, must-revalidate");
    header("Cache-Control: post-check=0, pre-check=0", false);
    echo $feed;
}


function putHeader() { 
    global $lang_common,$pun_config;
    echo '<'.'?xml version="1.0" encoding="ISO-8859-1"?'.'>'."\n";
    echo "<opml version=\"1.0\">\n";
    echo "<head>\n";
    echo "<title>".entity_to_decimal_value(htmlspecialchars($pun_config['o_board_title']))."</title>\n";

//
// change these 2 below
//
    echo "<ownerName>".entity_to_decimal_value(htmlspecialchars("Enter the name of the owner here"))."</ownerName>\n";
    echo "<ownerEmail>".entity_to_decimal_value(htmlspecialchars("you@your-email.com"))."</ownerEmail>\n";

//
// end changes
//
    echo "<dateCreated>".entity_to_decimal_value(htmlspecialchars(date("D, d M Y H:i:s T")))."</dateCreated>\n";
    echo "<dateModified>".entity_to_decimal_value(htmlspecialchars(date("D, d M Y H:i:s T")))."</dateModified>\n";
    echo "</head>\n";
    
} 

function putCat($cur) {
    global $lang_common,$pun_config, $rot, $db;
    
    echo '<outline text="'.entity_to_decimal_value(htmlspecialchars($cur[1])).'" type="rss" url="'.$rot.'rss.php?cid='.$cur[0].'" >'."\n";
    
    $result2 = $db->query("SELECT id, forum_name, disp_position
         FROM ".$db->prefix."forums 
                 WHERE cat_id=".$cur[0]."
         ORDER BY disp_position ASC") 
                 or error('Unable to fetch forums', __FILE__, __LINE__, $db->error());;
    
    while ($res = $db->fetch_row($result2)) {
    putForum($res);
    }

    echo "</outline>\n";
} 

function putForum($res) {
    global $lang_common,$pun_config, $rot;
    echo '<outline text="'.entity_to_decimal_value(htmlspecialchars($res[1])).'" type="rss" url="'.$rot.'rss.php?fid='.$res[0].'" />'."\n";
}



/* entity to unicode decimal value */


function entity_to_decimal_value($string){
    static $entities_dec = false;
    if (!is_array($entities_dec)) {
        $entities_named       = array(" ","¡","¢","£","¤","¥","¦","§","¨","©","ª","«","¬","­","®","¯","°","±","²","³","´","µ","¶","·","¸","¹","º","»","¼","½","¾","¿","À","Á","Â","Ã","Ä","Å","Æ","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï","Ð","Ñ","Ò","Ó","Ô","Õ","Ö","×","Ø","Ù","Ú","Û","Ü","Ý","Þ","ß","à","á","â","ã","ä","å","æ","ç","è","é","ê","ë","ì","í","î","ï","ð","ñ","ò","ó","ô","õ","ö","÷","ø","ù","ú","û","ü","ý","þ","ÿ","ƒ","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","•","…","?","?","?","?","?","?","?","™","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",""","&","<",">","Œ","œ","Š","š","Ÿ","ˆ","˜","?","?","?","?","?","?","?","–","—","‘","’","‚","“","”","„","†","‡","‰","‹","›","€","&apos;");
        $entities_decimal     = array(" ","¡","¢","£","¤","¥","¦","§","¨","©","ª","«","¬","­","®","¯","°","±","²","³","´","µ","¶","·","¸","¹","º","»","¼","½","¾","¿","À","Á","Â","Ã","Ä","Å","Æ","Ç","È","É","Ê","Ë","Ì","Í","Î","Ï","Ð","Ñ","Ò","Ó","Ô","Õ","Ö","×","Ø","Ù","Ú","Û","Ü","Ý","Þ","ß","à","á","â","ã","ä","å","æ","ç","è","é","ê","ë","ì","í","î","ï","ð","ñ","ò","ó","ô","õ","ö","÷","ø","ù","ú","û","ü","ý","þ","ÿ","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",""","&","<",">","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","'");
        if (function_exists('array_combine')) 
            $entities_dec=array_combine($entities_named,$entities_decimal);
        else {
            $i=0;
            foreach ($entities_named as $_entities_named) $entities_dec[$_entities_named]=$entities_decimal[$i++];
        }
    }
    return preg_replace( "/&[A-Za-z]+;/", " ", strtr($string,$entities_dec) );
}

?>

I had trouble that my Prev - Next month tabs at the top where showing URL's without the page name, i.e. http://something/forums/?action=???&month....


to fix this I replaced lines 63-67 of calendar.php with:

        <a href="calendar.php?<?echo $ltype?>month=<?echo $month?>&year=<?echo $year-1;?>"><–</a>
        <a href="calendar.php?<?echo $ltype?>month=<?if($month == 1){echo '12';}else{echo $month-1;}?>&year=<?if($month == 1){echo $year-1;}else{echo$year;}?>"><—</a>
        <? echo $lang_calendar[$monthtext]." ".$year."\n" ?>
        <a href="calendar.php?<?echo $ltype?>month=<?if($month == 12){echo '1';}else{echo $month+1;}?>&year=<?if($month == 12){echo $year+1;}else{echo$year;}?>">—></a>
        <a href="calendar.php?<?echo $ltype?>month=<?echo $month?>&year=<?echo $year+1;?>">–></a>

Also, if you call any PHP code within your template, I found that while viewing events some server variables where not available that are in every other page of punbb.  I needed to change any calls to SERVER_NAME in my php scripts with $GLOBAL["SERVER_NAME"], which I probably should have done from the begining.  I didn't notice the error right away because the error text was hidden in the links code like this <a href="error: call to undifined index/forums/....">Link</a>

Hope that helps people, I think my version is now bug free using these changes and the one already posted. All functions have been tested and work as of this moment. Who know about tomorrow, but that is another day of programming.

I'm trying to take an SEO approach to PunBB right now, so I'd be into it.  There is a good SEO article/crtique of phpbb that would give us a place to start

1.The first thing I am trying to do is change the Last Posts on the index.php to use the title of last post rather than the date as the link text. This places potential keywords, and words are always search friendlier than. It also makes keywords on the front page change regularly which I know google likes.

2. According to phpbb's own admission, google has devaluated any page called "viewforum.php" and "viewtopic.php" meaning they take the score they would normally give each page, and subtract from it because the page is titled viewtopic.php, so the page names should be changed at some point.

3. Another could be to try and derive keywords from forum titles and topic titles, removing "and, or, to, the" etc., and putting commas between the words, and placing it in the headers.  I've done a little experimenting, and I've found that when a link such as viewforum.php?topic=xxx is indexed by google, if the keywords, title, and description change, it will index more pages.

I know there are other, simpler mods, I just wish I could think of them right now :-)

I used a simple mod  for phpbb2 that I had modded heavily before abandoning it called Blender Portal. It could be easily adapted to our needs, and the way it implimented blocks was genius. Any stand alone script in the /blocks directory could be used as a side block, so no adapting a script to work with the portal. Any script already worked, and you could still blocks from phpnuke, etc.

I might tackle it, but here is the basic design if someone wants to start:

portal.php

create DB table PAGES
with fields "html code" "Page title" "Page description" "Keywords" "Unique ID"

call pages in this form portal.php?page=Unique ID

when page loads, call database, get page info, replace title, desc, and keywords in headers and replace html block from portal template

That would be a basic portal minus the admin page you have to create, then you have to impliment blocks, etc.  If someone who has done plugins or mods for punbb wants to work with me, we could knock out a rough version pretty quickly.

Max