Filing the content
Create site20 by copying site19.
- /cms
- ...
- site19
- site20
In this chapter, we are going to organize nodes in threads.
To test the result online, enter http://www.frasq.org/cms/site20/en/thread/1 in the address bar of your navigator. The site displays the content of thread 1 in English. Enter http://www.frasq.org/cms/site20/fr/fil/1 to display its translation in French.
A thread has a title, a name, an abstract and a cloud of words associated to it. A thread contains an ordered list of nodes. Click on the link Legal information to display node 1.
Start the command processor of MySQL and enter in the site's DB:
$ mysql -u root -p
mysql> use frasqdb2;
NOTE: Use phpMyAdmin for more comfort.
Add the table thread
then the table thread_locale
to the DB of the site:
thread_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
user_id INT(10) NOT NULL DEFAULT '1',
thread_type enum('thread') NOT NULL DEFAULT 'thread',
created datetime NOT NULL,
modified datetime NOT NULL,
PRIMARY KEY (thread_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
thread
contains the properties of a node which are in common for all languages: its identifier, the identifier of the user who has modified it for the last time, the type of the thread, its creation and modification dates.
The type of a thread will allow a particular interpretation of its contents - book, blog, forum, wiki etc.
The primary key of a thread
is its identifier.
thread_id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
locale enum('fr','en') NOT NULL DEFAULT 'fr',
name VARCHAR(100) NOT NULL,
title VARCHAR(100) NOT NULL,
abstract text,
cloud text,
PRIMARY KEY (thread_id,locale)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
A thread_locale
contains the properties of a thread which depend on a language: the designation of language of the content, the name of the thread, its title, the abstract and the list of words associated to the thread.
The identifier of a thread_locale
matches the identifier of a thread
.
The designations of the languages must match the languages listed by the configuration parameter $supported_languages
defined in the file includes/config.inc.
The primary key of a thread_locale
is its identifier and the designation of the language of its content.
The link between a thread and the nodes it contains is done by the table thread_node
:
thread_id INT(10) UNSIGNED NOT NULL,
node_id INT(10) UNSIGNED NOT NULL,
`number` INT(4) UNSIGNED NOT NULL,
PRIMARY KEY (thread_id,node_id)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
A thread_node
lists and orders the nodes of a thread.
The identifier thread_id
matches the identifier of a thread
.
node_id
matches the identifier of a node in node
.
The primary key of a thread_node
is the identifier of a thread and the identifier of a node.
Create a first thread:
(1, 1, 'thread', NOW(), NOW());
Thread 1 is created by the user 1, the administrator of the site. Check in the table user
.
Add a content in English:
(1, 'en', 'folder', 'Folder', 'Articles, notes and various pages.', 'articles notes information');
Add the version en French:
(1, 'fr', 'classeur', 'Classeur', 'Articles, notes et pages diverses.', 'articles notes informations');
Associate node 1 to thread 1 and place it at position 1:
Try a few requests on the DB:
Checks that thread 1 has been created.
Checks the name of thread 1 in English.
Checks that node 1 belongs to thread 1.
Returns the identifier of the node of thread 1 according to its name in English.
Returns all the properties of all the nodes of thread 1 in English.
Add the file thread.inc in the folder models with the following content:
- function thread_id($thread) {
- if (is_numeric($thread)) {
- $tabthread=db_prefix_table('thread');
- $sql="SELECT thread_id FROM $tabthread WHERE thread_id=$thread LIMIT 1";
- }
- else {
- $sqlname=db_sql_arg($thread, true);
- $tabthreadlocale=db_prefix_table('thread_locale');
- $sql="SELECT thread_id FROM $tabthreadlocale WHERE name=$sqlname LIMIT 1";
- }
- $r = db_query($sql);
- return $r ? $r[0]['thread_id'] : false;
- }
thread_id
returns the thread_id
of the thread whose identifier or name is $thread
, or false
if a thread with thread_id
or thread_name
set to $thread
doesn't exist.
- function thread_node_id($thread_id, $node) {
- if (is_numeric($node)) {
- $tabthreadnode=db_prefix_table('thread_node');
- $sql="SELECT tn.node_id AS node_id FROM $tabthreadnode tn WHERE tn.thread_id=$thread_id AND tn.node_id=$node LIMIT 1";
- }
- else {
- $sqlname = db_sql_arg($node, true);
- $tabthreadnode=db_prefix_table('thread_node');
- $tabnodelocale=db_prefix_table('node_locale');
- $sql="SELECT tn.node_id AS node_id FROM $tabthreadnode tn JOIN $tabnodelocale nl ON nl.node_id=tn.node_id WHERE tn.thread_id=$thread_id AND nl.name=$sqlname LIMIT 1";
- }
- $r = db_query($sql);
- return $r ? $r[0]['node_id'] : false;
- }
thread_node_id
returns the node_id
of the node contained in the thread $thread_id
whose identifier or name is $node
, or false
if thread $thread_id
doesn't contain a node with node_id
or node_name
set to $node
.
- function thread_get($lang, $thread_id) {
- $sqllang=db_sql_arg($lang, false);
- $tabthread=db_prefix_table('thread');
- $tabthreadlocale=db_prefix_table('thread_locale');
- $sql="SELECT tloc.name AS thread_name, tloc.title AS thread_title, tloc.abstract AS thread_abstract, tloc.cloud AS thread_cloud, t.thread_type AS thread_type, UNIX_TIMESTAMP(t.created) AS thread_created, UNIX_TIMESTAMP(t.modified) AS thread_modified FROM $tabthread t JOIN $tabthreadlocale tloc ON tloc.thread_id=t.thread_id AND tloc.locale=$sqllang WHERE t.thread_id=$thread_id LIMIT 1";
- $r = db_query($sql);
- return $r ? $r[0] : false;
- }
thread_get
returns all the attributes for the language $lang
of the thread whose identifier is $thread_id
, or false
in case of error.
Notice that the fields thread_created
and thread_modified
are converted to a Unix time.
- function thread_get_contents($lang, $thread_id) {
- $sqllang=db_sql_arg($lang, false);
- $tabthreadnode=db_prefix_table('thread_node');
- $tabnodelocale=db_prefix_table('node_locale');
- $sql="SELECT tn.node_id, tn.number AS node_number, nl.name AS node_name, nl.title AS node_title, nl.abstract AS node_abstract, nl.cloud AS node_cloud FROM $tabthreadnode tn LEFT JOIN $tabnodelocale nl ON nl.node_id=tn.node_id AND nl.locale=$sqllang WHERE tn.thread_id=$thread_id ORDER BY tn.number";
- $r = db_query($sql);
- return $r;
- }
thread_get_contents
returns the content of the thread $thread_id
for the language $lang
, or false
in case of error.
Create the action thread
by adding the file thread.php then the file threadsummary.php in the folder actions with the following contents:
- /cms/site20
- actions
- thread.php
- threadsummary.php
- actions
- function thread($lang, $arglist=false) {
- $thread=false;
- if (is_array($arglist)) {
- if (isset($arglist[0])) {
- $thread=$arglist[0];
- }
- }
- if (!$thread) {
- return run('error/notfound', $lang);
- }
- require_once 'actions/threadsummary.php';
- return threadsummary($lang, $thread);
- }
- require_once 'models/thread.inc';
- function threadsummary($lang, $thread) {
- $thread_id = thread_id($thread);
- if (!$thread_id) {
- return run('error/notfound', $lang);
- }
- $r = thread_get($lang, $thread_id);
- if (!$r) {
- return run('error/notfound', $lang);
- }
- extract($r); /* thread_name thread_title thread_abstract thread_cloud */
- head('title', $thread_title);
- head('description', $thread_abstract);
- head('keywords', $thread_cloud);
- $validate=url('thread', $lang) . '/'. $thread_name;
- $banner = build('banner', $lang, compact('validate'));
- $r = thread_get_contents($lang, $thread_id);
- $thread_contents = array();
- if ($r) {
- $node_uri = url('node', $lang);
- foreach ($r as $c) {
- extract($c); /* node_id node_name node_title node_number */
- $node_url = $node_uri . '/' . $node_id;
- $thread_contents[] = compact('node_title' , 'node_url');
- }
- }
- $content = view('threadsummary', $lang, compact('thread_title', 'thread_abstract', 'thread_cloud', 'thread_contents'));
- $output = layout('standard', compact('banner', 'content'));
- return $output;
- }
To give access to the thread
action, add an alias for each language in the file includes/aliases.inc:
- 'thread' => 'thread',
- 'fil' => 'thread',
Add the view of the summary of a thread in the folders views/en for the English version and views/fr for the version in French:
- /cms/site20
- views
- en
- threadsummary.phtml
- fr
- threadsummary.phtml
- en
- views
- <h3><?php echo htmlspecialchars($thread_title, ENT_COMPAT, 'UTF-8'); ?></h3>
- <?php if ($thread_abstract): ?>
- <h5>Abstract</h5>
- <p><?php echo htmlspecialchars($thread_abstract, ENT_COMPAT, 'UTF-8'); ?></p>
- <?php endif; ?>
- <?php if ($thread_cloud): ?>
- <h6>Cloud</h6>
- <p class="smaller"><?php echo htmlspecialchars($thread_cloud, ENT_COMPAT, 'UTF-8'); ?></p>
- <?php endif; ?>
- <h4>Contents</h4>
- <ol>
- <?php foreach ($thread_contents as $c): ?>
- <?php extract($c); /* node_title node_url */ ?>
- <li><a href="<?php echo $node_url; ?>"><?php echo htmlspecialchars($node_title, ENT_COMPAT, 'UTF-8'); ?></a></li>
- <?php endforeach; ?>
- </ol>
- <h3><?php echo htmlspecialchars($thread_title, ENT_COMPAT, 'UTF-8'); ?></h3>
- <?php if ($thread_abstract): ?>
- <h5>Extrait</h5>
- <p><?php echo htmlspecialchars($thread_abstract, ENT_COMPAT, 'UTF-8'); ?></p>
- <?php endif; ?>
- <?php if ($thread_cloud): ?>
- <h6>Nuage</h6>
- <p class="smaller"><?php echo htmlspecialchars($thread_cloud, ENT_COMPAT, 'UTF-8'); ?></p>
- <?php endif; ?>
- <h4>Contenu</h4>
- <ol>
- <?php foreach ($thread_contents as $c): ?>
- <?php extract($c); /* node_title node_url */ ?>
- <li><a href="<?php echo $node_url; ?>"><?php echo htmlspecialchars($node_title, ENT_COMPAT, 'UTF-8'); ?></a></li>
- <?php endforeach; ?>
- </ol>
Enter http://localhost/cms/site20/en/thread/1 then http://localhost/cms/site20/fr/fil/1 in the address bar of your navigator.
Comments