Invoking Photoswipe in mixed content blog posts - photoswipe

I'm using Photoswipe on blog posts that contain mixed content, like images, but also text, videos etc., not so much separate galleries with just images. Executing Photoswipe on the entire post seems to apply to more than the <figure> elements alone, so I'm looking to be a bit more specific. I would like to invoke Photoswipe only on the <figure> elements, but I'm at a bit of a loss on how I would do that.
I think the main idea here is that this variable:
var thumbElements = el.childNodes
...should be more specific. So I need something like this to work:
var allElements = el.childNodes,
thumbElements = allElements.getElementsByTagName("figure");
Except that doesn't work. Later on in the code, the figure elements are defined separately:
figureEl = thumbElements[i]; // <figure> element
So I'm a little lost here... I'd appreciate any help.

Okay, finally got it to work myself. For anyone else who may run into this, here's a better explanation of what I needed to work (I was a little vague in my initial question here), and how I got it to work.
In the documentation, Photoswipe provides a suggestion for how to implement it on a gallery, see the section How to build an array of slides from a list of links on http://photoswipe.com/documentation/getting-started.html
What this implementation assumes, is that your gallery is just that: just a collection of images. However, I use Photoswipe on all my blog posts, and these blog posts consist of mixed content, including paragraphs and videos and whatnot.
The provided implementation code did not allow for this out of the box, so I made two small adjustment to make it work.
I changed this:
// include only element nodes
if(figureEl.nodeType !== 1) {
continue;
}
Into this
// include only elements of the FIGURE name
if(figureEl.nodeName !== 'FIGURE') {
continue;
}
And following this concept, this:
if(childNodes[i].nodeType !== 1) {
continue;
}
Into this:
if(childNodes[i].nodeName !== 'FIGURE') {
continue;
}
Now, Photoswipe is not applied to all element nodes, but only child nodes that are more specifically of the FIGURE element type :)

Related

authorProfileImageUrl returns only a tiny thumbnail

I'm trying to use YouTube Data API to get a list of comments for a video.
The problem is that the field authorProfileImageUrl in the response contains a URL to a tiny thumbnail (28x28 pixels) of the profile image instead of the bigger one (48x48) that can be seen in YouTube's comment section. How can I retrieve the bigger one? Am I missing some magic parameter in the request that selects the size of the profile images in comments?
Here's my request URL:
https://www.googleapis.com/youtube/v3/commentThreads?videoId=VIDEO_ID&part=snippet&fields=pageInfo,items(snippet(topLevelComment(id,snippet(authorDisplayName,authorChannelUrl,authorProfileImageUrl,authorChannelId,textDisplay,likeCount,publishedAt)),totalReplyCount))&maxResults=3&key=API_KEY
Edit:
Here's an example profile pic URL i get:
https://yt3.ggpht.com/-b-fXZSZ0hPw/AAAAAAAAAAI/AAAAAAAAAAA/mq4JpF46xq4/s28-c-k-no-mo-rj-c0xffffff/photo.jpg
^^
I noticed that the marked part seems to select the size, because when I change the 28 to 48, the size of the profile pic changes too.
I could change it "manually" with some fancy regexp, and it will work, but it will also rely on implementation details that are undocumented and that may change in future and render the application broken :P So it really would be better if there was a documented API way to do that.
Seems like nobody knows how to solve this, ho here's my temporary solution.
It works, but it depends on an implementation detail that can change in the future and then the solution will break apart and will have to be corrected :q
I accept my own answer for now, but when someone posts a better one, I'll accept it instead.
The solution:
I made a simple function that searches for the image size in the URL string and replaces it with a bigger size.
function small2big(url)
{
return url.replace(/(\/.*s)28(.*\/photo.jpg)$/,"$1"+"48"+"$2");
}
Oh, and here's my middle finger for you, Google: ,,|,,
It seems that actually removing everything right at the 's28' will display the entire image without specifying a size.
For example, instead of this:
https://yt3.ggpht.com/-b-fXZSZ0hPw/AAAAAAAAAAI/AAAAAAAAAAA/mq4JpF46xq4/s28-c-k-no-mo-rj-c0xffffff/photo.jpg
You can use this: https://yt3.ggpht.com/-b-fXZSZ0hPw/AAAAAAAAAAI/AAAAAAAAAAA/mq4JpF46xq4/
And it will return the full size image.
In my case, using php I simply:
function bigAvatar($url) {
$url = substr($url, 0, strpos($url, 's28'));
return $url;
}
Again, if google decides to change this in the future, this would break. But for now, it works.

