Cakephp : Check if view element exists - view

Is there a way to check if an element exists for a view?
I want to load a different element according to a category it belongs to but not all categories have an element for it...

As of CakePHP version 2.3 you can use the View's elementExists method:
if($this->elementExists($name)) { ... }
In older versions of 2.x you can do:
if($this->_getElementFilename($name)) { ... }
But sadly in version 1.3 it looks like the only way is to know the full path and do something like:
if(file_exists($path . 'elements' . DS . $name . $ext)) { ... }
That is what they do in the 1.3 source code, but there is some complexity around getting $path from various plugins and checking each of those paths. (See link below.)
Sources:
http://api.cakephp.org/2.3/class-View.html#_elementExists
http://api.cakephp.org/2.0/source-class-View.html#722
http://api.cakephp.org/1.3/source-class-View.html#380

set element name in controller:
$default_element = 'my_element';
$element = 'my_cat_element';
if ($this->theme) {
$element_path = APP . 'views' . DS . 'themed' . DS . $this->theme . 'elements' . DS . $element . DS . $this-ext;
} else {
$element_path = APP . 'views' . DS . 'elements' . DS . $element . $this-ext;
}
if (!file_exists($element_path)) {
$element = $default_element;
}

You can always load an element specific to a category 'on demand' by telling it so from the controller. For example:
Within Controller Action:
$this->set('elementPath', "directory_name/$categoryName");
Within the View (this can also be tried exactly within a Layout):
<?php
if (!empty($elementPath)) { // you can also set a default $elementPath somewhere else, just in case
echo $this->element($elementPath);
}
?>
In fact, there is even other ways to achieve this. If the element is going to be loaded within a layout, then the set() method shown above can be specified from the view itself. Or, it can even be fetched from url parameters, like:
Within the View or Layout:
<?php
$elementPath = $this->params['url']['category']; // note that the param array can vary according how you set the url; see http://book.cakephp.org/#!/view/963/The-Parameters-Attribute-params
echo $this->element($elementPath);
?>
Of course, you will always have to specify, but the same would go for checking if the file exists.

Related

Laravel 5.2: Trying to use ID from database to display image with corresponding name?

For each entry in the database, there is a corresponding image whose file name is the same as the unique ID of that database entry, eg an entry with ID '4' has the header image title '4.png'. I want to display the relevant image to the entry currently displayed, but I can't quite get the code below to work:
$img = asset('images/header/' . $img_id . '.png');
I've verified that $img_id works, and the images are displayed when if I just use the direct path to them - ie 'images/header/4.png'.
Your code snippet seems to be ok. You should be using it in the view like:
<img src="<?= asset('images/header/' . $img_id . '.png') ?>">
Ideally you could opt for an accessor to deal with this. In your model, add this:
public function getImgAttribute()
{
return '<img src="'. asset('images/header/' . $this->attributes['id'] . '.png') .'">';
}
Now you can use it in your views like $model->img.

Display Joomla component within a module

I'm trying to display a Joomla 2.5 component in a module.
In my module entrypoint I have:
JLoader::import('joomla.application.component.model');
JLoader::import( 'quizzes', JPATH_SITE . '/components/com_questions/models' );
JLoader::import('joomla.application.component.controller');
if (!class_exists('QuestionsControllerQuizzes')) {
require_once (JPATH_SITE . DS . 'components' . DS . 'com_questions/controllers' . DS . 'quizzes.php');
}
$quiz_controller = new QuestionsControllerQuizzes(false, $params->get('poll'));
$quiz_controller->execute( JRequest::getVar('task','load') );
I tried to debug it and it seems that can't load the correct view. Seems to looking for a generic com_content in $this->basePath.
The strange thing is that if I load the module in a page where the component is loaded, it display correctly.
Any idea how to succesfully display the component output in a module?
Try this: How to display Joomla component in a module
and remember your controller should include a function for the task!

How do I stop Joomla from including jQuery?

