IPS Company Blog

Welcome Guest ( Log In | Register )

Rating 5
7 Pages V   1 2 3 > » 

IP.Board 3: Kernel Improvements

Posted by Matt, Oct 7 2008, 04:08 PM in IP.Board

Since IP.Board 2, we've had a "kernel" of classes which IP.Board uses but do not depend on IP.Board to use. A selection of these kernel classes includes DB management, file uploads, emailing, RSS parsing and reading, XML parsing and reading and our proprietry archive format XMLArchive.

For example, you could use "classUpload.php" and "classImage.php" in your own modifications or extensions to handle uploads and GD thumbnail generation. You would not have to initialize the registry or do anything else other than just include the file and use it.

As we took the plunge and went ahead with making PHP 5 a requirement, we were able to make some long-awaited improvements. Here are the high-lights.

Custom Fields

Josh has completely re-written custom field handling within IP.Board and this class ties it altogether. Josh uses just about every PHP 5 trick in the book including abstract classes, interfaces and ArrayAccess to provide a simple clean interface that can be used in almost any project. It doesn't have to be limited to just IP.Board's custom profile fields.

Graphing
Remco has extended this class to include many new graph types including "funnel", "bubble" and "radar" graphs so that presenting data is more relevant. As IP.Board 3.0.0 develops, we'll be making good use of these new methods for statistic reporting within the ACP.

GD and ImageMagick
Brandon virtually started from scratch with our GD image creation. He also wrote a class for imagemagick offering more choice for those who have it installed. It's now very simple to resize an image or add a watermark.

CODE
$image = new classImageGd();
$image->init( array( 'image_path'    => "/path/to/images/",
                       'image_file'    => "image_filename.jpg" ) );
  

//Set max width and height
$image->resizeImage( 600, 480 );
// Add a watermark
$image->addWatermark( "/path/to/watermark/trans.png" );
$image->displayImage();


XML Parsing and Creating
We've had a class for XML parsing and creating since IP.Board 2 but it was a kludge of PHPs then primative XML handling extension and a hand-rolled class for when the XML engine wasn't available. These methods functioned well but were known to be memory intensive.
Thankfully, PHP 5 has much better native XML handling which I took full advantage of when rewriting this class.
I looked at simpleXML intially but found it too, well, simple for our needs so I went ahead and used the full DOM methods. This gives us full control over both reading and creating XML documents.

Here's how simple it is to create a new XML document:

CODE
$xml = new classXML( 'utf-8' );
$xml->newXMLDocument();
  
/* Create a root element */
$xml->addElement( 'productlist', '', array( 'name' => 'myname', 'version' => '1.0' ) );
/* Add a child.... */
$xml->addElement( 'productgroup', 'productlist', array( 'name' => 'thisgroup' ) );
$xml->addElementAsRecord( 'productgroup',
                                             array( 'product', array( 'id' => '1.0' ) ),
                                             array( 'description' => array( 'This is a description' ),
                                                    'title'         => array( 'Baked Beans' ),
                                                    'room'         => array( '103', array( 'store' => 1 ) )
                                                 )
                         );
$xml->addElementAsRecord( 'productgroup',
                                             array( 'product', array( 'id' => '2.0' ) ),
                                             array( 'description' => array( 'This is another description' ),
                                                    'title'         => array( 'Green Beans' ),
                                                    'room'         => array( '104', array( 'store' => 2 ) )
                                                 )
                         );
                        
$xmlData = $xml->fetchDocument();


This will produce this document:

CODE
<productlist name="myname" version="1.0">
  <productgroup name="thisgroup">
   <product id="1.0">
    <description>This is a description</description>
    <title>Baked Beans</title>
    <room store="1">103</room>
   </product>
  <product id="2.0">
    <description>This is another description</description>
    <title>Green Beans</title>
    <room store="2">104</room>
   </product>
  </productgroup>
</productlist>


This is how you'd parse that document:

CODE
$xml->loadXML( $xmlData );

/* Grabbing specific data values from all 'products'... */
foreach( $xml->fetchElements('product') as $products )
{
     print $xml->fetchItem( $products, 'title' ) . "\";
}

/* Prints: */
Baked Beans
Green Beans


I'm sure you can appreciate how simple it is to use these new XML features!

XMLArchive
I created our XMLArchive format for IP.Board as a way of combining several files into one without using tar or zip which can be troublesome on some servers. XMLArchive is very simply file data in a basic XML format. I rewrote the class to make it easier to use and to add more functionality.

Here's how to read an archive:
CODE
$archive = new classXMLArchive();
$archive->read( "/path/to/archive.xml" );
print $archive['someDir/file.html'];


As you can see, we use PHPs ArrayAccess to transparently allow access to the contents of the fileset from the main class handle.

Here's how to create an archive:
CODE
$archive = new classXMLArchive();

$archive->add( "someDir" );
$archive->add( "anotherDir/anotherFile.html" );
$archive->add( "Create a new file from scratch!", "anotherDir/brandNewFile.html" );

# Save gzipped
$archive->saveGZIP( "/path/to/archive.xml.gzip" );
# Save normally
$archive->save( "/path/to/archive.xml" );
# Just return the data
$archive->getArchiveContents();


