Drupal: cannot unset js file and use new js in theme directory - drupal

I want to copy a js file in my theme folder instead of hacking the module. This is my code:
/*update js files */
$scripts = drupal_add_js();
unset($scripts['module']['sites/all/modules/imagefield_crop/imagefield_crop.js']);
$scripts['module']['sites/all/themes/zen/zen/js/imagefield_crop.js'] = array('preprocess' => 1, 'cache' => 1);
$vars['scripts'] = drupal_get_js('header', $scripts);
IT works for lightbox2 but it doesn't work for imagefield_crop.js
I've cleaned all Drupal caches and browser cache but my browser continues to load the original js in the module directory.
thanks
Update: This is the array $scripts
['module']
...
[sites/all/modules/imagefield_crop/Jcrop/js/jquery.Jcrop.js] => Array
(
[cache] => 1
[defer] =>
[preprocess] => 1
)

Given the updated question after the discussion in the comments, it seems like you are mixing up the involved js files. Imagefield_crop adds two different ones:
jquery.Jcrop.js, which is an imported library file providing the crop functionality in general (in context of jquery) - normally, you should not have a reason to replace this.
'imagefield_crop.js', which is the one providing the 'bridging' to allow the above library to work properly in the Drupal context - my understanding was that you wanted to replace this one.
Both are needed for the functionality to work. Your posted code would only replace the second one, and unless you accidentally posted the wrong code snippet in your question update, it seems to work.
If you wanted to replace both (or only the first one), you'd need to extend/adjust your unsetting logic to do so.

Hello here is the possible solutions it might help though I've never done this before
/**
* Implementation of hook_theme_registry_alter().
* Based on the jquery_update module.
*
* Make this page preprocess function runs *last*,
* so that a theme can't call drupal_get_js().
*/
function MYMODULE_theme_registry_alter(&$theme_registry) {
if (isset($theme_registry['page'])) {
// See if our preprocess function is loaded, if so remove it.
if ($key = array_search('MYMODULE_preprocess_page',
$theme_registry['page']['preprocess functions'])) {
unset($theme_registry['page']['preprocess functions'][$key]);
}
// Now add it on at the end of the array so that it runs last.
$theme_registry['page']['preprocess functions'][] = 'MYMODULE_preprocess_page';
}
}
/**
* Implementation of moduleName_preprocess_hook().
* Based on the jquery_update module functions. *
* Strips out JS and CSS for a path.
*/
function MYMODULE_preprocess_page(&$variables, $arg = 'my_page', $delta=0) {
// I needed a one hit wonder. Can be altered to use function arguments
// to increase it's flexibility.
if(arg($delta) == $arg) {
$scripts = drupal_add_js();
$css = drupal_add_css();
// Only do this for pages that have JavaScript on them.
if (!empty($variables['scripts'])) {
$path = drupal_get_path('module', 'admin_menu');
unset($scripts['module'][$path . '/admin_menu.js']);
$variables['scripts'] = drupal_get_js('header', $scripts);
}
// Similar process for CSS but there are 2 Css realted variables.
// $variables['css'] and $variables['styles'] are both used.
if (!empty($variables['css'])) {
$path = drupal_get_path('module', 'admin_menu');
unset($css['all']['module'][$path . '/admin_menu.css']);
unset($css['all']['module'][$path . '/admin_menu.color.css']);
$variables['styles'] = drupal_get_css($css);
}
}
}
http://www.mediacurrent.com/blogs/remove-or-replace-jscss-page

Related

Best way to modify OpenCart without touching Core and VQMOD/OCMOD