I've recently upgraded from Joomla 3.2.1 to Joomla 3.2.2.
In Joomla 3.2.1, I manually unset jQuery from being included:
$doc = JFactory::getDocument();
$dontInclude = array(
'/media/jui/js/jquery.js',
'/media/jui/js/jquery.min.js',
'/media/jui/js/jquery-noconflict.js',
'/media/jui/js/jquery-migrate.js',
'/media/jui/js/jquery-migrate.min.js',
'/media/jui/js/bootstrap.js',
'/media/system/js/core-uncompressed.js',
'/media/system/js/tabs-state.js',
'/media/system/js/core.js',
'/media/system/js/mootools-core.js',
'/media/system/js/mootools-core-uncompressed.js',
);
foreach($doc->_scripts as $key => $script){
if(in_array($key, $dontInclude)){
unset($doc->_scripts[$key]);
}
}
But this isn't working in Joomla 3.2.2. Is there a way to not include Joomla's jQuery in 3.2.2?
Another variation which works well for me with Joomla 3.4 is to edit the template > index.php file with something like:
$doc = JFactory::getDocument();
$headData = $doc->getHeadData();
$scripts = $headData['scripts'];
//scripts to remove, customise as required
unset($scripts[JUri::root(true) . '/media/system/js/mootools-core.js']);
unset($scripts[JUri::root(true) . '/media/system/js/mootools-more.js']);
unset($scripts[JUri::root(true) . '/media/system/js/core.js']);
unset($scripts[JUri::root(true) . '/media/system/js/modal.js']);
unset($scripts[JUri::root(true) . '/media/system/js/caption.js']);
unset($scripts[JUri::root(true) . '/media/jui/js/jquery.min.js']);
unset($scripts[JUri::root(true) . '/media/jui/js/jquery-noconflict.js']);
unset($scripts[JUri::root(true) . '/media/jui/js/bootstrap.min.js']);
unset($scripts[JUri::root(true) . '/media/jui/js/jquery-migrate.min.js']);
$headData['scripts'] = $scripts;
$doc->setHeadData($headData);
You need to add a prefix of JUri::root(true) before each of those file names - relative paths will not work
I've added:
$doNotInclude = array(
'jquery',
'bootstrap',
'behavior',
);
if(in_array($file, $doNotInclude)){
return;
}
immediately after:
list($key, $prefix, $file, $func) = static::extract($key);
in libraries/cms/html/html.php, in the "_" function.
I don't like it since its a modification to the Joomla core but it works. I'm still looking for a better solution.
You can also try something like this:
$removeScripts = [
'/media/jui/js/jquery.min.js',
'/media/jui/js/jquery-noconflict.js',
'/media/jui/js/jquery-migrate.min.js',
'/media/system/js/caption.js',
];
foreach ($removeScripts as $removeScript) {
unset($this->_scripts[JURI::root(true).$removeScript]);
}
The problem is with your in_array.
If you remove it by changing this:
foreach($doc->_scripts as $key => $script){
if(in_array($key, $dontInclude)){
unset($doc->_scripts[$key]);
}
}
to this:
foreach($doc->_scripts as $key => $script){
unset($doc->_scripts[$key]);
}
Then it works fine. It's pretty pointless checking if the array key exists as I gathered you haven't manually deleted any of these files yourself.
Hope this helps
Joomla 3.3.6 loads scripts in different way so $doc->_scripts will return nothing... so there is nothing to unset.
I recommend to use this plugin: https://github.com/Poznakomlus/joomla_options
It allows you to remove bootstrap, jQuery and mootools (you can choose what to disable).
Disclaimer: I'm not affiliated any way with plugin developer or plugin itself in any way.
If you are writing a custom template or a component, where you need to remove all the scripts loaded by default inside Joomla you can create a simple plugin and bind the execution to the onBeforeCompileHead event.
My implementation was as below. Its very simple. You can further play around with the search list, by being specific to file names or just plain blacklisting the parent folder.
protected $app;
public function onBeforeCompileHead() {
// Front end
if ($this->app instanceof JApplicationSite) {
$doc = JFactory::getDocument();
$search = array(
'jui/js/',
'system/js/'
);
foreach ($doc->_scripts as $key => $script) {
foreach ($search as $findme) {
if (stristr($key, $findme) !== false) {
unset($doc->_scripts[$key]);
}
}
}
}
}
This worked for me in joomla 3.9
<?php
defined('_JEXEC') or die('Restricted access');
$unset_scripts = [
'/media/jui/js/jquery.min.js',
'/media/jui/js/jquery-noconflict.js',
'/media/jui/js/jquery-migrate.min.js',
'/media/system/js/caption.js',
];
foreach ($unset_scripts as $script) {
unset($this->_scripts[JURI::root(true) . $script]);
}
if (isset($this->_script['text/javascript'])) {
$captionJsStr = '%jQuery\(window\)\.on\(\'load\',\s*function\(\)\s*{\s*new\s*JCaption\(\'img.caption\'\);\s*}\);\s*%';
$this->_script['text/javascript'] = preg_replace($captionJsStr, '', $this->_script['text/javascript']);
if (empty($this->_script['text/javascript'])) {
unset($this->_script['text/javascript']);
}
}
$this->_scripts = array();
?>
<!DOCTYPE html>

How to resize the categories images in Magento?

