How to work with hook_nodeapi after image thumbnail creation with ImageCache - drupal

A bit of a followup from a previous question.
As I mentioned in that question, my overall goal is to call a Ruby script after ImageCache does its magic with generating thumbnails and whatnot.
Sebi's suggestion from this question involved using hook_nodeapi.
Sadly, my Drupal knowledge of creating modules and/or hacking into existing modules is pretty limited.
So, for this question:
Should I create my own module or attempt to modify the ImageCache module?
How do I go about getting the generated thumbnail path (from ImageCache) to pass into my Ruby script?
edit
I found this question searching through SO...
Is it possible to do something similar in the _imagecache_cache function that would do what I want?
ie
function _imagecache_cache($presetname, $path) {
...
...
// check if deriv exists... (file was created between apaches request handler and reaching this code)
// otherwise try to create the derivative.
if (file_exists($dst) || imagecache_build_derivative($preset['actions'], $src, $dst)) {
imagecache_transfer($dst);
// call ruby script here
call('MY RUBY SCRIPT');
}

Don't hack into imagecache, remember every time you hack core/contrib modules god kills a kitten ;)
You should create a module that invokes hook_nodeapi, look at the api documentation to find the correct entry point for your script, nodeapi works on various different levels of the node process so you have to pick the correct one for you (it should become clear when you check the link out) http://api.drupal.org/api/function/hook_nodeapi
You won't be able to call the function you've shown because it is private so you'll have to find another route.
You could try and build the path up manually, you should be able to pull out the filename of the uploaded file and then append it to the directory structure, ugly but it should work. e.g.
If the uploaded file is called test123.jpg then it should be in /files/imagecache/thumbnails/test123/jpg (or something similar).
Hope it helps.

Related

Wordpress: how to call method and output?

I am using a Wordpress plugin found here https://github.com/hirezstudios/smite-api-wp . Issue I have is the readme says I need to:
// call a method
global $smiteAPI;
$gods = $smiteAPI->getGods(1);
// do whatever with the god data...
I understand I need to implement it on one of my .php files or generate a new one. However, I am unsure what call a method means or how to make the above work. The getGods(1) will return a .json file of all gods in a game called Smite; 1 tells the API english.

Meteor how to save templates in mongo

I want to give my users the possibility to create document templates (contracts, emails, etc.)
The best option I figured out would be to store these document templates in mongo (maybe I'm wrong...)
I've been searching for a couple of hours now but I can't figure out how to render these document template with their data context.
Example:
Template stored in Mongo: "Dear {{firstname}}"
data context: {firstname: "Tom"}
On Tom's website, He should read: "Dear Tom"
How can I do this?
EDIT
After some researches, I discovered a package called spacebars-compiler that brings the option to compile to the client:
meteor add spacebars-compiler
I then tried something like this:
Template.doctypesList.rendered = ->
content = "<div>" + this.data.content + "</div>"
template = Spacebars.compile content
rendered = UI.dynamic(template,{name:"nicolas"})
UI.insert(rendered, $(this).closest(".widget-body"))
but it doesn't work.
the template gets compiled but then, I don't know how to interpret it with its data context and to send it back to the web page.
EDIT 2
I'm getting closer thanks to Tom.
This is what I did:
Template.doctypesList.rendered = ->
content = this.data.content
console.log content
templateName = "template_#{this.data._id}"
Template.__define__(templateName, () -> content)
rendered = UI.renderWithData(eval("Template.#{templateName}"),{name:"nicolas"})
UI.insert(rendered, $("#content_" + this.data._id).get(0))
This works excepted the fact that the name is not injected into the template. UI.renderWithData renders the template but without the data context...
The thing your are missing is the call to (undocumented!) Template.__define__ which requires the template name (pick something unique and clever) as the first argument and the render function which you get from your space bars compiler. When it is done you can use {{> UI.dynamic}} as #Slava suggested.
There is also another way to do it, by using UI.Component API, but I guess it's pretty unstable at the moment, so maybe I will skip this, at least for now.
Use UI.dynamic: https://www.discovermeteor.com/blog/blaze-dynamic-template-includes/
It is fairly new and didn't make its way to docs for some reason.
There are few ways to achieve what you want, but I would do it like this:
You're probably already using underscore.js, if not Meteor has core package for it.
You could use underscore templates (http://underscorejs.org/#template) like this:
var templateString = 'Dear <%= firstname %>'
and later compile it using
_.template(templateString, {firstname: "Tom"})
to get Dear Tom.
Of course you can store templateString in MongoDB in the meantime.
You can set delimiters to whatever you want, <%= %> is just the default.
Compiled template is essentially htmljs notation Meteor uses (or so I suppose) and it uses Template.template_name.lookup to render correct data. Check in console if Template.template_name.lookup("data_helper")() returns the correct data.
I recently had to solve this exact (or similar) problem of compiling templates client side. You need to make sure the order of things is like this:
Compiled template is present on client
Template data is present (verify with Template.template_name.lookup("data_name")() )
Render the template on page now
To compile the template, as #apendua have suggested, use (this is how I use it and it works for me)
Template.__define__(name, eval(Spacebars.compile(
newHtml, {
isTemplate: true,
sourceName: 'Template "' + name + '"'
}
)));
After this you need to make sure the data you want to render in template is available before you actually render the template on page. This is what I use for rendering template on page:
UI.DomRange.insert(UI.render(Template.template_name).dom, document.body);
Although my use case for rendering templates client side is somewhat different (my task was to live update the changed template overriding meteor's hot code push), but this worked best among different methods of rendering the template.
You can check my very early stage package which does this here: https://github.com/channikhabra/meteor-live-update/blob/master/js/live-update.js
I am fairly new to real-world programming so my code might be ugly, but may be it'll give you some pointers to solve your problem. (If you find me doing something stupid in there, or see something which is better done some other way, please feel free to drop a comment. That's the only way I get feedback for improvement as I am new and essentially code alone sitting in my dark corner).

drupal add node_access hook to existing module (OG)

Please don't ask why do i need to or why am I such a pervert.
I have an Organic Groups module on drupal 6.
I need to add node_access hook to this module for some reason.
There is no preset node_access hook in "og.module" file or any file, connected to this module (i've checked this).
I've tried adding "og_node_access" function with following body: "echo '1111111';return true;" and it doesn't trigger anywhere (no echoes at all). I've tried to add it to og.module file.
P.S.:
Please do not reccomend any access expansions for OG - I have tried plenty of them. All I need is:(pseudocode)
if ($op=='view'){
if ($node->type == 'xxxx' || $node->type =='yyyyyyyy') {
SHOW THIS TYPE OF NODES ONLY TO ADMIN(S) OF THE GROUP (OR SITE) AND THE AUTHOR OF THE NODE, NOBODY ELSE (EVEN IN THE SAME GROUP) IS ALLOWED TO SEE IT OR TOUCH IT.
} else {
USE DEFAULT RULES (return IGNORE);
}
}
And I need it to be hardcoded, because Taxonomy access, Content Access and other "Acess" modules don't work properly (actually they don't work at all) with OG module.
P.P.S.:
I know, that OG is kind of sht and there are a couple of alternatives, but i just need this to be done in a described way.
So... node_grants hook (I've mistyped in my comment it's "node_grants" not "access_grants") solved my problem.
Unfortunately I've spent too much time (the whole day) googling and trying to understand a bit complicated grants system of drupal.
Anyway thank you (all) for your answer(s).

how to properly register nginx header filter?

I'm writing an nginx module.
From looking at other examples I'm registering my header filter in my modules postconfiguration hook:
static ngx_int_t
mod_py_postconfig(ngx_conf_t *cf)
{
ngx_http_next_header_filter = ngx_http_top_header_filter;
ngx_http_top_header_filter = mod_py_headers_filter;
return NGX_OK;
}
But the handler is never called. I've set a breakpoint in gdb on ngx_http_top_header_filter change and it seems my module's postconfig is called first, but then runs postconfig of the ngx_http_write_filter_module which overrides ngx_http_top_header_filter w/o storing the old value:
static ngx_int_t
ngx_http_write_filter_init(ngx_conf_t *cf)
{
ngx_http_top_body_filter = ngx_http_write_filter;
return NGX_OK;
}
it seems like it is designed to be the very last on called, so how come my module's postconfig is called first?
From what I can see the order of modules is set in objs/ngx_modules.c
I was able to fix the problem by manually reordering the modules there so that my module comes after ngx_http_header_filter_module, but this feels like an ugly hack, and also makes it hard to automate build process as ./configure overwrites this file each time.
OK, so I figured it out myself. Documenting it here in case anyone else will need it.
I was adding my module to the wrong list. The nginx module is configured through a 'config' file insed module's directory. My had the following line in it:
HTTP_MODULES="$HTTP_MODULES ngx_http_my_module_name"
I searched for HTTP_MODULES usage and found nginx/auto/modules script which actually builds ngx_modules.c file. It turns out there are several possible module lists used by nginx/auto/modules. I needed to add my module to the HTTP_AUX_FILTER_MODULES list like so:
HTTP_AUX_FILTER_MODULES="$HTTP_AUX_FILTER_MODULES ngx_http_my_module_name"
This placed my module at the right place just after HTTP_HEADERS_FILTER_MODULE and fixed the problem.

Migration to new domain

I'm working on a drupal 6 site at mydomain.com/drupalsite, and the designer has put a lot of hardcoded image paths in there, for instance a custom img folder in mydomain.com/drupalsite/img. So a lot of the site uses links to /drupalsite/img/myimg1.png.
Here's the problem -- the site is eventually moving to finaldomain.com, via pointing finaldomain.com to mydomain.com/drupalsite. So now paths like /drupalsite/img/myimg1.png will resolve to finaldomain.com/drupalsite/img/myimg1.png, instead of what should be finaldomain.com/img/myimg1.png. The finaldomain.com site has to point to that subdirectory so it hits the index.php.
My first instinct is to use an .htaccess file to replace the /drupalsite with "", but I've tried about a dozen different solutions and they haven't worked. My hack of a solution was to use some ln -s links but I really don't like it :) tia
Andrew
The best method, in hindsight, is to ensure folks use Drupal functions to make all links:
l (that's the letter L)
drupal_get_path()
base_path()
The l() function takes care of base path worries, and provides a systematic way to define your URL's. Using things like theme_image() plus the l() function are a sure win. Use the second and third functions above if you have to write your own <a> tags and for use inside theme functions like theme_image().
But for your current situation:
As regards Andy's solution, it would be better if you could limit your changes to certain database fields where you know the links are located.
So write a query to select all those fields (e.g. all body fields):
$my_query = db_query("SELECT vid, body FROM {node_revisions}");
This, for example, will get you every body field in the node_revisions table, so even your old revisions would have proper links.
Then run through those results, do str_replace() on each, and then write the changes back:
while($node = db_fetch_object($my_query)) {
$new_body = str_replace('what you have', 'what you want', $node->body);
db_query("UPDATE {node_revisions} SET body = '%s' WHERE vid = %d", $new_body, $node->vid);
}
I'd obviously try it on one record first, to make sure your code behaves as intended (just add a WHERE vid = 5, for example, to narrow it down to one revision). Furthermore, I haven't taken advantage of node_load and node_save, which are better for loading and saving nodes properly, so as to provide a more general solution (for you to replace text in blocks, etc.).
For your files, I'd suggest a good ol' sed command, by running something like the following from within your "sites" folder:
find ./ -type f -exec sed -i ’s/string1/string2/’ {} \;
Nabbed that from here, so take a look on that site for more explanation. If you're going to be working with paths, you'll either need to escape the / of the paths in your version of the sed command, or use a different sed separator (i.e. you can write s#string1#string2# instead of s/string1/string2/, so you could write s#/drupalsite/img/#/img# instead of s/\/drupalsite\/img\//\/img/ :-). See also Drupal handbook page for quick sed commands: http://drupal.org/node/128513.
A bit of a mess, which is why I try to enforce using the proper functions up front. But this is difficult if you want themers to create Drupal content but you don't want to give them access to the "PHP Filter" input format, or they simply don't know PHP. Proper Drupal theming, at any point past basic HTML/CSS work, requires a knowledge of PHP and Drupal's theme-related functions.
I've done this before by taking a full database dump, opening it in a text editor, and doing a global search and replace on the paths. Then on the new host, load the modified dump file, and it will have the correct paths in.
You could try Pathologic, it should be able to correct paths like this.

Resources