For simplicity's sake, there is now just one interface to add files: "add()". Personally, the fewer function names to remember the better!

Naturally, this blog entry does not cover all the changes and improvements within the kernel classes but it does go some way to showing just how much energy we've invested in ensuring that IP.Board is as robust and efficient as it can be.


IP.Board 3.0 Search Engine Optimization

Posted by bfarber, Oct 3 2008, 09:03 PM in IP.Board

We receive requests quite frequently to "add SEO to IPB". This is a very difficult request to quantify and to fulfill. What is SEO? What is wrong with IPB's positioning to search engines presently? What can be done better?

We've seen some suggestions over time that make sense, and some we feel would be better left to modifications. While we are not jumping full force into the "SEO" arena with IPB 3, we have made changes throughout the software that we believe will help you position yourself better for search engine indexing. This blog post will touch on a few of these changes.

Semantically correct HTML
The word "semantic" means the study of meaning in communication. Basically, when used in the context of an HTML document, to state that the source code is semantic means that the HTML tags used are appropriate for their representations. It wasn't too long ago that tables were used to position elements in your browser window, and 1x1px gif images were used to pad areas so things looked nice. Those days are (almost) long gone, and today's modern web pages are focusing on producing HTML source code that makes sense, while separating styling to CSS documents and javascript to external javascript files.

When IPB 3 ships it will validate as xHTML valid, and the source code will be semantically correct. Deprecated HTML tags and excessive and unnecessary tags (such as 3-layer nested divs) are not used, and the javascript is not obtrusive (*see comments). Screen readers and search engine spiders should find it much easier to read a topic generated by IPB 3 than IPB 2. Furthermore, all functions should work (although in some cases to a lesser degree) when javascript is not available. Heading tags are used properly and feature keywords related to the content on the page. They also cascade in a defined format so that they represent the content in a meaningful way.

*Note: HTML will be semantic and javascript unobtrusive to the extent possible. There are thousands of configurations, literally, and with so many browsers, options and features it is hard to make a blanket guarantee of this sort. Rikki has explained more about our goals for the skin in another blog entry if you are interested in the new skin.

Microformat support
Microformats are common ways to represent similar data. For instance, it is not uncommon for a random website to have some sort of news or articles data and some sort of user profile page for each user. Microformats were developed so that these common things could be represented in a common way to help further the web. By utilizing microformats, other webpages and scripts can parse your page and extract valuable data that they can then share. Even Internet Explorer 8 will be making use of Microformats for some of it's cooler new features, while other browsers already do or are also planning to.

IP.Board 3 makes use of several microformats to help your document make sense to tools that can read and understand these formats. Specifically, we are making use of the hCard, hCalendar, rel-nofollow, rel-tag, and rel-home microformats. We also make use of some other common relationship attributes where appropriate (such as "rel='help'" for the link to the help documentation), even though they are not necessary full-fledged microformats at this time. Furthermore, we will continue exploring and watching microformats, and applying them as they develop and relate to IPB.

rel='nofollow' Support
This is another common request we receive: making all posted links in topics utilize the "rel='nofollow'" attribute appropriately. Many users, on the other hand, have asked that we do not implement this. The idea is that search engines should understand "rel='nofollow'" to mean that the webmaster is not endorsing the link, so when the search engine follows it, the search engine shouldn't penalize the website the link is hosted on should they determine it was a bad link, or irrelevant to the linking site.

We have added a setting to allow users to enable this without having to make source code modifications. The rel='nofollow' attribute will be automatically appended to all urls posted and parsed through the normal bbcode routines when the setting is enabled.

Removal of "(Powered by Invision Power Board)" from board index
For years, since the beginning of IPB, the page title of the board index page has had "(Powered by Invision Power Board)" added to it if you did not purchase copyright removal. We did not disallow users from removing this text, however, and many users did.

We've gone ahead and bit the bullet, and removed this text from the base release.

Removal of "lo-fi" version
The lofi version in IP.Board was meant to provide a toned-down basic representation of the current topic or forum. It was useful for both search engines and mobile browsers. It was so useful, in fact, that many times when you reach an IPB in a search engine listing you will actually end up at the lo-fi page instead of the full-version page.

In IP.Board 3 we have removed the lofi version entirely in favor of the new output engine capabilities. A mobile skin can be set directly through the admin control panel, negating the necessity for an entirely different script to serve the content. This is the great thing about the MVC pattern for all you developers - leave the model and controller alone, and just change the view itself.

The relationship to search engine optimization comes into play when you consider that the lo-fi version and the full version are essentially duplicating the content from one another, and a commonly held belief exists that search engines penalize you for duplicate content. While we can't speak for what any given search engine actually does, we did feel this feature was deprecated and no longer needed given advances in the skin system in IPB, and have removed it entirely.

Changing of modes moved to user control panel
It's not uncommon for a search engine to index a link to a topic on a site running IP.Board, and for some unknown reason decide the topic is best represented when "&mode=outline" is added to the URL. While this doesn't stop you from visiting the page, it DOES change the layout of the page, and for newcomers some of the alternate layouts may not be as easy to follow when they first visit your site.

