PDA

View Full Version : Is it possible to show images into dhtml.table using channels?



varosi
07-07-2011, 09:08 AM
Hello!

Is it possible to show images into dhtml.table using channels? And how to?

neilw
07-07-2011, 08:35 PM
No, it is not possible. But that doesn't mean it's impossible. :cool:

The stock dhtml.table() function always outputs text, period. So I threw together a new template, dhtml_table_plus (http://developer.mindtouch.com/Template:dhtml_table_plus), that extends the functionality just a bit. You use it just like dhtml.table(), except that if a field name ends in "HTML" (case insensitive), the message text will be interpreted as HTML rather than plain text.

See it in action (http://developer.mindtouch.com/User:Neilw/Testing/enhanced_DHTML_table).

Not well tested, but seems to work. The template would be easy to hack to customize the appearance as desired.

Enjoy.

varosi
07-08-2011, 08:17 AM
Wow! Great, thank You very much! May be it is a good idea this template to be embedded in standard DekiScript library some day! It will be very powerful.

varosi
07-08-2011, 09:18 AM
How could I use this template with conjunction with ImageMagick. image.* functions are returning some kind of local URI. How could I transform it to "outside accessible" URI? To make it possible to display on that new table.

neilw
07-08-2011, 01:12 PM
You'll need to be a bit more specific than that. Exactly what do you want to do?

varosi
07-08-2011, 02:30 PM
I have large pictures attached to different pages in Deki. I have script that gather those pictures URLs and some other info and pass them to image.fittosize(). Then I would like to pipe them through a channel to that table you made. I would like to separate gathering code from table for easy use as different templates. That is why I'm using channels.

neilw
07-08-2011, 03:36 PM
Well, I can't get image.fittosize to work at all on my Wiki, and it seems like the ImageMagick extension is not running on the MCP. So I can't test it. If it is returning one of those funky local URIs, you're probably out of luck.

You don't strictly need image.fittosize() for wiki attachments, though. Depending on how you're identifying the images you want to use (list of URLs? Search?) you can get the dimensions from the API and set the width or height of the <img> object passed in the message sent from Pagebus.publish(). If you give me an idea how you're generating your list of images, I can help out with that.

Now that I understand your use case, though, I'm not super enthusiastic about using channels to solve your problem. That stuff is really designed to handle dynamic page construction given client interactions, whereas your application could be done completely on the server side. I don't think it would in any way hinder your ability to keep the table generator and the image gathering separate. But ultimately that's up to you.

varosi
07-08-2011, 04:02 PM
The idea is to have two script commands: {{ UserList() }} that is pushing user profiles (custom profiles). And a DHTML table that is listening to the default channel that could be configured easily by our stuff to display only certain columns including ones that have people's pictures. May be it is good idea to scale on HTML, not on the server-side. This may speed-up page loading. Because now it takes from 3 to 6 seconds to load the page with about 60 users.

neilw
07-08-2011, 04:07 PM
Ah, I see what you're doing (mostly). That is pretty clean, though I can almost certainly assure that the 3-6 seconds is being driven by UserList(), not the table. But whatever.

So basically, we just need to design out image.fittosize(). Can you give me an idea of how UserList() works right now?

varosi
07-11-2011, 09:09 AM
Now it does something like this:
var usersURLs = list.apply( list.select( site.users, "!$.anonymous && $.name!='Admin'"), "$.Uri" );
foreach( var userURL in usersURLs ) {
let userName = uri.parts( userURL ).path[0];
let userPage = wiki.page( userName );
let name = xml.text( userPage, "//div[@id='name']" );
.... // parsing different fields of the profile
pagebus.publish( publish, fields );
}

neilw
07-11-2011, 08:09 PM
I don't see anything in there about the image handling. If our immediate goal is to eliminate the need for image.fittosize() then we need to see how we're getting those image URLs.

Regarding performance, if you're doing a wiki.page() on each user's homepage, that would explain why the whole thing is taking a long time. You should definitely use webcache() to speed things up.

If conditions are right (more on this below), you can also probably get some speedup by eliminating the wiki.page() altogether. Each user variable contains a pointer to the page variable for that user's homepage. Then you can get page.xml on that page, and work from there. This would give something like this:


foreach (var u in list.select( site.users, "!$.anonymous && $.name!='Admin'")) {
var userName = u.name;
var userPage = u.homepage.xml;
...
pagebus.publish(publish, fields);
}


This is simpler and takes much better advantage of the data available in the user variable. I don't know exactly how much faster this would be, but it should be faster.

The only caveat, mentioned above, is that page.xml doesn't execute any DekiScript on the page. So, if you're looking to extract fields from the homepages that might have DekiScript in them, this won't work, and you'll need to go back to using wiki.page().

varosi
07-12-2011, 08:01 AM
Thanks for the code. But I need DekiScript for this page. I could think on some other variant. But you give me good ideas how to accelerate it! Thank you!

Image URLs are extracted the same way:
let imageURL = xml.text( userPage, "//div[@id='avatar']//@src" );

And this are not local URLs, but have full URI globally accepted.

varosi
07-12-2011, 02:38 PM
How this "webcache()" is used? I don't find information about it on developer.mindtouch.com

neilw
07-14-2011, 07:07 PM
Look in the App Catalog for webcache. I'm working on an article to explain it, but it's pretty simple. My typical usage would be:



var cacheid = "whatever-cache-id-i-want-to-use";
webcache.fetch(cacheid) ?? webcache.store(cacheid, (

// slow DekiScript code goes here; generate whatever output you want

), 3600); // #seconds of caching; 3600 -> 1 hour as an example


Cacheid defines a unique id for the entry into the cache. This is global for the entire wiki. Webcache.fetch(cacheid) looks to see if there's an up-to-date entry for that id in the cache. If so, it returns it, and the code outputs that. If not, it returns nil, and the webcache.store() executes instead.

Webcache.store() takes some XML (as typically output by a DekiScript block) and stores it in the cache. It also returns the XML, so in the code above that'll be output to the page.

It works great; the main caveats are:
1) the output page will potentially be "out of date" according to how the time-to-live parameter is set. Usually this isn't a big deal.
2) The lucky user who first loads the page when the cache expires will have to wait for the complete page load time. So it shouldn't be *too* long, or that user might never even wait for it to finish.

Sorry I don't have a great solution for your images if they're not locally attached to the wiki. You might be able to do your fittosize() in JavaScript, but that might get a little messy given the structure you're using.

varosi
07-15-2011, 09:05 AM
I added this webcache and now it is working lot faster! Thank You very much! This is great!

About images - yes, they are locally attached to Deki pages.