How do I add css to be loaded last in drupal? - php

drupal_add_css('override/files/style.css');
This kind of statement can't ensure the css is loaded last,
how can I do the trick?

Use the group attribute :
drupal_add_css(drupal_get_path('theme', 'mytheme') . '/css/styles.css', array('group' => CSS_THEME);

The CSS gets added in the order drupal_add_css() is called, which depends largely on the weight of the module or theme doing the calling, stored in the system table. Drupal.org's instructions on changing module weight also work for themes.
The other factor determining the order of drupal_add_css() is simply the order in which the containing function is called in the code of Drupal. template_preprocess_page(), for example, is always called after template_preprocess_node(), simply because the node goes in the page.

For Drupal 6 use:
drupal_add_css('site.css', 'theme', '', array('weight' => 999))

if you look in the template.php theme file of the ninesixty theme you will find a solution.
The following function are called from the theme_preprocess_page hook:
function ninesixty_css_reorder($css) {
global $theme_info, $base_theme_info;
// Dig into the framework .info data.
$framework = !empty($base_theme_info) ? $base_theme_info[0]->info : $theme_info->info;
// Pull framework styles from the themes .info file and place them above all stylesheets.
if (isset($framework['stylesheets'])) {
foreach ($framework['stylesheets'] as $media => $styles_from_960) {
// Setup framework group.
if (isset($css[$media])) {
$css[$media] = array_merge(array('framework' => array()), $css[$media]);
}
else {
$css[$media]['framework'] = array();
}
foreach ($styles_from_960 as $style_from_960) {
// Force framework styles to come first.
if (strpos($style_from_960, 'framework') !== FALSE) {
$framework_shift = $style_from_960;
$remove_styles = array($style_from_960);
// Handle styles that may be overridden from sub-themes.
foreach ($css[$media]['theme'] as $style_from_var => $preprocess) {
if ($style_from_960 != $style_from_var && basename($style_from_960) == basename($style_from_var)) {
$framework_shift = $style_from_var;
$remove_styles[] = $style_from_var;
break;
}
}
$css[$media]['framework'][$framework_shift] = TRUE;
foreach ($remove_styles as $remove_style) {
unset($css[$media]['theme'][$remove_style]);
}
}
}
}
}
return $css;
}

Use the weight attribute :
drupal_add_css(drupal_get_path('theme', 'mytheme') . '/css/styles.css', array('weight' => 999));
Note : CSS added in your theme's info will always be last, so use the same function as before to change the weight of your stylesheets declared in theme's info file.

This worked for me. Adds the css after the last css on the page
$module_path = drupal_get_path('module', 'my_module');
drupal_add_css($module_path . '/css/my_module.css', array('weight' => 99999, 'group'=>CSS_THEME));

Related

WordPress - how to check if CSS file name contains ".min"?

I would like to create a dynamic check to see if my CSS file contains the minified version style.min.css instead of style.css.
I have created a development and production mode in production it generates a minified version adding a hash and the development is just regular un minified without the .min
How can I do this the cleaner way? What if I have multiple CSS files, I don't want to copy-paste my code over and over again.
<?php
function nm_enqueue_style() {
wp_enqueue_style('nm-style', get_stylesheet_uri());
$cssFilePath = glob(THEME_DIR . '/build/css/prestigexotics.min.*');
$cssFileURI = THEME_DIR_CSS . '/' . basename($cssFilePath[0]);
if (strpos($cssFileURI, 'min') == false) {
wp_enqueue_style('theme', THEME_DIR_CSS . '/prestigexotics.css', array());
} else {
wp_enqueue_style('theme', $cssFileURI);
}
}
add_action('wp_enqueue_scripts', 'nm_enqueue_style');
You can create a function that would make it for you. It would return an array with what you need.
<?php
function checkCssMin($filePath) {
$cssFilePath = glob(THEME_DIR . $filePath);
$cssFileURI = THEME_DIR_CSS . '/' . basename($cssFilePath[0]);
if (strpos($cssFileURI, 'min') == false) {
return [false, $cssFileURI];
} else {
return [true];
}
}
function nm_enqueue_style() {
wp_enqueue_style('nm-style', get_stylesheet_uri());
wp_enqueue_style('theme', checkCssMin('/build/css/prestigexotics.min.*')[0] ? checkCssMin('/build/css/prestigexotics.min.*')[1] : ('/prestigexotics.css', array()));
}
add_action('wp_enqueue_scripts', 'nm_enqueue_style');
Note: I'm not very used to PHP syntax, but I hope the logic can help you. I'm sure you can simplify it even more.
Solved the issue created a function to dynamically output the JS files.

Adding script to certain nodes and pages on drupal 7

I am trying to add a script code on all pages of my drupal except a few. Is there any conditionals I can use in html.tpl.php ? or any functions on the template.php to achieve this?
I tried the code below on template.php but no luck :(
Thanks in advance!
function THEME_preprocess_page(&$variables) {
if (isset($variables['node']->type)) {
$variables['theme_hook_suggestions'][] = 'page__' .
$variables['node']->type;
}
//this is what I am trying
if ($variables['nid'] == '77') {
drupal_add_js(drupal_get_path('theme', 'THEME') .'/scripts/path.js');
}
}
You can use hook_page_build(&$page)
function MYMODULE_page_build(&$page){
$nids = array(123, 1234); // your nids
if(($node = menu_get_object('node', 1)) && in_array($node->nid ,$nids) ){
drupal_add_js(drupal_get_path('theme', 'mythemename') .'/scripts/path.js');
}
}
Clear all cache after create this function to see result , also ensure of path script is correct ;)

Wordpress match url for custom content without post or page

Im new in wordpress.
I want to use two tables and display some content without creating pages or posts.
The matched url will be something like this:
/[category]/[image] - /nature/green-tree
My method was to check the url in index.php from theme and split the url and create a mini route system just for the gallery. But I think it is not the smartest idea.
I don't want to use gallery plugins because I'm already using one, and this is a change that I need to to.
What is the best method to do this?
I suppose you need custom rewrite rules. Here is how you can do it by yourself.
If you are using a theme then open the functions.php file and enter the following code, otherwise if you are using a plugin, place this code somewhere in your plugin, but make sure, that it is loading immediately.
function registerCustomUrl($rewrite)
{
$rewrites = $rewrite->rules;
$newRewrites = array();
$newRewrites['([^/]+)/([^/]+)/?$'] = 'index.php?gallery_category=$matches[1]&gallery_image=$matches[2]';
foreach($rewrites as $rk => $rv)
{
$newRewrites[$rk] = $rv;
}
$rewrite->rules = $newRewrites;
}
add_action('generate_rewrite_rules', 'registerCustomUrl');
function registerCustomQueryVars( $vars ) {
$vars[] = 'gallery_category';
$vars[] = 'gallery_image';
return $vars;
}
add_filter('query_vars', 'registerCustomQueryVars');
function myCustomTemplateRedirect()
{
global $wp_query;
if(
isset($wp_query->query_vars['gallery_category']) &&
!empty($wp_query->query_vars['gallery_category']) &&
isset($wp_query->query_vars['gallery_image']) &&
!empty($wp_query->query_vars['gallery_image'])
)
{
// Within your custom template file you are able to
// use any theme function like the get_header(), get_footer(), etc
require_once('path/to/your/custom/template/file.php');
exit(0);
}
}
add_action("template_redirect", 'myCustomTemplateRedirect');

How to detect if the current page is the homepage with CakePhp?

How can I detect if the user is on the homepage of my website with CakePhp?
May I use $this->webroot?
The goal is to do something only if the current page is the homepage.
Simply you can try this:
if ($this->request->here == '/') {
// some code
}
Also it is good to read this part of documentation:
You can use CakeRequest to introspect a variety of things about the
request. Beyond the detectors, you can also find out other information
from various properties and methods.
$this->request->webroot contains the webroot directory.
$this->request->base contains the base path.
$this->request->here contains the full address to the current request
$this->request->query contains the query string parameters.
You can find it by comparing the present page with webroot or base
if ($this->here == $this->webroot){ // this is home page }
OR
if ($this->here == $this->base.'/'){ // this is home page }
You can get it properly by checking against params like below:
if($this->params['controller']=='homes' && $this->params['action']=='index')
in this way you can check for any page of cakephp on view side
Assuming you are going to do something from the AppController, it's best to see if the current controller/action pair is the one you define as "homepage" (as Cake can route a user anywhere from the '/' route and you probably still want the logic to be triggered when the action is called directly with the full /controller/action URI and not just on /). In your AppController just add a check:
if ($this->name == 'Foo' && $this->action == 'bar') {
// Do your stuff here, like
echo 'Welcome home!';
}
That way it will trigger whenever the bar action is requested from the FooController. You can obviously also put this logic in the specific controller action itself (and that might make more sense since it's less overhead).
You can use $this->request->query['page'] to determine where you are,
if ( $this->request->query['page'] == '/' ){
//do something
}
Edit:
check $this->request object using echo debug($this->request), it contains many informations you can use. Here is a sample of what you get:
object(CakeRequest) {
params => array(
'plugin' => null,
'controller' => 'pages',
'action' => 'display',
'named' => array(),
'pass' => array(
(int) 0 => 'home'
)
)
data => array()
query => array()
url => false
base => ''
webroot => '/'
here => '/'
}
If your home page is home.ctp as mentionned by the cakePHP convention. In PagesController, you can change the display function to look like :
(added code starts at the comment /* Custom code start*/ )
public function display()
{
$path = func_get_args();
$count = count($path);
if (!$count) {
return $this->redirect('/');
}
$page = $subpage = null;
if (!empty($path[0])) {
$page = $path[0];
}
if (!empty($path[1])) {
$subpage = $path[1];
}
/* Custom code start*/
if("home"==$page){
// your code here
}
/* Custom code end*/
$this->set(compact('page', 'subpage'));
try {
$this->render(implode('/', $path));
} catch (MissingTemplateException $e) {
if (Configure::read('debug')) {
throw $e;
}
throw new NotFoundException();
}
}
The way I achieved that was by using $this->params. If you use print_r($this->params);, you will see the content of that variable for you. It will return an array. You will see the difference of when you are versus when you are not in the home page. You will have to use one of the keys in $this->params to make your evaluations with an if statement. That was how I achieved it. Maybe you can find this approach useful too.

what is the purpose of having function exec() in Hook.php in prestashop

In the Header.tpl file there is a hook {$HOOK_TOP} which contains all the header part including menu, search etc... You can check that in this URL
In the FrontController it shows... 'HOOK_TOP' => Hook::exec('displayTop'),
it means in the Hook page there is a function called exec(). But I cannot understand the code properly in the exec() call.
It tells it Execute modules for specified hook. When I searched for "displayTop" I got a module name called blocktopmenu.php.
Execution only goes through 2 functions:
public function hookDisplayTop($param)
{
$this->user_groups = ($this->context->customer->isLogged() ? $this->context->customer->getGroups() : array(Configuration::get('PS_UNIDENTIFIED_GROUP')));
$this->page_name = Dispatcher::getInstance()->getController();
if (!$this->isCached('blocktopmenu.tpl', $this->getCacheId()))
{
$this->makeMenu();
$this->smarty->assign('MENU_SEARCH', Configuration::get('MOD_BLOCKTOPMENU_SEARCH'));
$this->smarty->assign('MENU', $this->_menu);
$this->smarty->assign('this_path', $this->_path);
}
$this->context->controller->addJS($this->_path.'js/hoverIntent.js');
$this->context->controller->addJS($this->_path.'js/superfish-modified.js');
$this->context->controller->addCSS($this->_path.'css/superfish-modified.css');
$html = $this->display(__FILE__, 'blocktopmenu.tpl', $this->getCacheId());
//print_r($html);//exit;
return $html;
}
and
protected function getCacheId($name = null)
{//echo"asdasdsad";exit;
parent::getCacheId($name);
$page_name = in_array($this->page_name, array('category', 'supplier', 'manufacturer', 'cms', 'product')) ? $this->page_name : 'index';
return 'blocktopmenu|'.(int)Tools::usingSecureMode().'|'.$page_name.'|'.(int)$this->context->shop->id.'|'.implode(', ',$this->user_groups).'|'.(int)$this->context->language->id.'|'.(int)Tools::getValue('id_category').'|'.(int)Tools::getValue('id_manufacturer').'|'.(int)Tools::getValue('id_supplier').'|'.(int)Tools::getValue('id_cms').'|'.(int)Tools::getValue('id_product');
}
But this public function hookDisplayTop($param) never gets called in the whole folder anywhere. I searched it but never found it in any file.
The exec() function shows below
public static function exec($hook_name, $hook_args = array(), $id_module = null, $array_return = false, $check_exceptions = true)
{
// Check arguments validity
if (($id_module && !is_numeric($id_module)) || !Validate::isHookName($hook_name))
throw new PrestaShopException('Invalid id_module or hook_name');
// If no modules associated to hook_name or recompatible hook name, we stop the function
if (!$module_list = Hook::getHookModuleExecList($hook_name))
return '';
// Check if hook exists
if (!$id_hook = Hook::getIdByName($hook_name))
return false;
// Store list of executed hooks on this page
Hook::$executed_hooks[$id_hook] = $hook_name;
// print_r(Hook::$executed_hooks);exit;
$live_edit = false;
$context = Context::getContext();
if (!isset($hook_args['cookie']) || !$hook_args['cookie'])
$hook_args['cookie'] = $context->cookie;
if (!isset($hook_args['cart']) || !$hook_args['cart'])
$hook_args['cart'] = $context->cart;
$retro_hook_name = Hook::getRetroHookName($hook_name);
//print_r($hook_name);exit;
// Look on modules list
$altern = 0;
$output = '';
foreach ($module_list as $array)
{
// Check errors
if ($id_module && $id_module != $array['id_module'])
continue;
if (!($moduleInstance = Module::getInstanceByName($array['module'])))
continue;
// Check permissions
if ($check_exceptions)
{
$exceptions = $moduleInstance->getExceptions($array['id_hook']);
$controller = Dispatcher::getInstance()->getController();
if (in_array($controller, $exceptions))
continue;
//retro compat of controller names
$matching_name = array(
'authentication' => 'auth',
'compare' => 'products-comparison',
);
if (isset($matching_name[$controller]) && in_array($matching_name[$controller], $exceptions))
continue;
if (Validate::isLoadedObject($context->employee) && !$moduleInstance->getPermission('view', $context->employee))
continue;
}
// Check which / if method is callable
$hook_callable = is_callable(array($moduleInstance, 'hook'.$hook_name));
$hook_retro_callable = is_callable(array($moduleInstance, 'hook'.$retro_hook_name));
if (($hook_callable || $hook_retro_callable) && Module::preCall($moduleInstance->name))
{
$hook_args['altern'] = ++$altern;
// Call hook method
if ($hook_callable)
$display = $moduleInstance->{'hook'.$hook_name}($hook_args);
else if ($hook_retro_callable)
$display = $moduleInstance->{'hook'.$retro_hook_name}($hook_args);
// Live edit
if (!$array_return && $array['live_edit'] && Tools::isSubmit('live_edit') && Tools::getValue('ad') && Tools::getValue('liveToken') == Tools::getAdminToken('AdminModulesPositions'.(int)Tab::getIdFromClassName('AdminModulesPositions').(int)Tools::getValue('id_employee')))
{
$live_edit = true;
$output .= self::wrapLiveEdit($display, $moduleInstance, $array['id_hook']);
}
else if ($array_return)
$output[] = $display;
else
$output .= $display;
}
}
if ($array_return)
return $output;
else
return ($live_edit ? '<script type="text/javascript">hooks_list.push(\''.$hook_name.'\'); </script>
<div id="'.$hook_name.'" class="dndHook" style="min-height:50px">' : '').$output.($live_edit ? '</div>' : '');// Return html string
}
I am not going to explain you the code line by line here, but i will explain you what the exec static member do.
When ever you call
Hook::exec("HookName");
It performs the following processes for you.
1) First it checks whether the hook is available or not? If it is not available return false;
2) Second it gets the module list for that hook from database. Also narrow down the list by exceptions for the modules for the hooks for the current page.
3) After it gets all the module(s) for the hook called for the current loaded (or called page) page, it calls the hooks function in the module. If you check modules for a specific hook you will find public function for that hook. Lets consider the Top hook. In modules you will have public functions like
public function hookTop // or public function hookDisplayTop for compatibility reasons
Please not that PS performs some other operations also there.
The above details are just giving you the idea that how hooks and modules work in PS.
Also taking the above theory, i implemented the same operations in Codeigniter and Zend Framework for my own projects, and it works like a charm ;) .
If you still have any other questions, let me know and i will provide you as much details as i can.
Thank you
Lines who call the HookDiplayTop are :
// Call hook method
if ($hook_callable)
$display = $moduleInstance->{'hook'.$hook_name}($hook_args);
else if ($hook_retro_callable)
$display = $moduleInstance->{'hook'.$retro_hook_name}($hook_args);

Categories