Many users do utilize the different layout options (which are handled on a per user-account basis) so we did not feel it wise to remove these options. Instead, we have moved the ability to change the layout of topics to the user control panel. This should stop search engines from indexing topics with "mode" parameters in them, reducing confusion for visitors actually clicking the link to visit your site.


Additional features
Additionally, we've already gone over a few other changes that are related to better search engine positioning which we need not repeat here. Just as a brief recap, you may also be interested in reading these blog entries



There are many more minor but important improvements buried deep within IP.Board 3 that should help you keep your site listed in search engines appropriately. While we won't jump on the SEO bandwagon and advocate certain styles of running your site or formatting your urls, we are doing our part to bring basic functionality our users have requested with regards to their site's optimization into reality with IPB 3.


IP.Board 3: Networking And Integration

Posted by Matt, Sep 30 2008, 03:42 PM in IP.Board

Brandon blogged a while back about IP.Board's integration points.

I wanted to spend a moment discussing the features within IP.Board 3 that all you integrate the board with your website and to create your own network.

Member Management
Since IP.Board 2, we've had, what we call, "Log In Modules". This is basically a mini-framework to allow custom code to be used easily when authenticating and registering members. For example, if you had a database full of members and you wanted for them to be able to use their existing usernames and passwords, you could add a log in module to query your database or other system (via SOAP, XML-RPC, etc) for authentication.

This system has been enhanced based on user feedback and IP.Board now ships with modules for LDAP and OpenID which will make it much easier to use existing authentication.

Networking
The log in modules also tie into our 'IP.Converge' product which allows you to share authentication details across multiple IP.Board installations. The IP.Boards don't even need to be on the same server! In fact, we use Converge and the log in modules ourselves so that our customers can use the same log in details on the forum as they do in our ticket center.
You could use this functionality to share members across many forums, creating a true network of members.

Using the IP.Board Engine

We've made no secret that IP.Board 3 is a complete rewrite. The new framework makes full use of PHP 5 and incorporates many timesaving features that you can instantly make use of.

It's common for our customers to ask how they can use certain parts of IP.Board within their own website. For example, they'd like to show a list of recent topics or posts. That's no problem as we've had an API class interface since IP.Board 2.

However, if you wanted to send data to IP.Board, such as a new post or new personal message; things got tricky. Even using a template bit required a lot of code copying.

For example, if you wanted to make use of our database engine or templating engine, you would need to copy a lot of 'index.php' so that it set up ipsclass correctly. With IP.Board 3, that is no longer required. You can use our engine in your own scripts as simply as this:

CODE
require_once( './initdata.php' );
  require_once( IPS_ROOT_PATH . 'sources/base/ipsRegistry.php' );
  
  $registry = ipsRegistry::instance();
  $registry->init();


Those few lines of code give you access to: Caches, settings, member management, database management and more.

Writing your own code
Quite often, you want to add some IP.Board functionality to your own website. With IP.Board 3.0.0 it's very simple.

You want to add a new post? No problem, simply use that code above and add:

CODE
require_once( IPSLib::getAppDir( 'forums' ) . '/sources/classes/post/classPost.php' );
  
  $postClass = new classPostForms( $registry );
  $postClass->setForumID( $forumID );
  $postClass->setForumData( $this->registry->class_forums->forum_by_id[ $forumID ] );
  $postClass->setTopicTitle( "My Topic" )
  $postClass->setPostContent( "Hello, I am post content!" );
  $postClass->setAuthor( $memberID );
  
  try
  {
      $postClass->addTopic();
  }
  catch( Exception $error )
  {
      print $error->getMessage();
  }


It's really as simple as that! Note the try -> catch block? That's consistent with all the new API-like functions. We take advantage of the PHP 5 exception handler to return information on what went wrong. We also list all the possible exceptions that are returnable in the phpDoc for that function.

Of course, seasoned modification authors will already be familiar with functions similar to those present in IP.Board 2's API system. The good news here is that this functionality doesn't require an API bridge anymore, it's the exact same code that is used in the normal posting routines.

Do you want to send a new personal conversation to someone in your own code? Simple!

CODE
require_once( IPSLib::getAppDir( 'members' ) . '/sources/classes/messaging/messengerFunctions.php' );
  $messengerFunctions = new messengerFunctions( $registry );
  $messengerFunctions->sendNewPersonalTopic( $toMemberID, $fromMemberID, $invitedUserIDArray, $msgTitle, $msgContent );


Want to get a list of PMs in your own code?

CODE
require_once( IPSLib::getAppDir( 'members' ) . '/sources/classes/messaging/messengerFunctions.php' );
  $messengerFunctions = new messengerFunctions( $registry );
  $messengerFunctions->getPersonalTopicsList( $memberID, 'in' );


Another common request is to use IP.Board's templates in your own projects, again this is as simple as:

CODE
require_once( './initdata.php' );
  require_once( IPS_ROOT_PATH . 'sources/base/ipsRegistry.php' );
  
  $registry = ipsRegistry::instance();
  $registry->init();
  
  print $registry->output->getTemplate( $templateGroup )->templateName( $templateArguments);


There really is so much that you can do. Listing them all would make for a very large blog entry indeed! We will of course be providing a lot of documentation on these new features.

Combine this functionality with the new hooks and plug-ins system and you've got a very quick way to build new code using our core. We're very excited to see what you do with it!


