Jekyll render partial inside markdown - ruby

We are attempting to move sites to Jekyll, and have a BS4 theme. In order to make it user friendly to the content managers, I've placed the following in my page layout:
<div class="container">
<div class="row">
<div class="col-md-12">
{{ content }}
</div>
</div>
</div>
However, I'd like to create a liquid tag or filter to allow for full-width images to be injected into the middle of the page. This would close the three container divs above the image, write out the image, and the create new divs below, and continue to write the markdown file. i.e.
{% fullwidth xenia-map.png %}
would produce something like this in the middle of the page:
</div>
</div>
</div>
<img src="input.jpg" class="img-responsive" />
<div class="container">
<div class="row">
<div class="col-md-12">
I have been able to create a filter and a tag (class) that will do 80%, however neither will write out closing tags at the beginning of the output. I just get the <img> tag.
Here's my class:
class FullWidth < Liquid::Tag
def initialize(tag_name, image, tokens)
super
#image = image.strip
end
def render(context)
"</div></div></div><img src='uploads/#{#image}' class='img-responsive'>"
end
end
Liquid::Template.register_tag('fw', FullWidth)

Your problem looks like an escaping issue.
Although I like the simplicity of your solution, I would consider two alternatives. The first ('include' solution) because it is easier to implement (anyone can make that one work). The second one ('javascript' solution) because it will allow your content editors to use a regular/graphical markdown editor and it will keep your markdown clean and reusable for other purposes.
'Include' solution
Just put an include in your markdown/html:
{% include fullwidth.html image="/uploads/xenia-map.png" %}
... and use this 'fullwidth.html':
</div>
</div>
</div>
<img src="{{ include.image }}" class="img-responsive" />
<div class="container">
<div class="row">
<div class="col-md-12">
'Javascript' solution
Use this markdown (or let a regular/graphical markdown editor generate this):
![Xenia map](/uploads/xenia-map.png){: .fullwidth}
... and use this jQuery:
$(document).ready(function(){
$('img.fullwidth').each(function() {
var img = $(this).parent().html();
$(this).unwrap();
document.body.innerHTML = document.body.innerHTML.replace(img,
'</div></div></div>'+img+'<div class="container"><div class="row"><div class="col-md-12">');;
});
});

Related

How to perform concatenation in <img> tag in the context of VueJS

I am trying to perform concatenation in img tag and here below is what i am trying to do:
<div class="vx-row">
<div v-for="item in items" class="vx-col" v-bind:key="item.id">
<div class="w-full mb-base">
<vx-card>
...
<img :src="require('./img/stars_' + item.id + '_logo.png')" alt=""/>
...
</vx-card>
</div>
</div>
</div>
I am trying to concatenate the item.id to the image path as i am making my code dynamic such that when the cards are displayed then the respective image is displayed.
Please let me know how it can be done, initially i could see images in respective cards but then i tried using
<img :src="require(`./img/stars_${this.$route.params.item_id}_logo.png`)">
in other components then i get error every where.
Here is the error that i get everywhere:
Here you can try a shorthand that webpack will use.
HTML:
<img :src="getByPath(item.id)" v-bind:alt="item.id">
Method:
getByPath(id) {
return require('./img/stars_' + id + '_logo.png')
}
you can do with method like below code
try this:
<div class="vx-row">
<div v-for="item in items" class="vx-col" v-bind:key="item.id">
<div class="w-full mb-base">
<vx-card>
...
<img :src="getImgUrl(item.id)" alt=""/>
...
</vx-card>
</div>
</div>
</div>
and create method:
getImgUrl(value) {
return `./img/stars_${value}_logo.png`
},

Parsing through response created with XPath

Using Scrapy, I want to extract some data from a HTML well-formed site. With XPath I am able to extract a list of items, but I am not able to extra data from the elements in the list, using XPath
All XPath's have been tested using XPather. I have tested the issue using a local file that contains the webpage, same issue.
Here goes:
# Get the webpage
fetch("https://www.someurl.com")
# The following gives me the expected items from the HTML
products = response.xpath("//*[#id='product-list-146620']/div/div")
The items are like this:
<div data-pageindex="1" data-guid="13157582" class="col ">
<div class="item item-card item-card--static">
<div class="item-card__inner">
<div class="item__image item__image--overlay">
<a href="/www.something.anywhere?ref_gr=9801" class="ratio_custom" style="padding-bottom:100%">
</a>
</div>
<div class="item__text-container">
<div class="item__name">
<a class="item__name-link" href="/c.aspx?ref_gr=9801">The text I want</a>
</div>
</div>
</div>
</div>
</div>
When using the following Xpath to extract "The text I want", i dont get anything:
XPATH_PRODUCT_NAME = "/div/div/div/div/div[contains(#class,'item__name')]/a/text()"
products[0].xpath(XPATH_PRODUCT_NAME).extract()
The output is empty, why?
Try the following code.
XPATH_PRODUCT_NAME = ".//div[#class='item__name']/a[#class='item__name-link']/text()"
products[0].xpath(XPATH_PRODUCT_NAME).extract()

