Nucleus Tips & Tricks (2003)

Introduction

Some tips and tricks gathered from the documentation and the Nucleus support forum.Some of them I wrote myself. Hope it is of use for you. If any questions please do not hesitate to ask them at ronmeul@xs4all.nl. This document is changing all the time (I hope :-)

Contents

How to create categories and subcategories

Step 1 is to use different blogs for different categories. For instance create a blog named animals and and one named plants. To make subcategories create them in your blogs e.g.

  1. blog animals with categories dogs, cats.
  2. blog plants with tulips, roses

Next I wanted a navigation bar with all my blogs (categories). I couldn't find a variable for that (any clues welcome here) so I wrote a simple plugin to list all my blogs:

<?
class NP_BlogList extends NucleusPlugin
{
function getEventList() { return array(); }
function getName() { return 'List categories'; }
function getAuthor() { return 'Ron Meulensteen'; }
function getURL() { return 'http://www.trapveldje.net/'; }
function getVersion() { return '0.1'; }
function getDescription() { return 'Display a list of blogs with links. The active blog has no link and 
has id=&quot;current&quot; and can be used with #current in a stylesheet. Usage: &lt;%BlogList%&gt;. 
To display a link to another (home)page as the first item in the list: &lt;%BlogList(Myotherpage)%&gt;.'; }

function doSkinVar($skinType, $otherpage="none")
	{
	global $manager, $blog, $CONF, $QUERY_STRING;	
	if ($blog) $b =& $blog;
	else $b =& $manager->getBlog($CONF['DefaultBlog']);
	
	$query = 'SELECT bname, bnumber, burl FROM nucleus_blog ORDER by bname';	
	$navBlogList = "<div id=\"navcontainer\"><ul id=\"navlist\">" ;

	if ( strlen ($otherpage) > 1 )
		{
		$foundhome = strpos($QUERY_STRING, 'blogid');

		if ($foundhome !== false || $skinType != 'index')
			{
			$navBlogList .= "<li><a href=\"".$CONF['Self']."\">".$otherpage."</a></li>";
			} else {
			$navBlogList .= "<li><div id=\"current\">".$otherpage."</div></li>";
			}
		}

	$entries = sql_query($query);
	while ($row = mysql_fetch_assoc ($entries))
		{
		if ($b->blogid ==  $row['bnumber'])
			{
			$navBlogList .= "<li><div id=\"current\">".$row['bname']."</span></li>";
			} else {
			$navBlogList .= "<li><a href=\"index.php?blogid=".$row['bnumber']."\">".$row['bname']."</a></li>";
			}
		}
		echo($navBlogList."</ul></div>");
	}
}
?>

Note: The list produced is compatible with the list-o-matic and Listamatic lists. This is a stylesheet generator to transform your list into e.g. buttons or tabs.

Now I wanted to add a mainpage to the list. I used a blog for this and let the name of the blog begin with &nbsp; to put it on top of the bloglist (other suggestions welcome!) and make it the default blog. If you want to see this in action take a look at http://www.vrijheid.org/test/ (In Dutch but you should get the picture).As the name indicates this is a testpage. Eventually it will move to http://www.vrijheid.org/. (Now running with FileMaker Pro as a database on an old Macintosh Performa)

To display a (sub)categorielist on each blog (main categorie) page I used this in my skin:

  1. <%if(blogsetting,bnumber,7)%>
    7 is the blogid of my main blog
  2. <%otherblog(nieuws,default,1)%>
    We are on the main page: display some mainpage stuff
  3. <%otherblog(wedstrijden,headlines,15,wedstrijdkalender)%>
    Display some more
  4. <%else%>
    We're NOT on the main page
  5. <%if(category)%>
    A categorie is selected
  6. <%category%>
    Display categorie name
  7. <%blog(default,15)%>
    Display 15 items for this category
  8. <%else%>
    NO categorie is selected
  9. <%categorylist(default)%>
    Display a list of categories. I used the category description here to explain the categorielink.
  10. <%endif%>
  11. <%endif%>

Breadcrumbs or 'You are here' navigation

With maincategories and subcategories use this on the main page skin (or create a skin for the homepage of your default blog)