IP.Board 3: Personal Conversations

Posted by Matt, Sep 26 2008, 01:41 PM in IP.Board

Around ten years ago, I was hard at work on one of the first 'Private Message' modifications for a board that has long ceased to exist. At the time it was an exciting novelty to be able to message another board member. These days it's an expected feature for any seriously considered forum software.

Not much has really changed with messaging's core features. Sure, the interface has become a little smarter and there have been a few little bells and whistles added such as message tracking but ultimately it's still sort-of email based in functionality.

This was a limitation I noted when developing IP.Dynamic. In fact, almost two years ago, I blogged about Personal Topics, the next logical step in private messaging.

Enter Personal Conversations
As, with most of IP.Board 3.0.0's new features, personal conversations - as we like to call them - have been a popular request. A request that we have now fulfilled! Why bother CC-ing and forwarding messages to other members when you can invite them right into the conversation?

How it Works
Where you would normally 'compose' a new message, you now 'start a new conversation'. The form looks largely the same. However, instead of there being a space to "CC" other members, there are boxes for you to invite other members. How many members you can invite is up to the administrator as it's limited to your group settings. In fact, the admin could remove your ability to invite other members completely if they desired to return to a more traditional messaging system.

The recipient and each invited member will be notified they have a new message (in terms of notification, a message is either a new conversation or a reply to any existing conversation). The new conversation will appear in both their "Inbox" and their "New" folders. It will remain in their "new" folder until its read and then it will only be available in the inbox. Why? Well, because of the magic folders. But more of that in a moment.

The conversation looks largely the same as a normal topic does; linearly sorted with the newest replies last. There is even a "fast reply" form much like you use when replying to topics. This instantly makes it easier to view previous replies and keep the 'thread' of conversation without having to delving into your 'sent' folder to see what you replied with.

The topic starter (and any participating super moderator) can choose to 'block' any participant that is blockable. Immunity from being blocked is granted by the "Not Ignorable" setting. This means you can ensure that you (the admin) can never be blocked from a conversation you are participating in. When a participant is blocked, the topic vanishes from their folders until they are unblocked.

Each participant apart from the topic starter can choose to leave a conversation at any time. Once the participant has left the conversation, it is only available in the magic "Finished" folder and the replies no longer count towards your space allowance. The topic starter cannot re-invite you but you can choose to rejoin the conversation at any time.

The topic starter can choose to invite more members (up to their invite allowance) at any time from the conversation display screen. Each participant can also view all participants and see the last time they read the conversation.

Magic Folders
This is the term we give to certain folders that are not editable or removable. They are: "New", "Finished", "All" and "My Conversations". Topics in "New" and "My Conversations" can also be in other folders. "My Conversations" is the default location for any conversation you start. You can then move into another folder -- but it will always be accessible from "My Conversations".
"New" simply lists any new personal conversations or any personal conversations with new replies. So, you could have a conversation in "My Folder". When it receives a new reply, it will also be listed in "New" until you read it.
"Finished" simply lists all the conversations you've left, allowing you to rejoin if desired.
"All", as the name implies, lists all the conversations you are participating in as either a starter, recipient or invitee.

We think this is a very exciting step forward for personal communication and opens up new ways to communicate via the forum. Ten years is a long time to wait for change. We hope you find it worth the wait!


IP.Board 3 Testing Procedures

Posted by bfarber, Sep 23 2008, 08:58 PM

As we get further along in the development cycle for IP.Board 3 an obvious step that we will be taking on soon is general testing of the new codebase. While this happens with every release, both internally and publicly, it is even more important for a release as immense as IP.Board 3. The entire underlying codebase has changed and vigorous testing will be needed to iron out all of the issues us developers have missed.

With every test phase of a product release, we frequently get barraged with requests from customers asking to be a part of the testing process. We wanted to let everyone know that we have come up with a process for IP.Board 3 that we think will please everyone - everyone will be able to test the new release if they wish to. original.gif

Progress is happening at an astounding rate, and right now we're working through bugs that we have identified and putting finishing touches on much of the software. The skin is still heavily being developed and worked on, both on the front end and in the admin control panel. Trust me when I say we're just as eager to get people in and show off what we've been working on as you guys are to see it. Please bear with us as we continue working on these rather unexciting yet necessary steps. We know you're anxious to see it and we want to ensure that what we deliver is what you are expecting. To that end, please also understand that future blog entries may be a little less exciting than they have been for the last several weeks.

All of us have begun testing IP.Board 3 internally. As we discover unfinished areas or bugs, we are working hard to rectify these things to get IP.Board 3 as stable as possible. We are still working through bug reports from previous versions of IP.Board, as well, to get IP.Board 3 off to a fresh start with as few bugs as possible.

Once we feel that IP.Board 3 is relatively stable, and that we have worked through all of the issues we have found internally, we will be inviting our customers (you!) to take a look and to give us your feedback. This first stage of testing we expect to remain tightly controlled, with us hosting a copy of IP.Board 3 and providing you access to this copy. You will be able to use the features and we would love for you to report back your comments on the functionality, the skin, and any issues you find. More information about what we will be looking for exactly will be available once we reach this point.

