Have prestashop and need global replace some html attributes from all pages (before displaying).
I use extending:
protected function smartyOutputContent($content)
Some replacing code.
All run good. (But this is not correct rewrite)
But have question, if someone know about some right way how to do it.?
In prestashop, or if some way how correct rewrite some of smarty and extend it...
(ideally if can use it in prestashop module)
Thanks for all ideas.
Change
In my case, need replace/rename itemprop, itemscope, itemtype. (in module change to json structure)
And want to do ideally, when modul is installed.
But user can had custom theme... So override template is not right way.
I do now:
modules/modul_name/override/classes/controller/Controller.php
With content:
protected function smartyOutputContent($content)
{
$this->context->cookie->write();
$html = '';
$js_tag = 'js_def';
$this->context->smarty->assign($js_tag, $js_tag);
if (is_array($content)) {
foreach ($content as $tpl) {
$html .= $this->context->smarty->fetch($tpl);
}
} else {
$html = $this->context->smarty->fetch($content);
}
$html = trim($html);
if (in_array($this->controller_type, array('front', 'modulefront')) && !empty($html) && $this->getLayout()) {
$live_edit_content = '';
if (!$this->useMobileTheme() && $this->checkLiveEditAccess()) {
$live_edit_content = $this->getLiveEditFooter();
}
$dom_available = extension_loaded('dom') ? true : false;
$defer = (bool)Configuration::get('PS_JS_DEFER');
if ($defer && $dom_available) {
$html = Media::deferInlineScripts($html);
}
$html = trim(str_replace(array('</body>', '</html>'), '', $html))."\n";
/* Remove snipped data from attributes html elements */
$html = str_replace(array('itemprop', 'itemscope', 'itemtype'), 'ip', $html);
$this->context->smarty->assign(array(
$js_tag => Media::getJsDef(),
'js_files' => $defer ? array_unique($this->js_files) : array(),
'js_inline' => ($defer && $dom_available) ? Media::getInlineScript() : array()
));
$javascript = $this->context->smarty->fetch(_PS_ALL_THEMES_DIR_.'javascript.tpl');
if ($defer && (!isset($this->ajax) || ! $this->ajax)) {
echo $html.$javascript;
} else {
echo preg_replace('/(?<!\$)'.$js_tag.'/', $javascript, $html);
}
echo $live_edit_content.((!isset($this->ajax) || ! $this->ajax) ? '</body></html>' : '');
} else {
echo $html;
}
}
All function correct.
Thanks for comment sadlyblue
Related
Site based on Joomla. I have many pages where h1 header is mentioned as product detail and displayed based on product details through PHP. There are 2 files: default.php and view.html.php.
default.php :
<h1>Used <?php echo $this->CatName; ?> <?php echo $this->prodDet->prod_name;?> Toy for Sale </h1>
This correctly display the h1 tag. I want to generate meta title of the page and use this h1 output as generated in view.html.php. This line defines the title of the page :
$this->document->setTitle($title);
And this line defines header h1 :
"{$this->item->heading}";
Complete code :
protected function _prepareDocument()
{
$app = JFactory::getApplication();
$menus = $app->getMenu();
$title = null;
// Because the application sets a default page title,
// We need to get it from the menu item itself
$menu = $menus->getActive();
if ($menu)
{
$this->params->def('page_heading', $this->params->get('page_title', $menu->title));
}
else
{
$this->params->def('page_heading', JText::_('COM_USEDCAR_DEFAULT_PAGE_TITLE'));
}
$title = $this->params->get('page_title', '');
if (empty($title))
{
$title = $app->get('sitename');
}
elseif ($app->get('sitename_pagetitles', 0) == 1)
{
$title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title);
}
elseif ($app->get('sitename_pagetitles', 0) == 2)
{
$title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename'));
}
$title = "{$this->item->heading}";
$this->document->setTitle($title);
if ($this->params->get('menu-meta_description'))
{
$this->document->setDescription($this->params->get('menu-meta_description'));
}
if ($this->params->get('menu-meta_keywords'))
{
$this->document->setMetadata('keywords', $this->params->get('menu-meta_keywords'));
}
if ($this->params->get('robots'))
{
$this->document->setMetadata('robots', $this->params->get('robots'));
}
}
Output in title tag is heading. How to put this h1 tag output instead of $title?
Here's what the title portion of your code does:
// getting title from params
$title = $this->params->get('page_title', '');
// trying to get it right
if (empty($title))
{
$title = $app->get('sitename');
}
elseif ($app->get('sitename_pagetitles', 0) == 1)
{
$title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title);
}
elseif ($app->get('sitename_pagetitles', 0) == 2)
{
$title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename'));
}
// overwrite everything above with some value, making above code useless
$title = "{$this->item->heading}";
$this->document->setTitle($title);
I might be wrong but if I recall correctly, if a value doesn't exist it will return the variable name when cast into a string. Here "heading" might be empty.
You might want to change your code to something like this:
[...]
if(!title){
if(property_exists($this, 'item') && property_exists($this->item, 'heading') && $this->item->heading){
$title = $this->item->heading;
} else {
$title = sprintf('Used %s %s Toy for Sale' , $this->CatName, $this->prodDet->prod_name);
}
}
$this->document->setTitle($title);
You might as well like to save the title to session and reuse it everywhere:
[...]
$this->document->setTitle($title);
// save title to session
$_SESSION['page_title'] = $title;
and update the previous loop:
// getting title from params
$title = (isset($_SESSION['page_title']) && $_SESSION['page_title'])? $_SESSION['page_title'] : $this->params->get('page_title', '');
if (empty($title)){
[...]
Full code would be something like that:
[...]
session_id() || session_start();
$title = (isset($_SESSION['page_title']) && $_SESSION['page_title'])? $_SESSION['page_title'] : $this->params->get('page_title', '');
if(!title){
if(property_exists($this, 'item') && property_exists($this->item, 'heading') && $this->item->heading){
$title = $this->item->heading;
} else {
$title = sprintf('Used %s %s Toy for Sale' , $this->CatName, $this->prodDet->prod_name);
}
}
if (empty($title))
{
$title = $app->get('sitename');
}
elseif ($app->get('sitename_pagetitles', 0) == 1)
{
$title = JText::sprintf('JPAGETITLE', $app->get('sitename'), $title);
}
elseif ($app->get('sitename_pagetitles', 0) == 2)
{
$title = JText::sprintf('JPAGETITLE', $title, $app->get('sitename'));
}
$_SESSION['page_title'] = $title;
$this->document->setTitle($title);
[...]
You might as well just ditch everything and go like that if you'd like:
[...]
$title = $this->params->get('page_title', '');
if(!title){
if(property_exists($this, 'item') && property_exists($this->item, 'heading') && $this->item->heading) {
$title = $this->item->heading;
} elseif(
property_exists($this, 'CatName') &&
property_exists($this, 'prodDet') &&
property_exists($$this->prodDet, 'prod_name') &&
$this->CatName &&
$this->prodDet->prod_name
){
$title = sprintf('Used %s %s Toy for Sale' , $this->CatName, $this->prodDet->prod_name);
} else {
$title = $app->get('sitename');
}
}
$this->document->setTitle($title);
[...]
Code is untested but it should put you on the right track :)
Why don't you just send your h1 content to your php-document as GET parameter and then just output the it using echo inside the title tag? Unless you avoid dinamic echoing, this could be a fine solution for outputting text as title.
I would abstract away the logic of constructing the title/header to some function and then use this function to construct the title in both places.
function constructTitle($catName, $prodName) {
return "Used {$catName} {$prodName} Toy for Sale";
}
...
[in default.php]
<h1><?php echo constructTitle($this->CatName, $this->prodDet->prod_name); ?></h1>
[in view.html.php]
$this->document->setTitle(constructTitle(..., ...));
This allows you to have a single point to format your title while using it in several places.
The function needs to, obviously, be place in such position so that it can be accessed in both places and you need to have some way to get category name and product name in view.html.php. Im not familiar enough with joomla to know these things.
Edit:
To clarify, there is no real way to "extract" the title from the default.php as it is dynamic. You would need to process the php file then maybe you could do some regex magic, but this is in no way the proper solution to the problem.
you can just send your h1 content to your php-document as GET parameter and then output the it using echo in the title tag? Unless you avoid dynamic echoing,it would work.
I using prestashop 1.6 and I have some variable in my index.tpl like as $aslist that I Don't know where this variable is defined or assigned!
I need to find this variable and do some change over that.
anybody know how can I find a solution that show where smarty variables assigned ?
I need to a address file like as:
$aslist assigned in .\www\controllers\front\CmsController.php - (line 58 )
You can add this function to config/config.inc.php
function log_smarty_assign($var_name)
{
$smarty_var_filter = 'aslist';
if ($var_name == $smarty_var_filter)
{
$log = '';
$trace = debug_backtrace(false);
if (isset($trace[1]))
{
$log .= 'Variable '.$var_name.' assigned in ';
$log .= $trace[1]['file'].' #'.$trace[1]['line'];
echo "<pre>$log</pre>";
}
}
}
Edit: $trace[1] should be used instead of $trace[2]
And then search for the smarty assign method and modify it to something like this:
I found it in /tools/smarty/sysplugins/smarty_internal_data.php
public function assign($tpl_var, $value = null, $nocache = false)
{
if (is_array($tpl_var)) {
foreach ($tpl_var as $_key => $_val) {
if ($_key != '') {
$this->tpl_vars[$_key] = new Smarty_variable($_val, $nocache);
//log the assignment
log_smarty_assign($_key);
}
}
} else {
if ($tpl_var != '') {
$this->tpl_vars[$tpl_var] = new Smarty_variable($value, $nocache);
//log the assignment
log_smarty_assign($tpl_var);
}
}
return $this;
}
Output example:
Variable product assigned in ...\classes\controller\Controller.php #180
I am trying to extend a Pico navigation plugin to exclude items from the navigation tree where the page's utilizes Twig template engine header tags.
My question is how do I get specific header tags from the .md files in the below PHP function and filter them to be excluded in the navigation tree?
The plugin currently implements the ability to omit items (pages and folders) from the tree with the following settings in a config.php file:
// Exclude pages and/or folders from navigation header
$config['navigation']['hide_page'] = array('a Title', 'another Title');
$config['navigation']['hide_folder'] = array('a folder', 'another folder');
The current function in the plugs' file uses the above config.php as follows:
private function at_exclude($page) {
$exclude = $this->settings['navigation'];
$url = substr($page['url'], strlen($this->settings['base_url'])+1);
$url = (substr($url, -1) == '/') ? $url : $url.'/';
foreach ($exclude['hide_page'] as $p) {
$p = (substr($p, -1*strlen('index')) == 'index') ? substr($p, 0, -1*strlen('index')) : $p;
$p = (substr($p, -1) == '/') ? $p : $p.'/';
if ($url == $p) {
return true;
}
}
foreach ($exclude['hide_folder'] as $f) {
$f = (substr($f, -1) == '/') ? $f : $f.'/';
$is_index = ($f == '' || $f == '/') ? true : false;
if (substr($url, 0, strlen($f)) == $f || $is_index) {
return true;
}
}
return false;
}
I need to add the ability of omitting items (or pages) from the tree using the Twig header tags 'Type' and 'Status' like so in the .md files:
/*
Title: Post01 In Cat01
Description: This post01 in cat01
Date: 2013-10-28
Category:
Type: post // Options: page, post, event, hidden
Status: draft // Options: published, draft, review
Author: Me
Template:
*/
...
The MarkDown content . . .
So if a user wants to remove items tagged with "post" in the 'type' tag and/or "draft" from the 'draft' tag (see header above), they would then add the linked tags in the array below that I added into the config.php:
// Exclude taged items:
$config['navigation']['hide_status'] = array('draft', 'maybe some other status tag');
$config['navigation']['hide_type'] = array('post', 'etc');
I also added the following to the bottom of the at_exclude() function:
private function at_exclude($page) {
. . .
foreach ($exclude['hide_staus'] as $s) {
$s = $headers['status'];
if ($s == 'draft' || 'review') {
return true;
}
}
foreach ($exclude['hide_type'] as $t) {
$t = $headers['type'];
if ($t == 'post' || 'hidden') {
return true;
}
return true;
}
. . .
This is obviously not working for me (because my PHP knowledge is limited). Any help with what I am missing, doing wrong or how I can add this functionality will be greatly appreciated.
I dived into the (not so beautiful) Pico code and those are my findings.
First of all, Pico doesn't read every custom field you add to the content header.
Instead, it has an internal array of fields to parse. Luckily, an hook called before_read_file_meta is provided to modify the array.
In at_navigation.php we'll add:
/**
* Hook to add custom file meta to the array of fields that Pico will read
*/
public function before_read_file_meta(&$headers)
{
$headers['status'] = 'Status';
$headers['type'] = 'Type';
}
This will result in Pico reading the headers, but it won't add the fields to the page data yet. We need another hook, get_page_data. In the same file:
/**
* Hook to add the custom fields to the page data
*/
public function get_page_data(&$data, $page_meta)
{
$data['status'] = isset($page_meta['status']) ? $page_meta['status'] : '';
$data['type'] = isset($page_meta['type']) ? $page_meta['type'] : '';
}
Now, in the at_exclude function, we can add the new logic.
(Instead of cycling, We configure an array of status and types we want to exclude, and we'll check if there is a match with the current page status/type)
private function at_exclude($page)
{
[...]
if(in_array($page['status'], $exclude['status']))
{
return true;
}
if(in_array($page['type'], $exclude['type']))
{
return true;
};
return false;
}
Now let's customize our config.php (I standardized the configuration with the plugin standards):
$config['at_navigation']['exclude']['status'] = array('draft', 'review');
$config['at_navigation']['exclude']['type'] = array('post');
All done!
But if you are just starting out, I'd advise you to use a more mature and recent flat file cms. Unless you are stuck with PHP5.3
I decided to simplify the function to omit it from the config.php since it really isn't needed to be set by the end-user. By doing so, the at_exclude() function is much simpler and quicker on the back-end by omitting all the checks via other files:
at_exclude {
. . .
$pt = $page['type'];
$ps = $page['status'];
$home = ($pt == "home");
$post = ($pt == "post");
$event = ($pt == "event");
$hide = ($pt == "hide");
$draft = ($ps == "draft");
$review = ($ps == "review");
$type = $home || $post || $event || $hide;
$status = $draft || $review;
if ( $type || $status ) {
return true;
};
return false;
}
Obviously it needs some tidying up but you get the picture. Thnx
I have two code blocks that are PHP functions that do two different things. They are:
<?php
if (!function_exists('UserPhotoDefaultUrl')) {
function UserPhotoDefaultUrl($User) {
$Email = GetValue('Email', $User);
$HTTPS = GetValue('HTTPS', $_SERVER, '');
$Protocol = (strlen($HTTPS) || GetValue('SERVER_PORT', $_SERVER) == 443) ? 'https://secure.' : 'http://www.';
$Url = $Protocol.'gravatar.com/avatar.php?'
.'gravatar_id='.md5(strtolower($Email))
.'&size='.C('Garden.Thumbnail.Width', 50);
if (C('Plugins.Gravatar.UseVanillicon', FALSE))
$Url .= '&default='.urlencode(Asset('http://vanillicon.com/'.md5($Email).'.png'));
else
$Url .= '&default='.urlencode(Asset(C('Plugins.Gravatar.DefaultAvatar', 'plugins/Gravatar/default.gif'), TRUE));
return $Url;
}
}
and...
<?php
class GravatarPlugin extends Gdn_Plugin {
public function ProfileController_AfterAddSideMenu_Handler($Sender, $Args) {
if (!$Sender->User->Photo) {
$Email = GetValue('Email', $Sender->User);
$Hash = md5($Email);
$Sender->User->Photo = 'http://w'.substr($Hash, 0, 1).'.vanillicon.com/'.$Hash.'_200.png';
}
}
}
The first shows the Gravatar image for User avatar in post content of my script (Vanilla forums), and the second one shows the Vanillicons (Vanillicon is similar to Gravatar) of all the users participating in a discussion in the sidebar (under 'In This Discussion'). I hope you get the idea as to what the two code blocks do now?
Using the how-it's-done code in the first code block, I need to modify the second code block to show Gravatar icons of all users participating in a discussion instead of Vanillicons. Can someone who knows PHP help?
<?php
if (!function_exists('UserPhotoDefaultUrl')) {
function UserPhotoDefaultUrl($User) {
$Email = GetValue('Email', $User);
$HTTPS = GetValue('HTTPS', $_SERVER, '');
$Protocol = (strlen($HTTPS) || GetValue('SERVER_PORT', $_SERVER) == 443) ? 'https://secure.' : 'http://www.';
$Url = $Protocol.'gravatar.com/avatar.php?'
.'gravatar_id='.md5(strtolower($Email))
.'&size='.C('Garden.Thumbnail.Width', 50)
.'&default='.urlencode(Asset(C('Plugins.Gravatar.DefaultAvatar', 'plugins/Gravatar/default.gif'), TRUE));
return $Url;
}
}
you class:
<?php
class GravatarPlugin extends Gdn_Plugin {
public function ProfileController_AfterAddSideMenu_Handler($Sender, $Args) {
if (!$Sender->User->Photo) {
$Sender->User->Photo = UserPhotoDefaultUrl($Sender->User); // not sure about the $Sender->User part because it is not displayed
}
}
}
I have little programming experience so the jump from basic php to using classes, functions etc is a little daunting.
I'm building a little php script that works out what "theme" a user has selected via a form and from that selection, it loads some specific files. I've built a working script, but there's so much repetition in it, it's a joke.
// Add our theme names to variables
$theme1 = "theme1";
$theme2 = "theme2";
$theme3 = "theme3";
// Test to see what Theme the user chose.
// Theme 1
if ($themeChoice==$theme1)
{
// Load the theme
$homepage = file_get_contents('../themes/'.$theme1.'/index.html');
$mobile_js_main = file_get_contents('../themes/'.$theme1.'/js/main.js');
$mobile_js_jquery = file_get_contents('../themes/'.$theme1.'/js/jquery.js');
$mobile_css_easy = file_get_contents('../themes/'.$theme1.'/css/easy.css');
$mobile_images_bg = file_get_contents('../themes/'.$theme1.'/images/bg.png');
$mobile_images_footer = file_get_contents('../themes/'.$theme1.'/images/footer.png');
$mobile_images_nav = file_get_contents('../themes/'.$theme1.'/images/nav.png');
if ($AddPortfolioPage != '')
{
$portfolioPage = file_get_contents('../themes/'.$theme1.'/portfolio.html');
}
if ($AddContactPage != '')
{
$ContactPage = file_get_contents('../themes/'.$theme1.'/contact.html');
}
if ($AddBlankPage != '')
{
$blankPage = file_get_contents('../themes/'.$theme1.'/blank.html');
}
}
This is then repeated for each theme...which is obviously not an ideal method of doing this. Any help is much appreciated!
Put all of your themes into an array and loop to find the chosen one.
$themes = array( "theme1", "theme2", "theme3");
foreach( $themes as $theme)
{
if( $themeChoice == $theme)
{
$homepage = file_get_contents('../themes/'.$theme.'/index.html');
$mobile_js_main = file_get_contents('../themes/'.$theme.'/js/main.js');
$mobile_js_jquery = file_get_contents('../themes/'.$theme.'/js/jquery.js');
$mobile_css_easy = file_get_contents('../themes/'.$theme.'/css/easy.css');
$mobile_images_bg = file_get_contents('../themes/'.$theme.'/images/bg.png');
$mobile_images_footer = file_get_contents('../themes/'.$theme.'/images/footer.png');
$mobile_images_nav = file_get_contents('../themes/'.$theme.'/images/nav.png');
if ($AddPortfolioPage != '')
{
$portfolioPage = file_get_contents('../themes/'.$theme.'/portfolio.html');
}
if ($AddContactPage != '')
{
$ContactPage = file_get_contents('../themes/'.$theme.'/contact.html');
}
if ($AddBlankPage != '')
{
$blankPage = file_get_contents('../themes/'.$theme.'/blank.html');
}
break; // Break will exit the loop once the choice is found
}
}