Is there a better way then using VQMOD/OCMOD to change OpenCart's core files?
Is there some "overrides" folder exists so that I can simply create any PHP file corresponding to the file structure and simply override a core file? (Like it is possible in PrestaShop and Magento).
VQMOD/OCMOD is highly inconvenient.
Does someone use any hacks & tricks to achieve the result?
I don't want to touch any core files to keep the system clean and manageable.
Thanks a lot!
My solution was to modify 1 function (modification()) in the system/startup.php which then allows you to copy any existing PHP file into an 'override' folder and modify it without making changes to the original file.
I'd like to find a way of just replacing the functions changed/added, but the OOP approach in OpenCart doesn't easily allow this.
I've adapted a few OCMOD modules to fit my override method (by applying the module, copying the changed files into my override structure and then removing the module), as I think it's easier to maintain and easier to develop with, and when I create my own modules, I create dummy files in the main structure and the actual files in the 'override' directory, which means all my modifications/additions are in one folder that maintains the structure of the original layout.
It would be possible to generate file diffs that create an OCMOD, but I haven't had time to do that yet. I do mark all my changes, so I can upgrade to newer versions by re-applying my changes manually (which is usually a "good thing" (c), and there is potential to have conflict with other extensions, so manually marking changes means I can apply changes to OCMOD patched files too.
My modification function looks like this:
function modification($filename) {
$mod_dirs = array(
DIR_MODIFICATION,
dirname(DIR_SYSTEM).'/override/' // do this second in case there are other over-rides needed for modules
);
foreach($mod_dirs as $mod) {
if (!defined('DIR_CATALOG')) {
$file = $mod . 'catalog/' . substr($filename, strlen(DIR_APPLICATION));
} else {
$file = $mod . 'admin/' . substr($filename, strlen(DIR_APPLICATION));
}
if (substr($filename, 0, strlen(DIR_SYSTEM)) == DIR_SYSTEM) {
$file = $mod . 'system/' . substr($filename, strlen(DIR_SYSTEM));
}
if (is_file($file)) {
return $file;
}
}
return $filename;
}
and my directory structure looks like this
/override
/override/admin
/override/catalog
/override/system
If you want to call your function within the system which follows the OC structure, avoid the search/replace mods, try using the new Opencart Events (a.k.a. hooks) instead:
https://github.com/opencart/opencart/wiki/Events-System
Or, you can still use the Opencart override engine (by a 3rd-party developer) though.
You can use Vqmod or Ocmod in OpenCart. both are working in OpenCart for overrides code.
For vqmod:
Read this Official OpenCart documentation.
http://docs.opencart.com/administration/vqmod/
For ocmod:
OCMOD works independently. You have to create ocmod xml file with ".ocmod.xml" extension, then you can upload that file using "Extension Installer" from admin panel of opencart.
You have to clear and refresh the modification cache to update the system and make the extension work. You can clear and refresh by top right buttons on Extension > Modification page in admin panel.
wouldn't it be possible to identify a controller file dependent if an alternative exists somewhere else? You could use vq/ocmod one time to write a script that says "if alternative core file exists in xyz location, use it, otherwise, use core file out of base folder" then add new core files to the mods directory that you created.. just a thought..
You can try the following solution. The advantage is you can use it with any files moved into system/override folder
function modification($filename) {
if (defined('DIR_CATALOG')) {
$file = DIR_MODIFICATION . 'admin/' . substr($filename, strlen(DIR_APPLICATION));
} elseif (defined('DIR_OPENCART')) {
$file = DIR_MODIFICATION . 'install/' . substr($filename, strlen(DIR_APPLICATION));
} else {
$file = DIR_MODIFICATION . 'catalog/' . substr($filename, strlen(DIR_APPLICATION));
}
if (substr($filename, 0, strlen(DIR_SYSTEM)) == DIR_SYSTEM) {
$file = DIR_MODIFICATION . 'system/' . substr($filename, strlen(DIR_SYSTEM));
}
if (is_file($file)) {
$new_file = str_replace("/storage/modification/" , "/override/",$file );
if (is_file($new_file)) $__file = $new_file;
else $__file = $file;
return $__file;
}
if( preg_match("/\/catalog\/model\//", $filename) )
$new_file = str_replace("catalog/model", "system/override/catalog/model", $filename );
else if( preg_match("/\/catalog\/controller\//", $filename) )
$new_file = str_replace("catalog/controller", "system/override/catalog/controller",$filename );
else $new_file = '';
if (file_exists($new_file )) $__file = $new_file;
else $__file = $filename;
return $__file;
}

Adding views programmatically to custom module in drupal 7

I am a newbie and have started writing modules. I need to add multiple views in 1 module. I have added 1 view using hook_views_api() and hook_views_data(). Please can anybody help in adding more views in single module?
This topic has been dormant for a number of years but has had no proper answer. So allow me.
The problem above is that you are listing your views in the same file, which is messy and unorganized. Below is a more appropriate and straightforward way of doing things.
Firstly i suggest creating a folder in your module directory, for example "YOUR_MODULE/views/".
Then for each view you would like to import you will create a new file such as "my_view.inc" with one file being one view. This makes it easier to find the view your looking for if you need to make changes later on.
Then is to declare which api you will use for your imports.
/**
* Implements hook_views_api().
*/
function YOUR_MODULE_views_api() {
return array(
'api' => '3.0',
);
}
Once you have declared the api version you will need the following below.
/**
* Implements hook_views_default_views().
*/
function YOUR_MODULE_views_default_views() {
$views = array();
$path = drupal_get_path('module', 'YOUR_MODULE') . '/views/*.inc';
foreach(glob($path) as $file) {
require_once $file;
$views[$view->name] = $view;
unset($view);
}
return $views;
}
What this does is look for all the "my_view.inc" files inside the subdirectory and will load them all automatically after a Clear Cache.
Hope this helps those who are still stuck.
Be sure to declare hook_views_api() or this hook won't get fired.
But you do this via hook_views_default_views()
In Views, you create the View you would like to include in the module. Then you use function hook_views_default_views() and attach the export code (from views) like so:
function yourmodulename_views_default_views() {
// Begin copy and paste of output from the Export tab of a view.
$view = new view;
// ..yadda yadda yadda
// Add view to list of views to provide.
$views[$view->name] = $view;
// Begin copy and paste of output for another view
$view = new view;
// ..yadda yadda yadda
// Add view to list of views to provide.
$views[$view->name] = $view;
return $views
}
The return $views at the end of the function will return all of the views for you.