After we have ironed out all the bugs and addressed all of the feedback we can, we (as per our usual procedures) will be updating our company forum. This helps give us a chance to really test out the new release in a live environment. You'd be surprised at some of the issues that never come up during development and basic testing that come up when you move to a live environment. This also helps give us a chance to test the software under a real-world usage scenario, giving us information about resource usage and areas of the software that we feel need improvement to be able to handle today's large forums. We are dedicated to ensuring that IP.Board 3 runs efficiently so that you can don't have to worry about how your site runs, but rather how you run your site.

Finally, once we've gotten to this point and feel we've nailed down all of the bugs we can (or at least most of them) and we feel the software is stable and resource-friendly, we will open up IP.Board 3 for public beta testing. This is the point where you will be able to download IP.Board 3 and install it on your own servers (but not upgrade your live website) so that you can test it to ensure that our next generation release will meet your needs. There are, quite literally, thousands of different configuration scenarios and hundreds of different server environments out there, and this stage of testing gives us a chance to help make sure IP.Board will run properly and bug-free in as many setups as possible.

Throughout this process, we will be contacting modification authors, community project teams, and skinners to help get them started as well. We would love for IP.Board 3 to launch and have resources available right from the start, or as shortly there-after as possible. While we have no control over third parties integrating with our software, we will do what we can to assist these developers so that our customers will have as short a wait as possible for the software they need to run their sites.

From there, we plan to follow the normal routines we follow for release. We will correct reported bugs, test them internally, and release public betas for further testing. When we feel we are ready for release, we will put out a "Release Candidate" version of the software. This release is one that, to our knowledge, should be ready for prime time, but we are providing another chance for customers to test it and report back any issues that they have found so that they may be addressed before we release the software as "final" for general public usage.

We know everyone is excited about IP.Board 3, and eager to get a look at what we've been working on for the last several months. We are eager to show it off, and are looking forward to the testing phases described above. These phases give us invaluable feedback from the most important users - you!


IP.Board 3: Friendly URLs at last!

Posted by Matt, Sep 18 2008, 03:00 PM in IP.Board

Possibly the most often requested feature we've had since the very first version of IP.Board is 'friendly URLs'.

Although this sounds like you'd expect your URLs to greet you with a self-empowerment phrase first thing in the morning, it really relates to making the board generated URLs a little more attractive to both humans and search engines.

I am being very careful to avoid the phrase "Search Engine Optimization" in this opening few paragraphs despite it being used often in the request for friendly URLs. What we've added will definitely help with SEO but it's not a complete solution and neither is it intended to be.

So, what do you have?
In a nutshell: friendly URLs! The process to create and manage them is far more interesting than the end result, but more on that in a moment. Lets first look at some examples of the new URLs.

Here's a few sample URLs from IPB 2.3.x:

To show a forum (My Test Forum):
www.board.com/forums/index.php?showforum=10

To show a topic (My Test Topic):
www.board.com/forums/index.php?showtopic=99

To show a user (Matt Mecham):
www.board.com/forums/index.php?showuser=30


There's nothing wrong with those URLs. They are short and concise and they spider very well, but we can do a little better to make them more attractive.

If you are on a Windows webserver, you can use the 'query' string method which presents URLs like this:

www.board.com/forums/index.php?/forum/10/my-test-forum
www.board.com/forums/index.php?/topic/99/my-test-topic
www.board.com/forums/index.php?/user/30/matt-mecham


If you are on an apache based web server you can make use of the 'path_info' method:

www.board.com/forums/index.php/forum/10/my-test-forum
www.board.com/forums/index.php/topic/99/my-test-topic
www.board.com/forums/index.php/user/30/matt-mecham


Even better, if you can manage your own .htaccess files, you can make use of the mod_rewrite functionality. For convenience, the mod_rewrite code is generated for you. The end result looks like this:

www.board.com/forums/forum/10/my-test-forum
www.board.com/forums/topic/99/my-test-topic
www.board.com/forums/user/30/matt-mecham


What would happen if you used accented characters like this: Mått Méçhåm? The are simply converted into their nearest non-accented 'versions'. In this example, "matt-mecham".

How do I use it?
The easiest way to generate a 'friendly URL' is by making use of the {parse} tag:

CODE
   {parse url="showtopic=99" base="public" seotitle="my-test-topic" template="showtopic"}


The "seotitle" parameter (and one of few concessions to the phrase Search Engine Optimization for brevity) is the ready-formatted string to use within the URL. If you want to parse the title on the fly into something a little more friendly, then you can wrap it like so:

CODE
   {parse url="showtopic=99" base="public" seotitle="%%My Test Topic%%" template="showtopic"}


The optional "template" parameter refers to which template is used to build the URL. These templates are managed in a single file in "admin/extensions/seoUrlTemplates.php". Here's an example:

CODE
$templates = array(
      
       # APP: MEMBERS
       'showuser'        => array( 'out'        => array( 'showuser=(.+?)(&|$)', 'user/$1/#{__title__}$2' ),
                                 'in'         => array( "/user/(\d+?)/", array( 'showuser', 1 ) ) ),
      
       # APP: FORUMS                        
       'showforum'     => array( 'out'        => array( 'showforum=(.+?)(&|$)', 'forum/$1/#{__title__}$2' ),
                                 'in'         => array( "/forum/(\d+?)/"  , array( 'showforum', 1 ) ) ),
                              
       'showtopic'     => array( 'out'        => array( 'showtopic=(.+?)(&|$)', 'topic/$1/#{__title__}$2' ),
                                 'in'         => array( "/topic/(\d+?)/", array( 'showtopic', 1 ) ) ),
                              
       );


