Commit 1b6520d6 authored by Nicholas Thompson's avatar Nicholas Thompson
Browse files

Some major reworking to the module including new features such as taxonomy and user page titles

parent ac470a37
<?php
$rows = array();
foreach (element_children($form['title']) as $key) {
$row = array();
$row[] = drupal_render($form['title'][$key]);
$row[] = drupal_render($form['pattern'][$key]);
foreach (element_children($form['pattern']) as $key) {
$title = array(
'#type' => 'item',
'#title' => $form['pattern'][$key]['#title'],
'#required' => $form['pattern'][$key]['#required'],
);
unset($form['pattern'][$key]['#title']);
$row = array(
drupal_render($title),
drupal_render($form['pattern'][$key]),
isset($form['showfield'][$key .'_showfield']) ? drupal_render($form['showfield'][$key .'_showfield']) : '',
);
$rows[] = $row;
}
print theme('table', array('Page Type', 'Pattern'), $rows);
print theme('table', array(t('Page Type'), t('Pattern'), t('Show Field')), $rows);
print drupal_render($form);
print '<h2>'. t('Available Tokens') .'</h2>'. theme('token_help');
......@@ -13,51 +13,102 @@
* array A structured array for use with Forms API.
*/
function page_title_admin_settings() {
//Define the titles
$form['title']['page_title_default'] = array('#type' => 'markup', '#value' => 'Default Pattern');
$form['title']['page_title_front'] = array('#type' => 'markup', '#value' => 'Frontpage Pattern');
// Define a default looking 'form element' for setting.
$showfield_form_element = array('#type' => 'checkbox', );
//Define the 'default' token patterns
$form['pattern']['page_title_default'] = array('#type' => 'textfield', '#default_value' => variable_get('page_title_default', '[page-title] | [site-name]'), '#size' => 30, '#maxlength' => 256, '#description' => t('This is the pattern used in a situation where a pattern is not defined specifically for a content type below.'), '#required' => TRUE, );
$form['pattern']['page_title_front'] = array('#type' => 'textfield', '#default_value' => variable_get('page_title_front', '[site-name] | [site-slogan]'), '#size' => 30, '#maxlength' => 256, '#description' => t('This is the frontpage pattern.'), );
//Definate the patterns per-node-type
// Define a default looking 'form element' for setting.
$pattern_form_element = array(
'#type' => 'textfield',
'#size' => 30,
'#maxlength' => 256,
);
// Set the theme callback for the patterns section
$form['patterns'] = array(
'#type' => 'fieldset',
'#title' => t('Page Title Patterns'),
'#collapsible' => TRUE,
'#theme' => 'page_title_admin_settings'
);
// Define the 'default' token patterns
$form['patterns']['pattern'] = array(
'page_title_default' => array(
'#title' => t('Default'),
'#default_value' => variable_get('page_title_default', '[page-title] | [site-name]'),
'#required' => TRUE,
) + $pattern_form_element,
'page_title_front' => array(
'#title' => t('Frontpage'),
'#default_value' => variable_get('page_title_front', '[site-name] | [site-slogan]'),
) + $pattern_form_element,
'page_title_user' => array(
'#title' => t('User Profile'),
'#default_value' => variable_get('page_title_user', ''),
) + $pattern_form_element,
);
// Define the "showfield" checkbox for the user profile page
$form['patterns']['showfield']['page_title_user_showfield'] = array(
'#default_value' => variable_get('page_title_user_showfield', 0),
) + $showfield_form_element;
// Definate the patterns per-node-type
$types = node_get_types();
foreach ($types as $type) {
// Define the node-type key
$key = 'page_title_type_'. $type->type;
$form['title'][$key] = array('#type' => 'markup', '#value' => t('Pattern for %type', array('%type' => $type->name)), );
$form['pattern'][$key] = array('#type' => 'textfield', '#default_value' => variable_get($key, ''), '#size' => 30, '#maxlength' => 256, '#description' => t('If left blank, will inherit from default settings.'), );
// Pattern entry
$form['patterns']['pattern'][$key] = array(
'#title' => t('Content Type - %type', array('%type' => $type->name)),
'#default_value' => variable_get($key, ''),
) + $pattern_form_element;
$form['patterns']['showfield'][$key .'_showfield'] = array(
'#default_value' => variable_get($key .'_showfield', 0),
) + $showfield_form_element;
}
//Add the system buttons to the form
$form = system_settings_form($form);
//Overide the theme function back to our own one
$form['#theme'] = 'page_title_admin_settings';
return $form;
}
// Definate the patterns per-vocab-type - if Taxonomy Module is enabled
if (module_exists('taxonomy')) {
$vocabs = taxonomy_get_vocabularies();
foreach ($vocabs as $vocab) {
// Define the vocab key
$key = 'page_title_vocab_'. $vocab->vid;
// Pattern entry
$form['patterns']['pattern'][$key] = array(
'#title' => t('Vocabulary - %vocab_name', array('%vocab_name' => $vocab->name)),
'#default_value' => variable_get($key, ''),
) + $pattern_form_element;
/**
* Displays the form for the "Content creation types" tab.
*
* @return
* array A structured form array for use with Forms API.
*/
function page_title_admin_types() {
$form['page_title_fieldset'] = array(
$form['patterns']['showfield'][$key .'_showfield'] = array(
'#default_value' => variable_get($key .'_showfield', 0),
) + $showfield_form_element;
}
}
// Add the token help to a collapsed fieldset at the end of the configuration page.
$form['token_help'] = array(
'#type' => 'fieldset',
'#title' => t('Content creation forms'),
'#description' => t('Display a "Page title" field for these content types.'),
'#title' => t('Available Tokens List'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['page_title_fieldset']['page_title_display'] = array(
'#type' => 'checkboxes',
'#default_value' => variable_get('page_title_display', array()),
'#options' => node_get_types('names'),
$form['token_help']['content'] = array(
'#type' => 'markup',
'#value' => theme('token_help'),
);
// Add save button, etc to the form.
// Return the form with the system buttons & action added to it
return system_settings_form($form);
}
......@@ -14,19 +14,56 @@ function page_title_install() {
}
/**
* Implementation of hook_schema().
*/
function page_title_schema() {
$schema['page_title'] = array(
'fields' => array(
'nid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
'type' => array('type' => 'varchar', 'length' => 15, 'not null' => TRUE, 'default' => 'node'),
'id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
'page_title' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '')
),
'primary key' => array('nid'),
'primary key' => array('type', 'id'),
);
return $schema;
}
/**
* Implementation of hook_update_n().
*/
function page_title_update_6200() {
$ret = array();
db_create_table($ret, 'page_title_temp', array(
'fields' => array(
'type' => array('type' => 'varchar', 'length' => 15, 'not null' => TRUE, 'default' => 'node'),
'id' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0),
'page_title' => array('type' => 'varchar', 'length' => 255, 'not null' => TRUE, 'default' => '')
),
'primary key' => array('type', 'id'),
));
$ret[] = update_sql('INSERT INTO {page_title_temp} (id, page_title) SELECT nid, page_title FROM {page_title}');
db_rename_table($ret, 'page_title', 'page_title_old');
db_rename_table($ret, 'page_title_temp', 'page_title');
$display_settings = variable_get('page_title_display', array());
foreach ($display_settings as $type) {
if ($type) {
variable_set('page_title_type_'. $type .'_showfield', 1);
}
}
variable_del('page_title_display');
return $ret;
}
/**
* Implementation of hook_uninstall().
*/
......
......@@ -16,23 +16,21 @@
* Implementation of hook_help().
*/
function page_title_help($path, $arg) {
$output = NULL;
switch ($path) {
case 'admin/help#page_title':
$output = '<p>'. t('Provides control over the &lt;title> element on a page using token patterns and an optional textfield to override the node title.') .'</p>';
$output .= '<p>'. t('Below are all the tokens you can use with <strong><em>Page Title</em></strong>:') .'</p>';
$output .= theme('token_help');
break;
case 'admin/content/page_title':
$output = t("<p>Drupal's default page title follows one of two patterns:</p>
<ol>
<li><strong>Default Page:</strong> <em>page title</em> | <em>site name</em></li>
<li><strong>Default Frontpage:</strong> <em>site name</em> | <em>site slogan</em></li>
</ol>
<p>The <strong>Page Title</strong> module lets you change these defaults in two ways. First, you can adjust the patterns below using the placeholders given. This will change the way the default page titles are created. Second, on every content creation form you can have the option of specifying a title that is different than the title of the node. If a value is provided, this will be used to generate the <code>[page-title]</code> placeholder. If left blank, <code>[page-title]</code> will inherit the node's title.</p>
<p><code>[page-title]</code> will default to the value returned from <code>drupal_get_title</code> if there is no overriden page title.</p>");
$output = '<p>'. t('Page Title provides control over the &lt;title> element on a page using token patterns and an optional textfield to override the title of the item (be it a node, term, user or other). You can configure these settings below. Please click on the <strong><em>more help&hellip;</em></strong> link below if you need further assistance.') .'</p>';
break;
case 'admin/content/page_title/types':
$output = '<p>'. t('To display a <em>Page Title</em> field on a node (just below the <em>Title</em> field), you will need to enable it for the appropriate content types below.') .'</p>';
case 'admin/help#page_title':
$output = '<p>'. t('Drupal\'s default page title follows one of two patterns:') .'</p>';
$items = array(
t('<strong>Default Page</strong>: <samp><em>page title</em> | <em>site name</em></samp>'),
t('<strong>Default Frontpage</strong>: <samp><em>site name</em> | <em>site slogan</em></samp>'),
);
$output .= theme('item_list', $items, NULL, 'ol');
$output .= '<p>'. t('The <strong>Page Title</strong> module lets you change these defaults in two ways. First, you can adjust the patterns below using the placeholders given. This will change the way the default page titles are created. Second, on enabled forms (curently node, term & user editing forms) you have the option of specifying a title that is different to the title of the item. This field only appears if the <em>Show Field</em> box is checked for the item. If a value is provided it will be used to generate the <samp>[page-title]</samp> placeholder however if it is left blank the <samp>[page-title]</samp> token will inherit the item\'s own title.') .'</p>';
$output .= '<p>'. t('The <samp>[page-title]</samp> token will default to the value returned from <samp>drupal_get_title</samp> if there is no value specified or no available page title field.') .'</p>';
$output .= '<p>'. t('Certain types of page title pattern have access to special tokens which others do not, depending on their <em>scope</em>. All patterns have access to the <strong>Global</strong> scope. Content type patterns have access to the <strong>Node</strong> tokens, vocabulary patterns have access to the <strong>Taxonomy</strong> tokens and finally the user patterns have access to the <strong>User</strong> tokens.') .'</p>';
break;
}
return $output;
......@@ -63,25 +61,6 @@ function page_title_menu() {
'type' => MENU_NORMAL_ITEM,
'file' => 'page_title.admin.inc',
);
$items['admin/content/page_title/settings'] = array(
'title' => 'Default settings',
'description' => 'Control the page title settings.',
'access callback' => 'user_access',
'access arguments' => array('administer page titles'),
'type' => MENU_DEFAULT_LOCAL_TASK,
'file' => 'page_title.admin.inc',
'weight' => -10,
);
$items['admin/content/page_title/types'] = array(
'title' => 'Content type settings',
'description' => 'Control the display of the Page title field.',
'page callback' => 'drupal_get_form',
'page arguments' => array('page_title_admin_types'),
'access callback' => 'user_access',
'access arguments' => array('administer page titles'),
'file' => 'page_title.admin.inc',
'type' => MENU_LOCAL_TASK,
);
return $items;
}
......@@ -111,34 +90,24 @@ function page_title_theme() {
*/
function page_title_node_type($op, $info) {
if ($op == 'update' && !empty($info->old_type) and $info->type != $info->old_type) {
//Get the display settings for node types
$display = variable_get('page_title_display', array());
// Load the old node type settings.
$temp = variable_get('page_title_type_'. $info->old_type, '');
//If the old one is set, set the new one
if ($display[$info->old_type]) {
$display[$info->type] = $info->type;
}
//Otherwise the new type is disabled like the old one was
else {
$display[$info->type] = 0;
// If the settings aren't empty, then save them into the new type
if (!empty($temp)) {
variable_set('page_title_type_'. $info->type, $temp);
}
//Unset the old type
unset($display[$info->old_type]);
// Delete the old setting
variable_del('page_title_type_'. $info-old_type);
//Save the settings
variable_set('page_title_display', $display);
//Get the old pattern, if set
$old_pattern = variable_get('page_title_type_'. $info->old_type, '');
//If it was set then set the new one to whatever the old pattern was
if (!empty($old_pattern)) {
variable_set('page_title_type_'. $info->type, $old_pattern);
// Essentially, do the same as above but with the _showfield suffix for the node type
$temp = variable_get('page_title_type_'. $info->old_type .'_showfield', 0);
if ($temp) {
variable_set('page_title_type_'. $info->type .'_showfield', $temp);
}
//Delete the old pattern
variable_del('page_title_type_'. $info->old_type);
variable_del('page_title_type_'. $info-old_type .'_showfield');
}
}
......@@ -147,13 +116,13 @@ function page_title_node_type($op, $info) {
* Implementation of hook_form_alter().
*/
function page_title_form_alter(&$form, $form_state, $form_id) {
//If we dont have permission to set the title then we need to abort this alter now!
// If we dont have permission to set the title then we need to abort this alter now!
if (!user_access('set page title')) return;
$display = variable_get('page_title_display', array());
//Check we're editing a node form and also check that the node type 'value' is enabled
if ($form['#id'] == 'node-form' && $display[$form['type']['#value']]) {
// Check we're editing a node and also check that the node type's 'show field' is enabled
if ($form['#id'] == 'node-form') {
$key = 'page_title_type_'. $form['type']['#value'] .'_showfield';
if (variable_get($key, 0)) {
$form['page_title'] = array(
'#type' => 'textfield',
'#title' => t('Page title'),
......@@ -164,6 +133,36 @@ function page_title_form_alter(&$form, $form_state, $form_id) {
'#weight' => -4,
);
}
}
// Check we're editing a taxonomy term and also check that the terms vocabulary's 'show field' is enabled
elseif ($form_id == 'taxonomy_form_term') {
$key = 'page_title_vocab_'. $form['vid']['#value'] .'_showfield';
if (variable_get($key, 0)) {
$form['advanced']['page_title'] = array(
'#type' => 'textfield',
'#title' => t('Page title'),
'#description' => t('Optionally specify a different title to appear in the &lt;title&gt; tag of the page.'),
'#default_value' => page_title_load_title($form['tid']['#value'], 'term'),
'#size' => 60,
'#maxlength' => 255,
'#weight' => -20,
);
}
}
// Check we're editing a user profile and also check that the user settings's have 'show field' enabled
elseif ($form_id == 'user_profile_form') {
if (variable_get('page_title_user_showfield', 0)) {
$form['account']['page_title'] = array(
'#type' => 'textfield',
'#title' => t('Page title'),
'#description' => t('Optionally specify a different title to appear in the &lt;title&gt; tag of the page.'),
'#default_value' => page_title_load_title($form['_account']['#value']->uid, 'user'),
'#size' => 60,
'#maxlength' => 255,
'#weight' => 20,
);
}
}
}
......@@ -174,21 +173,69 @@ function page_title_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
switch ($op) {
case 'update':
if (user_access('set page title')) {
db_query("DELETE FROM {page_title} WHERE nid = %d", $node->nid);
db_query('DELETE FROM {page_title} WHERE type = "node" AND id = %d', $node->nid);
}
// fallthrough to insert intentional!
case 'insert':
if (isset($node->page_title) && drupal_strlen(trim($node->page_title)) > 0 && user_access('set page title')) {
db_query("INSERT INTO {page_title} VALUES (%d, '%s')", $node->nid, $node->page_title);
db_query('INSERT INTO {page_title} VALUES ("node", %d, "%s")', $node->nid, $node->page_title);
}
break;
case 'delete':
db_query('DELETE FROM {page_title} WHERE nid = %d', $node->nid);
db_query('DELETE FROM {page_title} WHERE type = "node" AND id = %d', $node->nid);
break;
case 'load':
return array('page_title' => page_title_node_get_title($node->nid));
return array('page_title' => page_title_load_title($node->nid, 'node'));
}
}
/**
* Implementation of hook_taxonomy().
*/
function page_title_taxonomy($op, $type, $edit) {
if ($type == 'vocabulary') return;
switch ($op) {
case 'update':
if (user_access('set page title')) {
db_query('DELETE FROM {page_title} WHERE type = "term" AND id = %d', $edit['tid']);
}
// Fallthrough to insert is intentional!
case 'insert':
if (isset($edit['page_title']) && drupal_strlen(trim($edit['page_title'])) > 0 && user_access('set page title')) {
db_query('INSERT INTO {page_title} VALUES("term", %d, "%s")', $edit['tid'], $edit['page_title']);
}
break;
case 'delete':
db_query('DELETE FROM {page_title} WHERE type = "term" AND id = %d', $edit['tid']);
break;
}
}
/**
* Implementation of hook_user().
*/
function page_title_user($op, &$edit, &$account) {
switch ($op) {
case 'update':
if (user_access('set page title')) {
db_query('DELETE FROM {page_title} WHERE type = "user" AND id = %d', $account->uid);
}
// Fallthrough to insert is intentional!
case 'insert':
if (isset($edit['page_title']) && drupal_strlen(trim($edit['page_title'])) > 0 && user_access('set page title')) {
db_query('INSERT INTO {page_title} VALUES("user", %d, "%s")', $account->uid, $edit['page_title']);
}
break;
case 'delete':
db_query('DELETE FROM {page_title} WHERE type = "user" AND id = %d', $account->uid);
break;
}
}
......@@ -196,30 +243,31 @@ function page_title_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
/**
* Simple wrapper function to get the currently set title for a page
*
* @return unknown
* @return
* string the title for the current page
*/
function page_title_get_title() {
// Get the page title display settings.
$display_options = variable_get('page_title_display', array());
// Default to using the drupal internal title
$title = drupal_get_title();
// If we're looking at a node or a comment on a node, get the node object from the menu system.
if ((arg(0) == 'node') && (is_numeric(arg(1)))) {
if ((arg(0) == 'node' && is_numeric(arg(1))) || (arg(0) == 'comment' && arg(1) == 'reply' && is_numeric(arg(2))) && module_exists('comment')) {
$node = menu_get_object();
// If the node has a custom page title and the node type is configured to have a custom page title (ie, it's not a leftover from a previous setting), then use it.
if (!empty($node->page_title) && variable_get('page_title_type_'. $node->type .'_showfield', 0)) {
$title = $node->page_title;
}
elseif ((arg(0) == 'comment') && (arg(1) == 'reply') && (is_numeric(arg(2)))) {
$node = menu_get_object();
}
else {
$node = NULL;
elseif (arg(0) == 'user' && is_numeric(arg(1))) {
if (variable_get('page_title_user_showfield', 0) && ($user_title = page_title_load_title(arg(1), 'user'))) {
$title = $user_title;
}
// If we have a node and the node type is configured to have a custom page title and the node itself has a custom page title, use it.
if ($node && $display_options[$node->type] && !empty($node->page_title)) {
$title = $node->page_title;
}
// Otherwise, use the drupal title.
else {
$title = drupal_get_title();
elseif (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2)) && module_exists('taxonomy')) {
$term = taxonomy_get_term(arg(2));
if (variable_get('page_title_vocab_'. $term->vid .'_showfield', 0) && ($term_title = page_title_load_title($term->tid, 'term'))) {
$title = $term_title;
}
}
// Give other modules the oppertunity to use hook_page_title_alter().
......@@ -231,15 +279,27 @@ function page_title_get_title() {
/**
* Gets the page title for a node id.
* Gets the page title for a type & id.
*
* @param $id
* int The objects id.
* @param $type
* string What is the scope (usually 'node', 'term' or 'user').
*
* @param $nid
* int The node's id.
* @return
* string The node's page title.
* string the page title for the given type & id.
*/
function page_title_load_title($id, $type) {
return db_result(db_query('SELECT page_title FROM {page_title} WHERE type = "%s" AND id = %d', $type, $id));
}
/**
* Wrapper for old function...
* NOTE: This has been depricated in favor of page_title_load_title().
*/
function page_title_node_get_title($nid) {
return db_result(db_query('SELECT page_title FROM {page_title} WHERE nid = %d', $nid));
return page_title_load_title($nid, 'node');
}
......@@ -258,46 +318,50 @@ function page_title_page_get_title() {
if (is_null($title)) {
// If frontpage, then use the frontpage pattern and set the title.
if (drupal_is_front_page()) {
//Get the frontpage pattern
// Get the frontpage pattern
$page_title_pattern = variable_get('page_title_front', '[site-name] | [site-slogan]');
//If the frontpage pattern is empty, fallback to the default.
// If the frontpage pattern is empty, fallback to the default.
if (empty($page_title_pattern)) {
$page_title_pattern = variable_get('page_title_default', '[page-title] | [site-slogan]');
}
$title = token_replace($page_title_pattern, 'page_title');
$title = token_replace($page_title_pattern);
}
//Otherwise this is a non-frontpage page title.
// Otherwise this is a non-frontpage page title.
else {
//Get the node for this page
$node = ((arg(0) == 'node') && (is_numeric(arg(1)))) ? menu_get_object() : NULL;
//Get the pattern for the node type. If no node type available, assume blank
$title = variable_get('page_title_type_'. (isset($node->type) ? $node->type : ''), '');
//If pattern is emtpy (either if the type is not overridable or simply not set) fallback to the default pattern
if (empty($title)) {
$title = variable_get('page_title_default', '[page-title] | [site-name]');
// Initialize some variables we need
$page_title_pattern = '';
$types = array('global' => NULL);
// Determine scope
// Node (either node or comment reply)
if ((arg(0) == 'node' && is_numeric(arg(1))) || (arg(0) == 'comment' && arg(1) == 'reply' && is_numeric(arg(2)) && module_exists('comment')) ) {
$types['node'] = menu_get_object();
$page_title_pattern = variable_get('page_title_type_'. $types['node']->type, '');
}
//Define Token Types array
$types = array();
//Return the title using the node scope if node is set, and then add our scope replacements
if (isset($node)) {
$types['node'] = $node;
// Term
elseif (arg(0) == 'taxonomy' && arg(1) == 'term' && is_numeric(arg(2)) && module_exists('taxonomy')) {
$types['taxonomy'] = taxonomy_get_term(arg(2));
$page_title_pattern = variable_get('page_title_vocab_'. $types['taxonomy']->vid, '');
}
// User
elseif (arg(0) == 'user' && is_numeric(arg(1))) {
$types['user'] = user_load(array('uid' => arg(1)));
$page_title_pattern = variable_get('page_title_user', '');
}
//Finally, the page_title fallback
$types['page_title'] = NULL;
// If pattern is emtpy (either if the type is not overridable or simply not set) fallback to the default pattern)
if (empty($page_title_pattern)) {
$page_title_pattern = variable_get('page_title_default', '[page-title] | [site-name]');
}
//Apply token patterns using token_replace_multiple
$title = token_replace_multiple($title, $types);
// Apply token patterns using token_replace_multiple
$title = token_replace_multiple($page_title_pattern, $types);