Problems spawning draggable objects from database using web2py and jQueryUI

I am attempting to build a small proof-of-concept web application using the web2py framework. I'm so close, but my basic lack of knowledge of what's going on means I'm just hacking at it with pure guesswork rather than understanding what's going on. I was hoping someone on here could explain where I am going wrong...
The functionality I'm after is that the data needed to create the draggable items is held in a database table (and will ultimately form a hierarchy) with as little information held in the HTML as possible.
There's a fair bit of information for just about everything in this stack, so much so that I'm drowning in it, I don't know where to start. I suppose I should begin with what I've got so far...
The HTML:
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.2/jquery-ui.js"></script>
...
<script>
$(document).ready(function(){
$.ajax( {
type: "POST",
url: 'dragndrop.py',
success: function( response ) {
$("#draggable7").html(response);
}
} )
});
</script>
<div id="draggable7"></div>
The dragndrop.py script:
## My main draggable spawner
selected = [row.id for row in db(db.t_user_shop_layouts.id==7).select()]
return ''.join([DIV('draggable'.join(k), _class='draggable ui-widget-content', _snap=".ui-widget-header", _snapMode= "inner", _grid= [ 80, 80 ], _style='position: relative;') for k in selected])
And, just for completeness, the model web2py script (although the column I'm interested in is the "id" column, which is auto-generated):
db.define_table('t_shop_layout_items',
Field('f_item_display_name_string', type='string', notnull=True,
label=T('Item Display Name String')),
Field('f_item_icon_file', type='upload',
label=T('Item Icon File')),
Field('f_item_parent_id', type='integer',
label=T('Item Parent Id')),
auth.signature,
format='%(f_item_display_name_string)s',
migrate=settings.migrate)
I'm forcing the db call to only pick up one row at the moment (id == 7) just to get the ball rolling, but eventually what I'd like to do is have the (db.id == db.f_item_parent_id) items shown first. Then when double-click, any (db.f_item_parent_id == this.id) children get spawned using helpers. Then I'm going to get an 80x80 grid size target to land on to set shop layout, and save to db. But all this paragraph is for later, I'm just giving you an idea of where I'm going with it.
Finally, some great tutorials that have helped me along the way, but were either not web2py (PHP seems popular for this) or not dynamically spawning (but hard-coded in the HTML, or what-have-you. If I've missed something obvious, please let me know:
An excellent fiddle: http://jsfiddle.net/robertrozas/qLhke/25/ and its stack overflow beginnings Jquery drag drop form hidden value inserting into php mysql
The web2py documentation: http://web2py.com/books/default/chapter/34/11/jquery-and-ajax
OK, hope that's enough! Any help would be appreciated!
In web2py, you do not create .py files and then use them as URLs. Instead, you create functions in controllers and have URLs of the form /appname/controller/function. See the documentation on dispatching. It is also best to use the built-in URL() function to generate URLs. Also, this should probably be a GET request rather than POST.
You might also want to look into web2py's built-in ajax() function as well as Ajax components.
Regarding your data model, if the f_item_parent_id field is a self reference, then you should define it as a reference field (i.e., type='reference t_shop_layout_items').
More generally, before proceeding further, it will probably be very helpful if you read more of the documentation, particularly chapters 4, 5, 11, and possibly 12.

Where should I put data like testimonials and addresses in Umbraco?

I am fairly new to Umbraco and I am wondering where I should put pieces of random data.
I have a lot of experience with Sitecore, used it for several years, I am certified etc etc. But now I have to build something with Umbraco. At a first glance Umbraco looks inferior to Sitecore in every way, but I might be wrong about that.
So what I am wondering is, where should I put non-browsable pieces of data that are visible on several places throughout the website? I'd like to create data items in Umbraco for things like Testimonials, Offices? I'd like to have a centralized place in Umbraco where they can be maintained and reference them from a page node. But the way it looks now is that everything has to be on the page node. Which is sort ok, for your average family webpage.
Could someone please shed some light on this?
You could create another node under the man content and call it site settings and store them there that way all pages under the home page are just visible pages on the front end and all data nodes are in a separate area.
There is one property in umbraco that you can add to document types and name it "umbracoNaviHide" (for alias, the name can be anything). This allows wires in automatically to the .IsVisible() method.
var children = Model.Content.Children.Where(x => x.IsVisible());
I find this situation to be very frequent, think of slideshows. When I make an Umbraco website, under my root node I normalle havea Slideshow document type (that contains slides) and I programmatically traverse those to build the slideshow on the home page for example. This Slideshow document has that "umbracoNaviHide" property and I skip it from my menus either using the .IsVisible() method or by manually skipping specific document types.
var menuItems = Model.Content.Children.Where(x => x.DocumentTypeAlias != "Slideshow" && x.DocumentTypeAlias != "Search");
On the other hand, if you are looking for "labels", you can look at "Dictionnary" items under the "Settings" tab.
To directly answer your questions, I reccomend putting non-browsable pieces of data as children of the relevant browsable content node. (But there are other valid ways to do this, it really is up to you and what's best for your content editors.)
Hope this helps.

incorporating all views into one view

Just wondering what the shorthand would be in Rails to do this (if any):
I have views/pages/ containing 5 html.erb files and they all use the same default layout.html.erb, with one yield statement in the middle of it (the standard setup).
Now I want one view that incorporates all 5 of those erb files above contiguously, one after the other, in place of the one existing yield statement in that same layout.html.erb.
What minimal changes would I make to the layout.html.erb to accomplish this.
(Rails Newbie - like it more than Django now).
Ah,
I see what you're saying. Try this. Have your file structure such that all the views for said controller are in one folder...
#controllers_views = Dir.glob("your/controllers/views/*.erb")
#controllers_views.each { |cv| puts cv }
Seems like that would work, I'm away from my dev box or I'd test it for you.
Hope that helps.
Good luck!
You could always have a javascript that requests the sequential yields at a time interval as an ajax request. Then just your target element change to reflect the updated information.
Alternatively load all 5 into different divisions, and have them revolve visibility, like a picture gallery. CSS3 could pull this off.
http://speckyboy.com/2010/06/09/10-pure-css3-image-galleries-and-sliders/

Hpricot CSS Class search

I am working on some code that scrapes a page for two css classes on a page. I am simply using the Hpricot search method for this as so:
webpage.search("body").search("div.first_class | div.second_class")
...for each item found i create an object and put it into an array, this works great except for one thing.
The search will go through the entire html page and add an object into an array every time it comes across '.first_class' and then it will go through the document again looking for '.second_class', resulting in the final array containing all of the searched items in the incorrect order in the array, i.e all of the '.first_class' objects, followed by all the '.second_class' objects.
Is there a way i can get this to search the document in one go and add an object into the array each time it comes across one of the specified classes, giving me an array of items that is in the order they are come across in on the page i am scraping?
Any help much appreciated. Thanks
See the section here on "Checking for a Few Attributes":
http://wiki.github.com/why/hpricot/hpricot-challenge
You should be able to stack the elements in the same way as you do attributes. This feature is apparently possible in Hpricot versions after 2006 Mar 17... An example with elements is:
doc.search("[#href][#type]")
Ok so it turned out i was mistaken and this didn't do anything different to what i previously had at all. However, i have come up with a solution, wether it is the most suitable or not i am not sure. It seems like a fairly straight forward for an annoying problem though.
I now perform the search for the two classes above as i mentioned above:
webpage.search("body").search("[#class~='first_class']|[#class~='second_class']")
However this still returned an array firstly containing all the divs with a class of 'first_class' followed by all divs with a class of 'second_class'. So to fix this and get an array of all the items as they appear in order on the page, i simply chain the 'add_class' method with my own custom class e.g. 'foo_bar'. This then allows me to perform another search on the page for all divs with just this one tag, thus returning an array of all the items i am after, in the order they appear on the page.
webpage.search("body").search("[#class~='first_class']|[#class~='second_class']").add_class("foo_bar")
webpage.search("body").search("[#class~='foo_bar']")
Thanks for the tip. I hadn't spotted that in the documentation and also found another page i hadnt seen either. I have fixed this with the following line:
webpage.search("body").search("[#class~='first_class']|[#class~='second_class']")
This now adds an object into the array each time it comes across one of the above classes in the document. Brilliant!

Resources