this is going to be quick and direct. I'm trying to access different content results from a view related with a content type. I'm pretty much a newbie with twig, but I did make it work to access fields.
Example:
Content Type: Books
Fields: Name, Portrait(Image). Machine Name: field_name - field_image
Let's say I upload 2 contents called Book 1 and Book 2 based on the content type.
What I want is to display all fields from Book 1 for the moment or Book 2 but not all of the content at the same time.
My effort:
First attempt: tried this line of code
<h2>{{view.field.field_name.getvalue(view.result[0])}}</h2>
Works perfectly, it prints index 0 but not working printing the image, because instead it gives me the id.
Second attempt: tried this line of code:
{{fields.field_image.content}}
This one seems to be the most practical, it works showing the actual picture from the field image, but I dont know how to access only the image for one index(Book 1).
Third attempt: tried this line of code
{{content.field_image.0}}
This one doesnt work for me at all.
Hopefully somebody would help me with this. I've been struggling one week with this.
You can turn on Twig debugging, then do a dump to see how things are structured.
https://www.drupal.org/docs/8/theming/twig/discovering-and-inspecting-variables-in-twig-templates
Or perhaps look at the Twig Tweak module that gives a lot of great functions that might suite your needs:
https://www.drupal.org/docs/8/modules/twig-tweak/cheat-sheet-8x-2x
This one in particular might be good since you have the ID in your first example:
{# The argument can be FID, UUID or URI. #}
<dt>Image:</dt>
<dd>{{ drupal_image('public://ocean.jpg') }}</dd>
Related
I'm trying to extract some data from an amazon product page.
What I'm looking for is getting the images from the products. For example:
https://www.amazon.com/gp/product/B072L7PVNQ?pf_rd_p=1581d9f4-062f-453c-b69e-0f3e00ba2652&pf_rd_r=48QP07X56PTH002QVCPM&th=1&psc=1
By using the XPath
//script[contains(., "ImageBlockATF")]/text()
I get the part of the source code that contains the urls, but 2 options pop up in the chrome XPath helper.
By trying things out with XPaths I ended up using this:
//*[contains(#type, "text/javascript") and contains(.,"ImageBlockATF") and not(contains(.,"jQuery"))]
Which gives me exclusively the data I need.
The problem that I'm having is that, for certain products ( it can happen within 2 pairs of different shoes) sometimes I can extract the data and other times nothing comes out. I extract by doing:
imagenesString = response.xpath('//*[contains(#type, "text/javascript") and contains(.,"ImageBlockATF") and not(contains(.,"jQuery"))]').extract()
If I use the chrome xpath helper, the data always appears with the xpath above but in the program itself sometimes it appears, sometimes not. I know sometimes the script that the console reads is different than the one that appears on the site but I'm struggling with this one, because sometimes it works, sometimes it does not. Any ideas on what could be going on?
I think I found your problem: Its a captcha.
Follow these steps to reproduce:
1. run scrapy shell
scrapy shell https://www.amazon.com/gp/product/B072L7PVNQ?pf_rd_p=1581d9f4-062f-453c-b69e-0f3e00ba2652&pf_rd_r=48QP07X56PTH002QVCPM&th=1&psc=1
2. view response like scrapy
view(respone)
When executing this I sometimes got a captcha.
Hope this points you in the right direction.
Cheers
I'm developing a webapp that will need to download the html form a website and then iterate through the code and try to find a specific but ever changing value (in our case it will be the price for the product).
For this, I was thinking about asking the user (upon installation and setup) to provide the system with a few lines of html from the page (that has the price) and then from then on, every time we need to fetch the price we would try to search for those lines and find the price.
Now, I believe this is a horrible and slow way of doing this and since there are no rules and the html can be totally different from one website to another (even the same website might change) I couldn't find a better way.
One improvement that I thought about was to iterate through the first time and record the line at which we find the code. Once found, the subsequent times we would then start from a few lines before the expected location and start the search. Any Thoughts on how I can improve on this?
I posted this question on https://cstheory.stackexchange.com/ but they commented that it's not on topic and that I should post it here.
I have the code for the above and if needed I can post it, I'm simply thinking that there must be a better, faster way of doing this.
This is actually something I tried for a project recently (using BeautifulSoup and Python). The solution that worked for me was to workout CSS selectors (which can map to jQuery selectors) that targeted the elements that contained the values I was looking for. In my case I was able to narrow down the full document to just the elements that contained what I was looking for but if you couldn't get exactly what you where after you could combine this with some extra lactic like test to see if it looks like a price (via regex) or test what it is next to.
<div id="temp_1333021214801">
<input type="text"/>
</div>
$browser.text_field(:xpath,".//*[#id='temp_1333018770709']/input").set("apple")
I am getting error "unable to locate element", because the ID changes dynamically.
Please help me to set the text in the text field.
It seems like your dynamic id is temp_ so this should do it given information above:
browser.div(:id, /temp_\d+/).text_field.set 'something'
Issues with my solution is that it assumes id will always be temp_ regex matching any number set consecutively, which seems to be the case with your sample above. Also, it assumes there is no other div(:id, /temp_\d+/) combination in the DOM of that page, most likely should not be an issue.
If you have dynamic IDs I can suggest the following:
Code to object counts. For example
$browser.text_field(:index => 2)
gives the third text_field on the page.
Code to what is around the thing you're trying to find.
$browser.div(:name => 'mydiv').text_field(:index=>2)
gives the third text field in the div called 'mydiv'.
HOWEVER
If your front-end is less-than-testable in this way I highly suggest you put time into thinking over your commitment to automated testing in the first place. Any minor change to the software is going to have you working until 9pm pulling your hair out and rocking back and forth as you update all your scripts, so unless code maintenance is your weekend hobby think about semi-automation or exploratory testing or manual scripts. Talk to development (whomever that might be. It might be you!) or the higher-ups (unless that's you too) to see if it can be made more testable. Also don't use xpaths unless you take some deviant pleasure in it.
Hope that was helpful, I can't do anything specific without the source HTML.
I know i can use
<mt:EntryAssets lastn="1">
<img src="<$mt:AssetThumbnailURL width="100"$>" />
</mt:EntryAssets>
to show the 'last' asset...how do I show the 'first' or 'oldest' assest?
[I'll point out here that "first" and "oldest" are not necessarily the same question.
You'll see why this is important below. Given the snippet you used, I'm going to assume what you're asking for is first as in position within the entry content. Sorry for length, but this is one of my pet bugs.]
Technically, you can't. That bug(summarized further down if you don't have an Fbz account) has finally been attached to a milestone, so hopefully this won't always be the case.
Practically, reversing the sort order will usually probably output what you expect:
<mt:entryassets limit="1" sort_order="ascend">
...as long as you compose your entries top-to-bottom, and don't later mess with the assets much
The underlying problem is that the current EntryAssets implementation doesn't actually take your content into account. It just loads a list of associated assets and then sorts them by the created_on dates of the assets themselves, not what physical order they appear in or even when they were attached to that particular entry. So as an extreme example, if you insert five images into a post, my snippet above will return the first image, as expected. If you later reverse their order and save, it'll still output that same image, which is now the (ordinal) last one. So, back to what I said at top, you're thinking "first" and MT is always giving you "oldest." And this requires an even further assumption that you're always uploading the assets at time of composition. If one of them was already in the system from say, two years ago, it's going to get returned because it's just older than everything else.
If you're using MT4.3x with the Entry Asset Manager in the sidebar of the composition screen and use it to attach(rather than insert) assets, this is going to get even more complicated, because there's no way to distinguish between assets that were associated with the entry via each manner.
So.
If you absolutely need the returned asset to be predictable, you'll need to actually distinguish it from the group in some way. There's this suggestion to tag the asset with "#first" or something similar. It's not great, but you'll at least know what you're getting(assuming you only tag one asset per entry as such). If you've got custom fields available, you might see if it makes more sense to create a separate "featured/thumbnail image" asset field that it would go into so that you could explicitly test for it. It'll ultimately depend some upon why you're wanting to extract this particular asset.
HI
I am new to Magento and still new to the whole css, php thing. And I have been searching for over a month to find this answer (I am sure it is here some place, but I cannot seem to find it)
I am building a b2b site for a clothing company. Since they are a wholesaler, they do not sell single items, but rather, they sell them in a pack. Depending on the items , some will come in a pack of 2-Small; 2-Medium; 2-Large, other will come in a pack of 1-Small; 2-Medium; 1-Large, and so on.
So far, I set up an attribute called “Package Set”, which describes the kind of pack the customer will be getting when ordering the item, but it only appears in the Additional Information tab, which is not good, because we want that information to stand out. Putting it in the Short Description is an option, but we want to emphasize it more.
So we want to
1. add a text “per pack” right behind the price.
2. add the value of the attribute “Package Set”, right underneath the price, so people will see it clearly, both in the category and product page. It would look some thing like,
“$60 per pack
Package Set: 2-Small; 2-Medium; 2-Large.”
I am using the modern theme
running 1.4.1.1
Thank you
Copy the file "app/code/design/frontend/base/default/template/catalog/product/view/price_clone.phtml" to the directory "app/code/design/frontend/default/modern/template/catalog/product/view/". This is so you are not overwriting the original file.
Open the file for editing. After where you see this:
<?php echo $this->getPriceHtml($_product, false, '_clone') ?>
Add the following:
<?php echo $this->__('per pack') ?>
By using the function $this->__() you are making the text available to be translated easily. It is good practice to do this always.
For the second part now add this bit on the line after:
<p><?php echo $this->__('Package Set %s', $_product->getPackageSet()) ?></p>
Again it is potentially being translated but this time your extra attribute is being inserted where it says %s. The reason for doing this is to make it clearer when using inline translation. The line has been wrapped in a <p> paragraph tag for yet more clarity and to ensure it appears on it's own line, not following on the end of the previous.
I have assumed your attribute has the code "product_set" - which in Magento becomes 'camel case', or getProductSet.
Finally you might want to remove the attribute from Additional Information tab. This is quite simple, go back to the Manage Attributes page in admin, edit your attribute and change "Visible on Product View Page on Front-end" to "No".