I can't print images with laravel and vue js

I'm getting stuck in an ecommerce development project using Laravel and Vue. I can't make the images appear dynamically in the index view of the product. I'm able to upload and print the images in the show view and these are stored in storage / app / images.
The problem is that the image_url attribute of a product is nullable so it may or may not have an image and the idea is to show them when they have one.
Here is the code of the component ProductCardComponete.vue that is where I develop the code itself.
<template lang="html">
<div class="col-xs-12 col-sm-6 col-md-3">
<div class="card">
<header class="bg-dark padding">
</header>
<div class="justify-content-center">
<!-- <img v-for="product in products" v- if="product.extension" :src="'/productos/images/'+product.id+product.extension">
-->
<img :src="'/productos/images/34.jpeg'" class="card-img-top">
</div>
<div class="card-body padding">
<h2 class="card-title">
<a :href="'/productos/'+product.id">
{{product.title}}
</a>
</h2>
<h4 class="card-subtitle">{{product.humanPrice}}</h4>
<p class="card-text">{{product.description}}</p>
</div>
</div>
</div>
</template>
<script>
export default {
props:{
product: {
type: Object
}
}
}
</script>
Of course, when I put the route in a static way, it works. But I don't know how I could arrive at the solution to show it dynamically and the way of showing the image if the product has one.
Finally here is a link to the github Repo of the project just in case.
Github Repo
Images should be saved in storage/app/public/ and you should make a symlink so that you can access storage folder in public folder. Otherwise you will stuck in accessing images. Read this official doc.

aurelia multiple viewPorts on the same component

Is it possible to use viewPorts with the same component, without it being instantiated twice. E.g.
config.map([
{
route: 'route1',
name: 'route1',
viewPorts: {
default: {moduleId: './route1-module'},
heading: {moduleId: './route1-module', view: './route1-module-heading.html'}
},
nav: true,
title: 'Route1'
}]);
route1-module is been instantiated and attached twice. I need to avoid it.
It sounds like you want to use the layouts feature that will be present in a later release (I'm not sure when but the PR has been merged recently).
The PR is here: https://github.com/aurelia/templating-router/pull/25
Essentially it gives you a chance to specify a view/viewmodel pair (a layout) that will sit in place of the original module when routed to. Instead the original content will be projected into the layout using slots.
Example:
route-config
config.map([
{ layoutView: "layout.html", moduleId: 'page1' }
]);
page1.html
<template>
<div slot="slot1">some content</div>
<div slot="slot2">some other content</div>
</template>
layout.html
<template>
<div class="some-fancy-container">
<p>This is slot 2</p>
<!-- slot2 content will be projected here -->
<slot name="slot2">some fallback content</slot>
</div>
<div class="sidebar">
<p>This is slot 1</p>
<!-- slot1 content will be projected here -->
<slot name="slot1">some fallback content</slot>
</div>
</template>
Resulting HTML output:
<template>
<div class="some-fancy-container">
<p>This is slot 2</p>
some other content
</div>
<div class="sidebar">
<p>This is slot 1</p>
some content
</div>
</template>
This is similar to MVC partials or ASP.NET master pages and allows you to specify an alternative layout for certain pages (without needing child routes).
It's very distinct from viewports (it also works with viewports in that you can specify a layout for a viewport too)

Watir: How to retrieve all HTML elements that match an attribute? (class, id, title, etc)

I have a page that is dynamically created and displays a list of products with their prices. Since it's dynamic, the same code is reused to create each product's information, so they share the tags and same classes. For instance:
<div class="product">
<div class="name">Product A</div>
<div class="details">
<span class="description">Description A goes here...</span>
<span class="price">$ 180.00</span>
</div>
</div>
<div class="product">
<div class="name">Product B</div>
<div class="details">
<span class="description">Description B goes here...</span>
<span class="price">$ 43.50</span>
</div>
</div>`
<div class="product">
<div class="name">Product C</div>
<div class="details">
<span class="description">Description C goes here...</span>
<span class="price">$ 51.85</span>
</div>
</div>
And so on.
What I need to do with Watir is recover all the texts inside the spans with class="price", in this example: $ 180.00, $43.50 and $51.85.
I've been playing around with something like this:
#browser.span(:class, 'price').each do |row| but is not working.
I'm just starting to use loops in Watir. Your help is appreciated. Thank you!
You can use pluralized methods for retrieving collections - use spans instead of span:
#browser.spans(:class => "price")
This retrieves a span collection object which behaves in similar to the Ruby arrays so you can use Ruby #each like you tried, but i would use #map instead for this situation:
texts = #browser.spans(:class => "price").map do |span|
span.text
end
puts texts
I would use the Symbol#to_proc trick to shorten that code even more:
texts = #browser.spans(:class => "price").map &:text
puts texts

Resources