This example shows the default template code for showing users, forums and topics. The 'out' method deals with how the link is formatted while 'in' tells IP.Board how to handle the incoming links.

This means that if you don't like the format of the links currently, you can change them to suit your own tastes. Modification authors can also add to this file (via an interface in the ACP) to add in friendly URLs for their own applications and modules.

I did mention that "seotemplate" is optional - and it is. If you don't specify a template name then IP.Board will test all available templates to the URL its examining to see if there's a match. Actually specifying which template to use simply speeds up the process a little.

Any variables not catered for in the templates is added at the end of the URL, separated by an underscore like so:

www.board.com/forums/topic/99/my-test-topic/_/view/getNewPost

This makes for a convenient way to transport data without having to add all the possible permutations in the template file.

We hope that the inclusion of this popular request will go some way into helping your overall SEO approach as well as making common links look altogether more pleasant!


IP.Board 3 Error Handling Improvements

Posted by bfarber, Sep 16 2008, 08:20 PM in IP.Board

It is necessary in any application to handle error situations. The most common method of handling such a situation is to issue an alert to the user so that they know an error has occurred. While this is sufficient in most cases to resolve the problem, we wanted to address IP.Board's error handling routines a little bit with the upcoming release to try to make them a little more useful.

Firstly, we've gone through all of the errors that are issued, and clarified and separated them. No more obscure "Sorry, some required files are missing" error messages when doing something as simple as visiting a topic that has been deleted. The error messages should be much easier for the end user to understand with the upcoming release.

In addition to updating the error messages themselves, we've added unique error codes to each and every message. The error codes follow a defined format so that in the event you need to submit a ticket and reference an error message you received, by providing the error code our technicians can look up more information on the error and easily find where and how it was triggered. This should help make technical support more efficient for all of us.

At some point following the release of IP.Board 3.0, we intend to make public this error codes database so that users can easily look up more information on errors when they need to by themselves.

Further to this, we've added error logging. By default, certain errors will trigger a log to be generated. Generally, these logs are only generated when an error has occurred that could indicate a user is attempting to bypass security restrictions. Some administrators may want to trap more errors, however (perhaps even all generated errors), and as such we've added a setting that allows you to force IP.Board to log all errors above a given level (levels range from 1 through 5). Additionally, you can opt to be notified of all errors triggered above a certain level. For instance, if you want to know about all level 5 (serious) errors encountered right away, you can have the board email you when such an error is generated. This can help you administrate your board more effectively and securely by identifying issues you didn't know existed (for instance, in a custom modification), and can help our technical support drill down on issues that are unique to your site.

The log pruning task has been updated to support the new error log tables so you can prevent it from growing too large.

We have some more ideas for improvements to the error system in general to provide more value and assistance for you and your users. Errors are a necessary part of application development, but we are doing our part to make them as friendly and manageable as possible.

If you have more ideas for improvements to the error management system in IP.Board 3 please share them with us below!


IP.Board 3: Topic Marking Overhaul

Posted by Matt, Sep 11 2008, 02:43 PM in IP.Board

Topic markers have evolved quite a bit over the past few years. What started out as being an almost secondary concern has become quite an important part of the user experience.

A Very Brief History
Early versions of IP.Board relied on cookies to track read topics. This worked fairly well but it wasn't without problems. Anything to do with cookies is always a little flaky. There is a very finite amount of information you can store and browsers have a habit of eating them or not setting them correctly. The biggest complaint, however, is that topics that you have read on one computer do not stay read on another computer.

IP.Board 2 introduced topic markers that are stored in a database table. This greatly increased stability and allowed the read topics to remain read regardless of computer used.

However, this did lead to some performance issues on busier boards as the topic marker table is often in demand whcih can result in locking issues and processes queueing. Also, the code wasn't centralized and sprawled through different files making maintenance very difficult.

Learning From Experience

It was obvious we needed to centralize all the code and create a common, simple public interface as a matter of course. We also wanted to allow our other applications (such as blog and gallery) to use this system without having to copy code. Making it truly extensible also allows modification authors to use this centralized system without having to maintain their own code.

Next up was the performance issue. How could we increase performance without losing functionality? The most obvious answer was to store the read topics in the user's session. This was fine in principle but there were obstacles to overcome. First of all, session handling in IP.Board 2 is not entirely centralized. There is a class but it is not used exclusively. Other files such as register.php and login.php are allowed to modify the session table without telling other classes what it did. When you're trying to preserve data, this cannot be allowed. Also, session handling in general isn't an exact science. IP addresses change meaning new sessions can be created several times during a single visit.

The solution to these problems must be robust, centralized and extensible.

So, what's new?
First up was tightening up session handling. All session management is now performed through a single class (publicSessions). Other files that need to manage sessions are done so via publicSessions. This allows this one class to keep tight control over the session data.