Parse Smarty template without triggering calls to user plugins

I'm writing a (Symfony2) SmartyBundle extension to support Assetic.
To support the stylesheets feature I've registered a block plugin called stylesheets:
{stylesheets
assets='#SmartyBundle/Resources/public/css/*'
debug=true}
{$asset_url}
{/stylesheets}
This plugin gets called properly and everything work as expected when the Symfony/assetic cache is created.
The problem arises When the Symfony cache is empty and Assetic loads every template file resource and asks the template engine to retrieve a PHP array with the tokens found in the stylesheets tag. The class called to retrieve the array is SmartyFormulaLoader.
<?php
class SmartyFormulaLoader implements \Assetic\Factory\Loader\FormulaLoaderInterface
{
public function load(ResourceInterface $resource)
{
// raw template content
$content = $resource->getContent();
// a FileLoaderImportCircularReferenceException is throw here
$smartyParsed = $this->smarty->fetch('string: '.$content);
// build an array with tokens extracted from the block function
$formulae = $this->extractStylesheetsTokens($smartyParsed);
return $formulae;
}
When $smarty->fetch() is called in the load() method an exception is thrown: Symfony\Component\Config\Exception\FileLoaderImportCircularReferenceException: Circular reference detected in "." ("." > ".").
This is caused by the Smarty template being parsed/compiled and the stylesheets plugin being called again.
So I'm asking if Smarty provides a template parser that extracts the block function tokens (without calling the stylesheets plugin) so I can feed Assetic. Or any other solution that I may be missing to solve this.
Thanks.
After a little chat with Smarty dev #rodneyrehm we came to the conclusion that:
Should parse raw template source instead of compiling the template and parsing it
Should write my own parser (instead of using some Smarty internal helper)
So, for this particular case we came up with this implementation:
<?php
class SmartyFormulaLoader
{
public function load(ResourceInterface $resource)
{
// template source
$templateSource = $resource->getContent();
// ask Smarty which delimiters to use
$ldelim = $smarty->left_delimiter;
$rdelim = $smarty->right_delimiter;
$_ldelim = preg_quote($ldelim);
$_rdelim = preg_quote($rdelim);
// template block tags to look for
$tags = implode('|', array('stylesheets', 'javascripts', 'image));
// match every assetic tag
if (preg_match_all('#'.$_ldelim.'(?<type>'.$tags.').*?'.$_rdelim.'#s', $templateSource, $matches, PREG_SET_ORDER)) {
foreach ($matches as $match) {
// extract block attributes
if (preg_match_all('#(?<key>[a-zA-Z0-9_]+)\s*=\s*(["\']?)(?<value>[^\2]*?)\2(\s|'.$_rdelim.')#s', $match[0], $_matches, PREG_SET_ORDER)) {
$t = array(
'type' => $match['type'],
'attributes' => array(),
);
foreach ($_matches as $_match) {
if (empty($_match[2])) {
// make eval a little bit safer
preg_match('#[^\w|^\.]#', $_match['value'], $evalMatches);
$_match['value'] = ($evalMatches) ? null : eval(sprintf('return %s;', $_match['value']));
}
$t['attributes'][$_match['key']] = $_match['value'];
}
// call some Assetic methods with the extracted attributes
$formulae += $this->buildFormula($match['type'], $t['attributes']);
}
}
}
return $formulae;
}
}
Full implementation is available here: https://github.com/noiselabs/SmartyBundle/blob/master/Assetic/SmartyFormulaLoader.php

(Drupal 6) $theme_key returning no value

I am trying to set up a Drupal 6 node to load blocks dynamically depending on the selected theme. I figured that I could use $theme_key to determine the name of the theme, and work from there. The weird thing is that if I have several checks on a page, the first one will return an empty value for $theme_key, but subsequent checks will work as expected.
For instance:
<?php
print "Theme: ". $theme_key;
if($theme_key =="foo"){
$viewName = 'theView';
$display_id = 'block_1';
print views_embed_view($viewName, $display_id);
}
else {
$viewName = 'theOtherView';
$display_id = 'block_1';
print views_embed_view($viewName, $display_id);
}
?>
If I have the above in the node multiple times with theme "foo" active (for testing purposes) - the first time will return a blank value for $theme_key, and display theOtherView, but the second time it will show Theme: foo and will display theView. All subsequent calls to $theme_key will be correct as well.
Any calls to $theme_key prior to the first block will return blank values.
I am declaring
<?php global $theme_key; ?>
at the beginning of the node content. (Before all of the conditional blocks...)
What am I doing wrong? Is there a better way to check the current theme?
Just looking at the init_theme() function the globals $theme and $theme_key contain exactly the same values so you could try using $theme (as yvan suggested), but as they contain the same data and are both globals set in the same function I'm not sure it would make any difference.
Is this code in a template file? If so you could be suffering from the age old Drupal theming problem whereby some variables aren't available when the template is built. You could try adding a hook_preprocess_node() function in a module/theme to set up the variable and pass it to your template file. Something like this:
function MYMODULE_preprocess_node(&$vars) {
global $theme_key;
$vars['current_theme_key'] = $theme_key;
}
And then in your template file you'll have access to the variable $current_theme_key, which should then have the right variable in it.
Hope that helps, I've come across these sort of problems with Drupal before and they're a nightmare to debug.
Edit to add more helpful function:
function MYMODULE_preprocess_node(&$vars) {
$node = $vars['node'];
if ($node->type == 'my_type') {
global $theme_key;
$view_name = $theme_key == 'foo' ? 'theView' : 'theOtherView';
$display_id = 'block_1';
$vars['my_custom_view'] = views_embed_view($view_name, $display_id);
}
}
Then in your node.tpl.php or node-type.tpl.php file you can use code like this:
if (isset($my_custom_view)):
echo $my_custom_view;
endif;
By constructing the variables in a preprocess function you shouldn't have any problems with the global $theme_key not being available any more.
Bear in mind you could also implement this in your theme (in the template.php file) by changing the function name to MYTHEME_preprocess_node.
Make sure you clear your Drupal cache once you've implemented the function (wherever you decide to put it) so the system will pick up the changes.
Hope that helps!

Can Drupal change the template used based on a file extension in the url?

I am using Drupal 6.16 with a number of modules installed. I was trying to find out if there is a way to change the output of a node when a different file extension is added to the url. For example:
http://example.com/drupal?q=foo/bar - returns a normal drupal node
http://example.com/drupal?q=foo/bar.xml - returns xml output of the node
Is this even possible with Drupal? Do I have to hack the core code to get this working?
You should not need to hack the core code. There are probably several contributed modules that can do this for you.
To output an XML version of a node, check out the Views Bonus Pack module, which extends the Views module. It has basic export capabilities, including CSV, TXT, DOC, and XML. The documentation is brief, but there is a README.txt file in the views_bonus/export/ directory that gives the basic steps for creating a feed in a view that will output XML.
You can set the path for the feed, so while I don't believe the .xml extension will work, you could set up a path with an additional component like this:
http://example.com/drupal?q=foo/bar <-- normal output
http://example.com/drupal?q=foo/bar/xml <-- XML output
To change the template file that is used for a node based on the path, you can use a preprocess function in your template.php file to add a template suggestion based on the path. This takes a bit more understanding of how the template files work, but ultimately you'll have more control of the output than you will with a view.
Here is how I fixed this.
Add the custom_url_rewrite_inbound function to check for incoming request ending with .xml. If it finds a request ending with .xml it strips that off, so that the correct data can be located by the rest of the drupal machinery. It also sets 'subsite_xml_request' to true so that the appropriate theme template can be used later.
function custom_url_rewrite_inbound (&$result, $path, $path_language) {
if(preg_match('/\.xml$/', $path)) {
$search = preg_replace('/^(.*)\.xml$/', "$1", $path);
if ($src = drupal_lookup_path('source', $search, $path_language)) {
$_REQUEST['xml_request'] = true;
$result = $src;
}
}
Modify the phptemplate_preprocess_page function in your template.php to add additional '-xml' templates.
function phptemplate_preprocess_page(&$vars) {
if ($_REQUEST['xml_request']) {
if (module_exists('path')) {
$path = str_replace('/edit','',$_GET['q']);
$alias = drupal_get_path_alias($path);
if ($alias != $_GET['q']) {
$template_filename = 'page';
foreach (explode('/', $alias) as $path_part) {
$template_filename = $template_filename . '-' . $path_part;
$vars['template_files'][] = $template_filename . '-xml';
}
$vars['template_files'][] = 'page-xml';
}
}
}
}
Create the required page-xml.tpl.php

Resources