Here is my current component setup. I have a very dynamic page generation component that syncs with data from a external API to create pages for products without extra data entry.
Right now it works at a simple button click to populate all and update any changes, or just update individual fields. What this leads to is the generation of static "pages" from the api in joomla, and the ability to update it from the api.
The problem comes into the fact that this is used as the "home" menu item so the component itself takes the root directory. What I need is each "page" to take a sub menu of home automatically, though just setting the main menu item as home does not seem to work, it leads to the JRoute class getting confused and using component/ , everything I have read so far takes the assumption it is not the default menu item so I am losing home making it fully automatic.
So my question is, is there a function class to create menu items from components in joomla? adding another row to the joomla menu table for each page while i update them "should" solve the problem, I know I can try to figure out how joomla adds them to the database on my own, but I would prefer to use a joomla class/function if at all possible, any ideas?
here is my current router.php, works fine for directly linking to the page but not when using JRoute. There is some uneeded parts to this as I have been doing some extensive testing though.
<?php
defined('_JEXEC') or die;
function GoFormsBuildRoute($query){
$segments = array();
$app = JFactory::getApplication();
$menu = $app->getMenu();
$params = JComponentHelper::getParams('com_goforms');
$db = JFactory::getDBO();
if (empty($query['Itemid'])) {
$menuItem = $menu->getActive();
$menuItemGiven = false;
}
else {
$menuItem = $menu->getItem($query['Itemid']);
$menuItemGiven = true;
}
//print_r($menuItem);
if(isset($query['option'])){
unset($query['option']);
}
if(isset($query['view'])){
$view = $query['view'];
}else{
return $segments;
}
unset($query['view']);
if(isset($query['id'])){
if ($menuItemGiven && isset($menuItem->query['id'])) {
$mCatid = $menuItem->query['id'];
} else {
$mCatid = 0;
}
//echo 'hi';
if(strpos($query['id'], ':') === false) {
$db = JFactory::getDbo();
$aquery = $db->setQuery($db->getQuery(true)
->select('alias')
->from('#__goforms_list')
->where('id='.(int)$query['id'])
);
$alias = $db->loadResult();
$query['id'] = $alias;
}
$segments[] = $query['id'];
unset($query['id']);
}
print_r($segments);
return $segments;
}
function GoFormsParseRoute($segments){
$vars = array();
$app = JFactory::getApplication();
$menu = $app->getMenu();
$item = $menu->getActive();
$params = JComponentHelper::getParams('com_goforms');
$db = JFactory::getDBO();
print_r($item);
$count = count($segments);
if($count == 1){
if(isset($segments[0])){
$vars['view'] = 'region';
$alias = str_replace(':','-',$segments[0]);
//print_r($alias);
//echo '<br>';
$query = 'SELECT alias, id FROM #__goforms_list WHERE alias = "'.$alias.'"';
$db->setQuery($query);
$page = $db->loadObject();
if($page){
$vars['view'] = 'region';
$vars['id'] = (int)$page->id;
return $vars;
}else{
$vars['view'] = 'goforms';
}
}else{
$vars['view'] = 'goforms';
}
}
return $vars;
}
?>
in review:
Joomla 2.5
component is at root menu item of site (home)
items from component need to fall under the first level of menu after home
links work, however JRoute class in joomla does not properly make the link.
Related
ORGINAL QUERY - Updated Query Below
I am in the process of building a custom application in PHP. I know there have been many questions asked about Routing etc. on here and I have spent many of hours reading them all. This is how I got my routing elements to work in the first place. However 1 thing I cant get to fit into my project is peoples suggestions on how to route URLs based on a database entry.
The application itself is working perfectly fine and I already have some URL Routing in place which works exactly how I want it. The issue I have is when I add new products into my database I have a trigger that generates a SEO Friendly URL and stores it in a field in the database.
All the product URLs are structured in the same way.
/North/productdetails/Productname
/South/productdetails/Productname
/NorthEast/productdetails/Productname
etc.
What I am looking to do is not have to manually write a new URL Route into the routes.php file every time a product is added.
this is my .htaccess
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
rewriteRule ^(.+)$ index.php?uri=$1 [QSA,L]
and my index.php file contains:
<?php
header("Cache-Control: no-cache");
include 'System/Config/route.php';
include 'System/Config/settings.php';
connect();
$route = new Route();
include 'System/Config/routeURL.php';
$route->add('/', 'Home');
$route->add('/results', 'Results');
$route->add('/special', 'Special');
$route->gogo();
?>
I need something like this to go in and catch every URL passed to it. It then needs to check the URL and send the relevant information to a page.
$route->add('/results/NorthEast/productdetails/<whateveryisstoredindatabse>', 'productURLS');
The class file that I use at the min to check it is this:
class productURLS
{
function Item($itemID)
{
$host = $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
$itemID = '0';
if($host == host +<URLStored in database>) {
$itemID = <what ever id is in database>;
} else {
$itemID = '0';
$_POST['ShowProductDetails'] = $itemID;
}
public function __construct()
{
productURLS::Item($ItemID);
include 'pages/productdetails.php';
}
}
The class I wrote above is what I use to deter the current URLS onsite, I have modified it to identify where I need help on.
This is the route controller:
class Route
{
private $_uri = array();
private $_method = array();
/**
* Builds a collection of internal URL's to look for
* #param type $uri
*/
public function add($uri, $method = null)
{
$this->_uri[] = '/' . trim($uri, '/');
if ($method != null) {
$this->_method[] = $method;
}
}
/**
* Triggers from start page
*/
public function gogo()
{
$uriGetParam = isset($_GET['uri']) ? '/' . $_GET['uri'] : '/';
foreach ($this->_uri as $key => $value)
{
if (preg_match("#^$value$#", $uriGetParam))
{
$usemethod = $this->_method[$key];
new $usemethod();
}
}
}
}
Does anyone have any suggestions in what I can do with what I have? or will it require a complete rewrite of the routing?
Regards
UPDATED
I have left the original query in as well as this one. For anyone landing on this page I have now been able to obtain data from the database and use it to generate a route in my routing controller dynamically. This is how I did it.
my index.php file now looks like this:
<?php
header("Cache-Control: no-cache");
include 'System/Config/route.php';
include 'System/Config/settings.php';
connect();
$route = new Route();
include 'System/Config/routeURL.php';
$q="SELECT `itemID`,`SEOFriendlyURL` FROM `Products`";
$r=mysql_query($q);
$numrows = mysql_num_rows($r);
if($numrows==0)
{
// Does nothing as the database is empty - Not really needed but good just in case
}
// Dynamic Routing Elements
while($row = mysql_fetch_array($r))
{
$route->add("/results" . $row['SEOFriendlyURL'] ."", 'productURLS');
}
//Static Routing Elements
$route->add('/', 'Home');
$route->add('/results', 'Results');
$route->add('/special', 'Special');
$route->gogo();
?>
This has worked perfectly, When ever one of these URLS is called it diverts to the right page. The only thing I'm having issues with now is passing the relevant ID's via $_post
This is what I ended up with but its not working.
class productURLS
{
function clubs($ItemID)
{
$q="SELECT `itemID`,`SEOFriendlyURL` FROM `products`";
$r=mysql_query($q);
$numrows = mysql_num_rows($r);
if($numrows==0)
{
$ItemID = '0';
}
while($row = mysql_fetch_array($r))
{
$host = $_SERVER['REQUEST_URI'];
$ClubID = '0';
if($host == "/newtest/results" . $row['SEOFriendlyURL'] ."") {
$ClubID = "'" . $row['itemID'] ."'";
} else {
$itemID = '0';
}
}
$_POST['ShowClubDetails'] = $itemID;
}
public function __construct()
{
productURLS::clubs($itemID);
include 'pages/productdetails.php';
}
}
However this doesn't work. Because the query etc. is in the index page is it really needed again here? and is it better to get the query to store the ID in a variable and use that in the function instead?
Regards
I have managed to get this fully working. Here is what I did. May be of some use to someone else.
Index.php
include 'System/Config/routeURL.php';
$q="SELECT `ItemID`,`SEOFriendlyURL` FROM `Products`";
$r=mysql_query($q);
$numrows = mysql_num_rows($r);
if($numrows==0)
{
echo "There's nothing here!";
}
// Add's all SEOFriendly URL's in table into route file (Dynamic)
while($row = mysql_fetch_array($r))
{
$route->add("/results" . $row['SEOFriendlyURL'] ."", 'ProductURLS');
}
routeURL.php
class ProductURLS
{
public function __construct()
{
$host = $_SERVER['REQUEST_URI'];
$host = ltrim ($host, '/results');
$host = "/$host";
$q="SELECT `ItemID`,`SEOFriendlyURL` FROM `Products` WHERE `SEOFriendlyURL` = '$host'";
$r=mysql_query($q);
if($r) {
$row = mysql_fetch_assoc($r);
$ItemID = $row['ItemID'];
} else {
$ItemID = '0';
}
$_POST['ShowClubDetails'] = $ItemID;
//echo "Whole query: $ItemID"; // This is to make sure the ProductID is being passed.
include 'pages/ProductDetails.php';
}
}
How I cant load a 'page' view within my template. My page view is "foo_bar" and the view file is "views-view-unformatted--foo-bar--page.tpl.php" then I use the next code but it did't load the view.
$block = block_load('views', 'foo_bar');
$output = drupal_render(_block_get_renderable_array(_block_render_blocks(array($block))));
echo $output;
There are 2 functions to load a view;
$view = views_get_view('view_name');
// ensure view exists
if (!$view)
return;
$view->set_display('view_display');
$view->set_arguments(array($tid));
//$view->is_cacheable = FALSE; //default
$view->pre_execute();
$view->execute();
$result = $view->render();
or a simpler:
$result = views_embed_view($name, $display_id = 'default');
I am trying to list a few games, each, on individual pages. While a game page is opened into a new window the head title of page (< title>) is set to games page header (< h1> My Game). Also to list all game types I am using quick tabs.
From 12 types of games only at 2 of them the title is settled correctly and my problem is that I don't know from where it comes. I have tried to var_dump() all the headers and all of them are returning the same thing "Game" not the title/heading from db.
Where should I look or what would be the next step ?
$metaTitle = $page['content']['metatags']['global']['title']['#attached']['metatag_set_preprocess_variable'][0][2];
$metaTitle = str_replace(' | SuperCasino.com', '', $metaTitle);
Where should I look or what would be the next step ?
Here is my preprocess page code
function desktop_preprocess_page(&$vars, $hook) {
if (isset($vars['node_title'])) {
$vars['title'] = $vars['node_title'];
}
// Adding a class to #page in wireframe mode
if (theme_get_setting('wireframe_mode')) {
$vars['classes_array'][] = 'wireframe-mode';
}
// Adding classes wether #navigation is here or not
if (!empty($vars['main_menu']) or !empty($vars['sub_menu'])) {
$vars['classes_array'][] = 'with-navigation';
}
if (!empty($vars['secondary_menu'])) {
$vars['classes_array'][] = 'with-subnav';
}
// Page template suggestions based off of content types
if (isset($vars['theme_hook_suggestions']['node'])) {
$vars['theme_hook_suggestions'][] = 'page__type__'. $vars['node']->type;
$vars['theme_hook_suggestions'][] = "page__node__" . $vars['node']->nid;
}
// Add first/last classes to node listings about to be rendered.
if (isset($vars['page']['content']['system_main']['nodes'])) {
// All nids about to be loaded (without the #sorted attribute).
$nids = element_children($vars['page']['content']['system_main']['nodes']);
// Only add first/last classes if there is more than 1 node being rendered.
if (count($nids) > 1) {
$first_nid = reset($nids);
$last_nid = end($nids);
$first_node = $vars['page']['content']['system_main']['nodes'][$first_nid]['#node'];
$first_node->classes_array = array('first');
$last_node = $vars['page']['content']['system_main']['nodes'][$last_nid]['#node'];
$last_node->classes_array = array('last');
}
}
//var_dump($vars['theme_hook_suggestions']);die();
// Page template suggestions based off URL alias
if (module_exists('path')) {
//$alias = drupal_get_path_alias(str_replace('/edit','',$_GET['q']));
$alias = request_path();
if ($alias != $_GET['q']) {
//echo'here';die;
$template_filename = 'page';
foreach (explode('/', $alias) as $path_part) {
$template_filename = $template_filename . '__' . str_replace('-','_',$path_part);
$vars['theme_hook_suggestions'][] = $template_filename;
//var_dump($template_filename);
}
}
}
You can use drupal_set_title(YOUR_TITLE) for the different pages.
drupal_set_title($title = NULL, $output = CHECK_PLAIN)
https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal_set_title/7
From the theme level, you can use this code in your template.php:
function MYTHEMENAME_preprocess_page(&$vars, $hook) {
$vars['title'] = $custom_title';
$vars['head_title'] = $custom_title;
}
For Drupal 7 its is :
$vars['site_name']
In my codeigniter app i have an article module, which has three categories,
primary category
secondary category
tertiary category
list of articles
Now the first page shows an accordion with the heirarchy above except the list of articles, the user can click on expand or click on a category name directly.
So if a user clicks on primary category name all the articles will be listed paginated based on codeigniter's inbuilt pagination library.
Likewise if a tertiary category is clicked articles in that alone will be listed. The problem is all the articles listing is handled by a single function and hence i have a route like this.
$route['article/(:any)/(:any)/(:any)/(:any)'] = "articles/articles/show_article/$4";
$route['article/(:any)/(:any)/(:any)'] = "articles/articles/find_type/$3";
$route['article/(:any)/(:any)'] = "articles/articles/find_type/$2";
$route['article/(:any)'] = "articles/articles/find_type/$1";
and my find_type method is
function find_type($str)
{
$rawstr = $str;
$str = deurl($str);
$ch = 1;
$id = 0;
$query = $this->db->get_where("articles_primary",array("primary_name"=>$str));
if($query->num_rows==1) {
$ch = 1;
$id = $query->row('id');
}
$query = $this->db->get_where("articles_secondary",array("secondary_name"=>$str));
if($query->num_rows==1) {
$ch = 2;
$id = $query->row('id');
}
$query = $this->db->get_where("articles_tertiary",array("tertiary_name"=>$str));
if($query->num_rows==1) {
$ch = 3;
$id = $query->row('id');
}
$query = $this->db->get_where("articles_list",array("url_title"=>$rawstr));
if($query->num_rows==1) {
$ch = 4;
}
switch ($ch)
{
case 1:
$this->show_articles_list($id,"primary",$rawstr);
break;
case 2:
$this->show_articles_list($id,"secondary",$rawstr);
break;
case 3:
$this->show_articles_list($id,"tertiary",$rawstr);
break;
case 4:
$this->show_article($rawstr);
break;
}
}
and finally my list articles is
function show_articles_list($id,$tbl,$rawstr)
{
$query = $this->db->get_where("articles_list",array($tbl."_id"=>$id));
$this->load->library('pagination');
$config['base_url'] = current_url();
$config['total_rows'] = $query->num_rows;
$config['per_page'] = 9;
$this->pagination->initialize($config);
$page = $this->uri->segment(3);
if($page=="") { $page = 0; }
$this->db->limit(9,$page);
$data["query"] = $this->db->get_where("articles_list",array($tbl."_id"=>$id));
$this->template->write_view('maincontent', 'articles/articles_list',$data);
//$this->template->write_view('subcontent', 'articles/related_articles',$data);
$this->template->write("title","Laws",true);
$this->template->write_view('rightcontent','general/include/query_document_tab');
$this->template->render();
}
as you can see the routes are based on uri segments and hence the pagination is not working. Is there anyway i can tweak the pagination to work with the current setup i have?
How about adding another parameter to the functions and changing the routes file accordingly:
function find_type($str, $page=0){
...
$this->show_articles_list($id,"primary",$rawstr, $page);
etc...
...
}
function show_articles_list($id,$tbl,$rawstr,$page)...
Routes:
$route['article/(:any)/(:any)/(:any)/(:any)'] = "articles/articles/show_article/$4/4";
$route['article/(:any)/(:any)/(:any)'] = "articles/articles/find_type/$3/3";
$route['article/(:any)/(:any)'] = "articles/articles/find_type/$2/2";
$route['article/(:any)'] = "articles/articles/find_type/$1/1";
You'd use that parameter to denote the uri segment for pagination.
OR
You can just use $this->uri->total_segments().
I have my homepage http://www.faberunashop.com set up as a directory. When you click on the post image, it takes you over to the artists site. Here is the code that I used to make this happen by adding it to the functions.php:
function print_post_title() {
global $post;
$thePostID = $post->ID;
$post_id = get_post($thePostID);
$title = $post_id->post_title;
$perm = get_permalink($post_id);
$post_keys = array(); $post_val = array();
$post_keys = get_post_custom_keys($thePostID);
if (!empty($post_keys)) {
foreach ($post_keys as $pkey) {
if ($pkey=='url1' || $pkey=='title_url' || $pkey=='url_title') {
$post_val = get_post_custom_values($pkey);
}
}
if (empty($post_val)) {
$link = $perm;
} else {
$link = $post_val[0];
}
} else {
$link = $perm;
}
echo '<h2>'.$title.'</h2>';
}
Now I want to do the same to my search and archive page. What do I adjust to make them behave the same?
I suppose that you use WordPress.
In that case you can change the layout and the behavior of your search results by creating a file with name search.php into your theme for your search results, and another file for archives that called archives.php.
For more information about Template Hierarchy for WordPress you can find here http://codex.wordpress.org/Template_Hierarchy