The biggest challenge was to allow sessions to handle the marker data and only allowing the markers to be written back to the database table when the session is deleted. The theory is sound and simple but the execution a little trickier. The gory details of which are explained a littler further down for the technically minded.

In brief, the system loads the markers from the database table when a new member session is created. The markers are saved in with the rest of the session data when the session is updated at the end of a page view (to update the running time and location, etc). This continues until the session is due to be removed, for example, when the member is no longer active and the session is older than the allowed time. The sessions to be removed are captured and allowed to be examined by other classes. The item marking class examines these sessions and writes back the marker information to the marker database. The system also makes use of cookies to give some permanence for guests and those that are not logged in. The cookies are limited to the last 100 items read to prevent cookies being sent that are too large.

The end result is a much leaner system which should be much more efficient and presents a very simple public interface. Here's some sample code to give you a taste:

CODE
# To mark an item read (an item is a topic for the forums 'application')
$itemMarking->markRead( array( 'forumID' => 2, 'topicID' => 10 ) );

# To fetch the read status of an item
if ( $itemMarking->isRead( array( 'forumID' => 2, 'itemID' => 99, 'itemLastUpdate' => 1200098989 ) ) === TRUE )
{
     ....
}

# To fetch the last time an item was marked
$lastMarked = $itemmarking->fetchTimeLastMarked( array( 'forumID' => 2, 'itemID' => 99 ) );


Modification authors can write their own plug-ins and make use of the system with minimal coding effort.

Listen Up, Here Comes The Science Bit
For the more technically minded, this section explains how the system works within the new IP.Board 3.0.0 framework.

The first challenge was to make proper use of __construct and __destruct within PHP 5. This is very straightforward in the case of __construct; this is run when the class is initialized. There are no problems with that. The item marking class grabs and filters the cookie data and also grabs and filters the session item marking data in __construct.

The real issue is with __destruct. Specifically the order in which they are called. In PHP 5.0.0 to PHP 5.2.4 they are called in the order they were created. This means that by the time __destruct() is called in item Marking the DB connection has been closed which isn't at all helpful. This is because the DB is set up before classItemMarking. Now, as of PHP 5.2.5 the __destruct order has been reversed. This means that the DB connection will still be available.
However, that's not very convenient for code that has to be robust on different platforms and with unpredictable version of PHP. Another solution was needed.

Thankfully register_shutdown_function() executes before any __destruct() calls, so we can reliably use this. There is a __myDestruct function in the ipsRegistry class which calls __myDestruct() in all the registry child classes (DB, Member, Request, Cache, Settings, etc). The member registry class makes use of this to fire a manual destruct function within itemMarking to allow it to save back any data for deleted sessions and to provide information for the session update. A __myDestruct fires within the public session class to actually update the sessions and delete the expired ones.

Phew! As you can see, there's a lot going on behind the scenes in IP.Board 3.0.0 which makes full use of all PHP 5 has to offer.


IP.Board 3: Skin update

Posted by Rikki, Sep 9 2008, 02:55 PM in IP.Board

We wanted to use this blog entry to bring you an update on the brand new IPB3 skin. In my previous entry, I didn't go into any detail about the skin itself, but I did introduce the Style Guide and some goals/ambitions for the front-end interface. We're now at a stage where we can talk about the skin itself.

Whereas most of our other entries explain one particular feature in-depth, this post will be more of a quick-fire overview of some of things we're implementing on the front-end of IPB3, and some other tidbits.

Popup Windows
We took the decision to try and eliminate all popup windows from IPB3. Popup windows create several problems: in this day and age, you can't guarantee a user will even see them due to popup blockers, and secondly, with the myriad devices accessing the internet now, you can't be sure that a popup window will be supported, or a good user experience.

Instead, where browsers support it, inline ajax-populated popups are being used. Where browsers don't support it, the user is taken to the content like they would any other page. Our goal is to keep the entire experience confined to one browser window/tab, as I believe it should be. This includes friends management and warning management (for moderators).

Unobtrusive Javascript
Going hand-in-hand with the above was a desire to make IPB fully usable even if you had javascript disabled. As such, we've worked to make every feature, as far as is possible, available and usable even without javascript. There are some exceptions to this, e.g. the post editor (although you can still post, you'll just see a textarea), but on the whole we're on our way to making IPB3 much more accessible than IPB2.

Getting at user information
IPB has a lot of relevant information about each user, but presently it can be tedious to access the important details quickly since you have to go to their profile, taking you out of your workflow. New to IPB3 is a user card which can be accessed almost anywhere; wherever you see a username, simply hover over it to get all the relevant information for that user, including photo, contact details and reputation. This has been implemented in such a way that skinners and modders can also integrate it incredibly easily. We've also added a new bbcode which allows users to create these special links from within their posts.

Better uploading tools
In the past we've had numerous calls for TRUE multiple attachments. You'll be pleased to know that we've fully integrated SWFUpload into IPB3 for webservers that support it (which should be most). For those unfamiliar with this tool, it allows users to select multiple files in the Open dialog, and javascript then manages the upload queue for you. Another cool improvement is we now support upload progressbars with no additional server requirements! In addition, if you upload images, you'll see a thumbnail immediately, making it easy to insert the right image to your post, right where you want it.