  1. <%if(blogsetting,bnumber,7)%>Beginpagina
    On the main page (blogid=7) just display the title of the mainpage 'Beginpagina'
  2. <%else%>
    NOT on a main page
  3. <a href="/test/index.php?blogid=7">Beginpagina</a> &rarr;
    Display link to the main page
  4. <%if(category)%>
    A categorie is selected:
  5. <a href="/test/index.php?blogid=<%blogsetting(id)%>"><%blogsetting(name)%></a> &rarr; <%category%>
    Display a link to the main categorie blog and show the (sub)categoriename at the end
  6. <%else%>
    NO categorie selected
  7. <%blogsetting(name)%>
    Just display the blog name (main categorie)
  8. <%endif%>
  9. <%endif%>

On the detailpage skin

<a href="/test/index.php?blogid=7">Beginpagina</a> &rarr; <a href="/test/index.php?blogid=<%blogsetting(id)%>"><%blogsetting(name)%></a> &rarr; <a href="/test/index.php?blogid=<%blogsetting(id)%>&catid=<%category(id)%>"><%category%></a> &rarr; <%itemtitle%>

Title of the latest item in your blog

Use <%otherblog(blogname,template,1)%> then in the template use <%title%> in the itembody part. I use this on the main page to put this into the title of the document so Google and other search engines display a decent title in the search results.

Select the skin you want

Use skinid as a parameter: http://www.trapveldje.net/index.php?itemid=37&skinid=18

Meta tag description

To put the first 255 characters of your item in the description meta tag of an item page use:

  1. <meta name="description" content="<%item(templatename)%>" />. In the template put <%syndicate_description(255)%> in the item body part.
    or
  2. <%otherblog(1,1,title_or_first_words)%>
    This <%otherblog%> tag will call your main blog (so get the blogid right, replace the first 1 with the right ID if necessary). It will only show 1 item (the last) and of that one item just the title or the first X characters (you just need to create a template with either <%title%> or <%syndicate_description(255)%>

http://forum.nucleuscms.org/viewtopic.php?t=2620

Select a template based on the category

<%if(category)%><%blog(default,5)%><%else%><%blog(default,5,'edutopical')%><%endif%>

http://forum.nucleuscms.org/viewtopic.php?t=2640

Display only one category

There are actually a couple of ways to let Nucleus to display only one category:

  1. The easiest is just selecting www.yourdomain.com/index.php?catid=X (X being the category's id)
  2. By calling your blog inside your Main Index Skin with <%blog(mytemplate,5,mycategory)%>
  3. By directly editing the index.php file that displays your front page. It will look something like this:
    $CONF['Self'] = 'index.php';
    include('config.php');
    selectBlog('shortblogname');
    selector();

By adding selectCategory('categoryname'); between selectBlog and selector, the front page can be forced to display one category. http://forum.nucleuscms.org/viewtopic.php?t=2507

If statements

Overview of if statements
if... Explanation
<%if(category)%> checks if a category is selected
<%if(loggedin)%> if visitor is logged in
<%if(skintype,typename)%> check for skintype
<%if(previtem)%>, <%if(nextitem)%>  
<%if(blogsetting,bshortname,blog)%>  
<%if(blogsetting,columnname,value)%> Column name can be any of the blog table column names (see below)
<%if(onteam)%>, <%if(onteam,myweblog)%>  

output when current visitor is logged in, and member of the currently selected blog (or has admin rights)

you can use <%if(blogsetting)%> with any of the blog table's column names as given in the mysql file:

Integrate photoalbums

http://photostack.org/

Plugin development

Global variables in plugins

Start your script defining the globals you need:

global $var1, $var2;
Overview of globals
global Explanation
$currentSkinName contains the name of the skin used
$skinType [index, item, archivelist, search, member, error]
if ($skinType == 'search')
$currentBlogid = $blog->getID() blog that is parsed in the skin.
$blog  
$blogid  
$catid  
$skinid  
$itemid  
$memberid  
$archive  
$archivelist  
$highlight  
$amount  
$action  
$nextaction  
$maxresults  
$startpos  
$query  
$imagepopup  
$member  
$manager  
$archive  
$query  
$CONF  

 

To retrieve e.g. item data use the global $manager; in the following way:

$item =& $manager->getItem($itemid,'','');
echo( $item['title'] );

$blog =& $manager->getBlog($blogid);
or
$blog =& $manager->getBlog(getBlogIDFromName('secondBlog'))

This way, only one blog object will be created during the request, and the info for the weblog will be read out of the database only once.
$blog->getName();

Request variables

Instead of using $_POST of $HTTP_POST_VARS to get request variables, it's suggested to use one of the following methods, making sure you get the same data under different PHP configurations:
$var = getVar('name'); // $_GET
$var = postVar('name'); // $_POST
$var = cookieVar('name'); // $_COOKIES
$var = serverVar('name'); // $_SERVER
$var = requestVar('name'); // $_REQUEST (=GET/POST or COOKIE)
$var = intPostVar('name'); // same as postVar, but parses data into an integer (intval)
$var = intGetVar('name'); // =intval(getVar(..))
$var = intRequestVar('name');
$var = intCookieVar('name');

All of these methods make sure that no magic quotes are present (the magic_quotes_gpc PHP option automagically replaces ' by \', when enabled), and work on all PHP versions on which Nucleus runs (4.0.6 - ...)

Global variables that are available without declaring global

The following global variables are accessible from within files included by the phpinclude skin/templatevar:

$GATEWAY_INTERFACE, $SERVER_NAME, $SERVER_SOFTWARE
$SERVER_PROTOCOL, $REQUEST_METHOD, $QUERY_STRING
$DOCUMENT_ROOT, $HTTP_ACCEPT, $HTTP_ACCEPT_CHARSET
$HTTP_ACCEPT_ENCODING, $HTTP_ACCEPT_LANGUAGE
$HTTP_CONNECTION, $HTTP_HOST, $HTTP_REFERER
$HTTP_USER_AGENT, $REMOTE_ADDR, $REMOTE_PORT
$SCRIPT_FILENAME, $SERVER_ADMIN, $SERVER_PORT
$SERVER_SIGNATURE, $PATH_TRANSLATED, $SCRIPT_NAME
$REQUEST_URI, $argv, $argc, $PHP_SELF
$HTTP_COOKIE_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS
$HTTP_POST_FILES, $HTTP_ENV_VARS, $HTTP_SERVER_VARS
$HTTP_SESSION_VARS, $PATH_INFO, $HTTPS
$HTTP_RAW_POST_DATA, $HTTP_X_FORWARDED_FOR

Functions

Create URL

When you need a link to something in a blog you can use these functions:

This way, the URL mode, normal or fancy, will be intact. $params is optional.

$params = array('catid' => 3, 'highlight' => 'WordIsearchedFor');
echo createItemLink($itemid, $params);

How Nucleus works

The first step after a visitor connects to your site is to load the index.php file. This is the default page:

<?php
// This file will generate and return the main page of the site
$CONF = array();
$CONF['Self'] = 'index.php';
include('../config.php');
selector();
?>
It starts with the declaration of the array $CONF and put the name of the index page into the array.

The next code is to include the file config.php. This file holds the basic settings of the Nucleus system e.g. the name of your database and the location of the Nucleus files. It also loads the globalfunctions.php which holds, as you may have guessed from the name, all the global functions needed to run Nucleus. The default location is /nucleus/libs/globalfunctions.php.

Between include('../config.php'); and selector(); the following statements can be used:

These can be used to force the page to display a certain category or blog.

This file also contains the next function: selector().

 function selector() {
global $itemid, $blogid, $memberid, $query, $amount, $archivelist, $maxresults;
global $archive, $skinid, $blog, $memberinfo, $CONF, $member;
global $imagepopup, $catid;
global $manager;
// first, let's see if the site is disabled or not
if ($CONF['DisableSite'] && !$member->isAdmin()) {
header('Location: ' . $CONF['DisableSiteURL']);
exit;
}
// show error when headers already sent out
if (headers_sent() && $CONF['alertOnHeadersSent']) {
// try to get line number/filename (extra headers_sent params only exists in PHP 4.3+)
if (function_exists('version_compare') && version_compare('4.3.0', phpversion(), '<=')) {
headers_sent($hsFile, $hsLine);
$extraInfo = ' in <code>'.$hsFile.'</code> line <code>'.$hsLine.'</code>';
} else {
$extraInfo = '';
} startUpError(
'<p>The page headers have already been sent out'.$extraInfo.'. This could cause Nucleus not to work in the expected way.</p><p>Usually, this is caused by spaces or newlines at the end of the <code>config.php</code> file, at the end of the language file or at the end of a plugin file. Please check this and try again.</p><p>If you don\'t want to see this error message again, without solving the problem, set <code>$CONF[\'alertOnHeadersSent\']</code> in <code>globalfunctions.php</code> to <code>0</code></p>',
'Page headers already sent'
);
exit;
}
// make is so ?archivelist without blogname or blogid shows the archivelist
// for the default weblog
if (serverVar('QUERY_STRING') == 'archivelist')
$archivelist = $CONF['DefaultBlog'];
// now decide which type of skin we need
if ($itemid) {
// itemid given -> only show that item
$type = 'item';
if (!$manager->existsItem($itemid,0,0))
doError(_ERROR_NOSUCHITEM); global $itemidprev, $itemidnext, $catid, $itemtitlenext, $itemtitleprev;
// 1. get timestamp and blogid for item
$query = 'SELECT UNIX_TIMESTAMP(itime) as itime, iblog FROM '.sql_table('item').' WHERE inumber=' . $itemid;
$res = sql_query($query);
$obj = mysql_fetch_object($res);
// if a different blog id has been set through the request or selectBlog(),
// deny access
if ($blogid && (intval($blogid) != $obj->iblog))
doError(_ERROR_NOSUCHITEM);
$blogid = $obj->iblog;
$timestamp = $obj->itime;
$b =& $manager->getBlog($blogid);
if ($b->isValidCategory($catid))
$catextra = ' and icat=' . $catid;
// get previous itemid and title
$query = 'SELECT inumber, ititle FROM '.sql_table('item').' WHERE itime<' . mysqldate($timestamp) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime DESC LIMIT 1';
$res = sql_query($query);
$obj = mysql_fetch_object($res);
if ($obj) {
$itemidprev = $obj->inumber;
$itemtitleprev = $obj->ititle;
}
// get next itemid and title
$query = 'SELECT inumber, ititle FROM '.sql_table('item').' WHERE itime>' . mysqldate($timestamp) . ' and itime <= ' . mysqldate(time()) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime ASC LIMIT 1';
$res = sql_query($query);
$obj = mysql_fetch_object($res);
if ($obj) {
$itemidnext = $obj->inumber;
$itemtitlenext = $obj->ititle;
}
} elseif ($archive) {
// show archive
$type = 'archive';
// get next and prev month links
global $archivenext, $archiveprev, $archivetype;
sscanf($archive,'%d-%d-%d',$y,$m,$d);
if ($d != 0) {
$archivetype = 'day'; // TODO: move to language file
$t = mktime(0,0,0,$m,$d,$y);
$archiveprev = strftime('%Y-%m-%d',$t - (24*60*60));
$archivenext = strftime('%Y-%m-%d',$t + (24*60*60));
} else {
$archivetype = 'month'; // TODO: move to language file
$t = mktime(0,0,0,$m,1,$y);
$archiveprev = strftime('%Y-%m',$t - (1*24*60*60));
$archivenext = strftime('%Y-%m',$t + (32*24*60*60));
} } elseif ($archivelist) {
$type = 'archivelist';
if (intval($archivelist) != 0)
$blogid = $archivelist;
else
$blogid = getBlogIDFromName($archivelist);
if (!$blogid) doError(_ERROR_NOSUCHBLOG);
} elseif ($query) {
global $startpos;
$type = 'search';
$query = stripslashes($query);
if ($blogid==0)
$blogid = getBlogIDFromName($blogid);
if (!$blogid) doError(_ERROR_NOSUCHBLOG);
} elseif ($memberid) {
$type = 'member';
if (!MEMBER::existsID($memberid))
doError(_ERROR_NOSUCHMEMBER);
$memberinfo = MEMBER::createFromID($memberid);
} elseif ($imagepopup) {
// media object (images etc.)
$type = 'imagepopup';
// TODO: check if media-object exists
// TODO: set some vars?
} else {
// show regular index page
global $startpos;
$type = 'index';
}
// decide which blog should be displayed
if (!$blogid)
$blogid = $CONF['DefaultBlog'];
if (!$manager->existsBlogID($blogid))
doError(_ERROR_NOSUCHBLOG);
$b =& $manager->getBlog($blogid);
$blog = $b; // references can't be placed in global variables?
// set catid if necessary
if ($catid)
$blog->setSelectedCategory($catid);
// decide which skin should be used
if ($skinid != '' && ($skinid == 0))
selectSkin($skinid);
if (!$skinid)
$skinid = $blog->getDefaultSkin();
if (!SKIN::existsID($skinid))
doError(_ERROR_NOSUCHSKIN);
$skin = new SKIN($skinid);
// parse the skin
$skin->parse($type);
}

The selector() function checks the url to see what kind of action is required e.g. display an item and then parses it with a call to SKIN.php:

$skin = new SKIN($skinid);
	// parse the skin
	$skin->parse($type);

Links

Skins & templates howto
Trick: Using skinvars in non-blog pages
If statement with blogsettings
HOWTO wiki