How to resize the categories images in Magento? I used the following code to resize product images, but I'm not able to use it for showing categories images:
$this->helper('catalog/image')->init($_product, 'small_image')->resize(170);
If I am not mistaken, it should be :
init($_product, 'small_image')->resize(100,100);
// single parameter work with 'image'
init($_product, 'image')->resize(100);
// How about this
$this->helper('catalog/image')->init($this->getProduct(), 'thumbnail', $image->getFile())->resize(100,100);
Here is the new code. If you tell me before which extension used, we were solve quickly.
If I am not mistaken, you used Template Monster Catalog Image Extension. So, there is a function inside of the extension, like below.
// app/design/frontend/default/default/template/easycatalogimg/homepage.phtml
<?php echo Mage::helper('easycatalogimg/image')->resize($imageUrl, $width , $height) ?>
<?php
$_file_name = $cat->getThumbnail(); // Here $cat is category data array
$_media_dir = Mage::getBaseDir('media') . DS . 'catalog' . DS . 'category' . DS;
$cache_dir = $_media_dir . 'resize' . DS; // Here i create a resize folder. for upload new category image
if (file_exists($cache_dir . $_file_name)) {
$catImg =Mage::getBaseUrl('media') . 'catalog' . DS . 'category' . DS . 'resize' . DS . $_file_name;
} elseif (file_exists($_media_dir . $_file_name)) {
if (!is_dir($cache_dir)) {
mkdir($cache_dir);
}
$_image = new Varien_Image($_media_dir . $_file_name);
$_image->constrainOnly(true);
$_image->keepAspectRatio(false);
$_image->keepFrame(false);
$_image->keepTransparency(true);
$_image->resize(224, 174); // change image height, width
$_image->save($cache_dir . $_file_name);
$catImg = Mage::getBaseUrl('media') . 'catalog' . DS . 'category' . DS . 'resize' . DS . $_file_name;
}
echo $catImg ; // display resize category thumbnail imagename
?>
" />
For more clarification see here
If you want to resize category images, here is a free module based on core image resize. As I was struggling myself so, ended up creating this extension to resize category images with ease same as product image resizing.
I realize that I'm late to the party but I had a chance to look at this recently and using init() to resize product images is perfectly fine as described in the question but you shouldn't have to use the same function to resize a single image, through a function where the image itself (third parameter) is an optional value.
Here's what I've done to resize the image, this is for any image:
$model = Mage::getModel('catalog/product_image');
$model->setBaseFile('test.png');
$model->setWidth(100);
$model->resize();
$model->saveFile();
echo $model->getUrl();
// generates the following url: http://example.com/media/catalog/product/cache/1//9df78eab33525d08d6e5fb8d27136e95/test.png
If you don't want to save your image in the media directory then you can use Varien_Image object to achieve that:
$varienImage = new Varien_Image('test.png');
$varienImage->resize(100);
$varienImage->save('var', 'test2.png');
save() takes the first parameter as the directory where you'd like the new file to be saved and second parameters is the name of the new file.
The steps are similar as to what the init function does aside from dealing with a bunch of logic with the product itself.
If you need to resize the category image as it keeps shrinking to 475px wide, you can do so by deleting the 'width="475"' from the following template:
app/design/frontend/default/default/template/catalog/category/view.phtml
You might also need to turn off or clear the cache in the backend at: System --> Cache Management --> Image Cache --> Clear.
From: http://www.pridedesign.ie/content/magento-resize-category-image

WordPress plugin: finding the <!--more--> in the_content

I'm writing a WordPress plugin that filters the_content, and I'd like to make use of the <!--more--> tag, but it appears that it has been stripped out by the time it reaches me. This appears to be not a filter, but a function of the way WordPress works.
I could of course resort to reloading the already-loaded content from the database, but that sounds like it might cause other troubles. Is there any good way for me to get the raw content without the <!--more--> removed?
Chances are, by the time your plugin runs, <!--more--> has been converted to <span id="more-1"></span>
This is what I use in my plugin, which injects some markup immediately after the <!--more--> tag:
add_filter('the_content', 'inject_content_filter', 999);
function inject_content_filter($content) {
$myMarkup = "my markup here<br>";
$content = preg_replace('/<span id\=\"(more\-\d+)"><\/span>/', '<span id="\1"></span>'."\n\n". $myMarkup ."\n\n", $content);
return $content;
}
You can use the follow code:
The !is_single() will avoid display the more link in the View Post page.
add_filter('the_content', 'filter_post_content');
function filter_post_content($content,$post_id='') {
if ($post_id=='') {
global $post;
$post_id = $post->ID;
}
// Check for the "more" tags
$more_pos = strpos($filtered_content, '<!--more-->');
if ($more_pos && !is_single()) {
$filtered_content = substr($filtered_content, 0, $more_pos);
$replace_by = '<a href="' . get_permalink($post_id) . '#more-' . $post_id
. '" class="more-link">Read More <span class="meta-nav">→</span></a>';
$filtered_content = $filtered_content . $replace_by;
}
return $filtered_content;
}
Based on Frank Farmer's answer I solved to add thumbnail photo after the generated more tag (<span id="more-...) in single.php file with this:
// change more tag to post's thumbnail in single.php
add_filter('the_content', function($content)
{
if(has_post_thumbnail())
{
$post_thumbnail = get_the_post_thumbnail(get_the_ID(), 'thumbnail', array('class'=>'img img-responsive img-thumbnail', 'style'=>'margin-top:5px;'));
$content = preg_replace('/<span id\=\"(more\-\d+)"><\/span>/', '<span id="\1"></span>'.$post_thumbnail, $content);
}
return $content;
}, 999);

Resources