Searching
The search form and results page have both been completely redesigned. Since the search mechanism in IPB3 underwent such a big change in being able to search all applications at once, we needed a new interface that made this easy to use. The result is a search form that adapts, showing you additional filters based on the applications you've chosen to search. The search results page combines all results from the applications you selected, but also allows you to show the results from just one application at a time. And finally, multiple results from one object (e.g. several matching posts in one topic) are grouped together so it's really easy to see the breakdown of your results.

Other significant improvements
While almost every page of IPB3 has been recoded from scratch and improved, some areas have undergone more changes than most. I'll cover them briefly so you know what you can expect when we unveil the skin:

  • Improved board index
    One of the first steps I made when developing the new skin was to look at each major page and figure out if it could be made more useful than it is now. One result of this process was to improve the board index - and the new hooks system made this possible. The board index now features a collapsible sidebar, showing relevant information such as recent topics, top posters and more. Naturally, since this is hook-based, mod authors will be able to easily add their own data to this area.

  • User control panel
    The control panel was a big focus right from the start. We first knew we were going to remove the messenger from the UCP, since it didn't fit conceptually. What was left has been redesigned, with settings broken down into tabbed sections, showing only the menu for that section - this should prevent new users from being overwhelmed when they open their UCP and seeing so many links.

  • Messenger
    As noted above, the Messenger is now its own complete section, reducing clutter.

  • User profiles
    User profiles have been redesigned, bringing them more into line with what users might expect from their favorite social networking sites. One new feature we're excited about is a Recent Activity feed, which allows you to see quickly what content a user has contributed recently, be it topics or posts, calendar events, images and more. This is made possible by the search index, which we covered in a previous post.


Media tag
We've added a new [media] bbcode tag, which will insert all kinds of media right into a post. If you put a YouTube link in a media tag, it'll insert the YouTube player; similarly, if you link to a Flickr album, it'll insert a Flickr slideshow. New media handlers can be created in the ACP for those sites we don't support out of the box, while still using the same [media] tag - making it really simple for your users.

Quick PM
One last feature to mention - we have implemented a Quick PM feature, which allows you to PM a member from topic view without leaving the page. We hope this increases personal communication, and reduces the chance of topics going off-topic.


I hope that gives you some idea of what you can look forward to with regards to the front-end appearance of IPB3. We'll be previewing the actual design of the skin in the coming weeks as we ramp up testing, so if you have any questions, comments or suggestions on the things I've covered here, now is a good time to get them out!


The "all new" Output Engine

Posted by Matt, Sep 4 2008, 02:45 PM in IP.Board

Way, way back in the early days when we were planning IP.Board 3, a primary consideration was to completely overhaul the output engine to add several new features and to increase extensibility.

Out with the old...
The system in IP.Board 2.x is really just a perfunctory "engine" build around a few methods in a class. There was no real cohesive structure with many different files and functions accessing 'skin' methods. We decided that a virtual re-write was required.
We didn't want to be tied to a single output format. Back when IP.Board 2 was first written, there were no iPhones and the idea of actually viewing a forum on a cell phone seemed more than a little crazy. Times have changed.

...and in with the new
At first glance, the new system isn't that different from what we had in IP.Board 2. It's when you scratch the surface that its power becomes more obvious.

The first change is that you can have an unlimited depth for child skins. In IP.Board 2 you could only have one level of child skins which was very limiting to some skinners. Also, in IP.Board 2 there was a single master skin from which each skin inherited from.

While there is still a single "master" skin in IP.Board 3.0.0, it's completely transparent and instead you can set up several different "root" skins for which child skins inherit from. This instantly makes for more flexibility.

In IP.Board 3, each skin can have multiple CSS files which can be hard-positioned within the ACP to ensure the correct load order for correct cascading.

Also, each skin allows you to set group-based permissions so that you can determine exactly who can view and select skins.

And finally, guests can select a skin (as long as you give them permission to do so!)

Going Deeper: User Agents
IP.Board has a completely new user-agent system where you can add new user-agents and group together several. This system is now used for the 'search engine spider' settings.

This also means that you can tie a user agent to a specific skin. Do you want your iPod touch and iPhone users to use a specific skin? You can do that very easily within the ACP. Taking it further, you can even designate specific versions for each user agent. Do you want to take advantage of Firefox 3 or IE 8? That's very simple to do now. You can even set a range of versions very simply.

Going Deeper Still: Output Formats

The biggest change is that IP.Board can now handle multiple output formats. By this we mean that IP.Board has a plug-in architecture to allow completely different processing for HTML, XML or even WAP. This system is completely extensible so modification authors can easily write their own engine plug-ins which drop in and are available for use immediately.

Each skin must choose an output format to use which means that you can have completely different skin sets for XML and HTML bringing in even more flexbility.

You can also use a "gateway" file to set the output format. IP.Board 3 ships with two gateway files. "index.php" which is tied to the HTML output format and "xml.php" which is tied to the XML output format. This means that "index.php?showforum=1" and "xml.php?showforum=1" enable the correct output engine instantly.

Putting it Together

Take this scenario: You want to support WAP using XML with XLST templates specifically for Nokia cell phones. Done, done and done. All without having to make a single PHP modification.

Now that's a powerful system!


7 Pages V   1 2 3 > »