I am trying to upload images to a blog using carrier wave. on the blog, I want all of the images to fit in the same size box, regardless of the size of the photo. I want all of them to be 450x253. Here is my code:
Uploader file for carrier wave:
class PhotoUploader < CarrierWave::Uploader::Base
include CarrierWave::MiniMagick
include Sprockets::Rails::Helper
storage :fog
def store_dir
"uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}"
end
process :resize_to_fill => [450, 253]
# Create different versions of files:
version :thumbnail do
process :resize_to_fill => [200, 112]
end
version :profile_size do
process :resize_to_fill => [450, 253]
end
version :full_size do
process :resize_to_fill => [568, 320]
end
def extension_white_list
%w(jpg jpeg gif png)
end
end
And my index.html.erb file:
<div class="row">
<% #articles.each do |article| %>
<div class="col-md-6">
<div class="well well-lg">
<p><%= image_tag(article.image.url) %>
<div class="body">
<div class="text-center">
<%= article.description %>
</div>
<div class="row">
<div class="col-xs-3">
<button class="btn btn-primary btn-lg" type="submit">Button</button>
</div>
<div class="col-xs-9">
<button class="btn btn-default btn-lg pull-right" type="submit">Button</button>
</div>
</div>
</div>
</div>
</div>
<% end %>
<div class="col-md-6 col-sm-6">
</div>
</div>
At this line:
<%= image_tag(article.image.url) %>
I have also tried:
<%= image_tag(article.image.profile_size.url) %>
since my uploader file says the profile_size should render 450x253, but that still doesn't work. With my current code, the size of the photo as it displays on the page is just the same size of whatever it is that I upload, it doesn't resize at all, for example:
I want them all to be the same size of the one on the left in the photo, but auto resized to that (the one in the photo is naturally that size), how can I do that? I already tried looking here: http://www.rubydoc.info/github/jnicklas/carrierwave/CarrierWave/MiniMagick
and here: Carrierwave - Resizing images to fixed width
thanks
Use resize_to_fit or resize_to_limit instead of resize_to_fill
process :resize_to_limit => [450, 253]
or
process :resize_to_fit => [450, 253]
Related
I was trying to scrape this site when I was running into errors due to tags that I thought existed, but did not exist in the scraped html from Bs4.
Site: https://en.thejypshop.com/category/cdlp/59/
I manually verified that the parsed output from Bs4 was giving me a completely different view of the html than when I inspected the site itself; here is a comparison of the two (copied relevant html in the two pastebin links). I also tried scraping with different parsing options such as 'lxml', 'html.parser', etc. but to no avail.
(Bs4 Output): https://pastebin.com/tg4P5DFh
<div class="thumbnail">
<div class="prdImg">
<a href="/product/stray-kids-mini-album-maxident-case-ver/842/category/59/display/2/" name="anchorBoxName_842">
<img alt="" id="eListPrdImage842_2" src="https://cafe24img.poxo.com/jyp3602022/web/product/medium/202210/ca01b08c39232296f482b657be53aa4b.jpg" />
</a>
<span class="wish">
<img alt="Before add to wish list" categoryno="59" class="icon_img ec-product-listwishicon" icon_status="off" individual-set="F" login_status="F" productno="842" src="/web/upload/icon_202204271744355800.png" />
</span>
</div>
<div class="icon">
<div class="promotion"></div>
<div class="button">
<div class="option"></div>
<img alt="Add to cart" class="ec-admin-icon cart" onclick="category_add_basket('842','59', '2', 'A0000', false, '1', 'P0000BGK', 'B', 'T', '20');" src="/web/upload/icon_202204271744303700.png" />
<img alt="View larger image" onclick="zoom('842', '59', '2','', '');" src="//img.echosting.cafe24.com/design/skin/admin/en_US/btn_prd_zoom.gif" style="cursor:pointer" />
</div>
</div>
</div>
(html from Site): https://pastebin.com/2xfi4XTA
<div class="thumbnail">
<div class="prdImg">
<a href="/product/stray-kids-mini-album-maxident-case-ver/842/category/59/display/1/">
<img src="https://cafe24img.poxo.com/jyp3602022/web/product/medium/202210/ca01b08c39232296f482b657be53aa4b.jpg" id="eListPrdImage842_1" alt="">
</a>
</div>
<span class="pro_icon">
<img src="/web/upload/icon_202204271744355800.png" class="icon_img ec-product-listwishicon" alt="Before add to wish list" productno="842" categoryno="59" icon_status="off" login_status="F" individual-set="F">
<img src="/web/upload/icon_202204271744303700.png" onclick="category_add_basket('842','59', '1', 'A0000', false, '1', 'P0000BGK', 'B', 'T', '20');" alt="Add to cart" class="ec-admin-icon cart">
</span>
<span class="soldout_icon"></span>
</div>
Note that the <span class="soldout_icon"></span> tag does not appear in what Bs4 sees, among other things.
My guess as to why this is the case;
I am not using a headless browser, so some websites such as this one might not display the same thing.
There is some JS running in the background that Bs4 does not pick up on
Please let me know if any of my guesses are incorrect and what is actually going on!
Yes, you are right as
the second page is beeing built dynamicaly so you can't get the real html with bs4. Try to use combination of selenium and bs4 to get what you need. Here is a small script that finds some hidden divs and print them out. You should get deeper insight and simulate web surfing to catch the html when the page is fully developed. This one below is still in the process of construction.
import time
from bs4 import BeautifulSoup
from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--ignore-certificate-errors')
options.add_argument('--incognito')
options.add_argument('--headless')
driver = webdriver.Chrome(options = options)
urls = ['https://en.thejypshop.com/category/cdlp/59/', 'https://pastebin.com/2xfi4XTA']
for url in urls:
data = driver.get(url)
time.sleep(1)
pg_html = driver.page_source
pg_html = pg_html.replace('<', '<').replace('>', '>')
soup = BeautifulSoup(pg_html, 'html.parser')
dv = soup.find_all('div', attrs={'class': 'thumbnail'})
dv1 = soup.find_all('span', attrs={'class': 'soldout_icon'})
try:
print(60 * '-')
print(dv[0])
except:
pass
print(60 * '-')
try:
print(dv1[0])
print(60 * '-')
except:
pass
''' R e s u l t :
------------------------------------------------------------
<div class="thumbnail">
<div class="prdImg">
<img alt="" id="eListPrdImage842_2" src="https://cafe24img.poxo.com/jyp3602022/web/product/medium/202210/ca01b08c39232296f482b657be53aa4b.jpg"/>
<span class="wish"><img alt="Before add to wish list" categoryno="59" class="icon_img ec-product-listwishicon" icon_status="off" individual-set="F" login_status="F" productno="842" src="/web/upload/icon_202204271744355800.png"/></span>
</div>
<div class="icon">
<div class="promotion"> </div>
<div class="button">
<div class="option"></div> <img alt="Add to cart" class="ec-admin-icon cart" onclick="category_add_basket('842','59', '2', 'A0000', false, '1', 'P0000BGK', 'B', 'T', '20');" src="/web/upload/icon_202204271744303700.png"/> <img alt="View larger image" onclick="zoom('842', '59', '2','', '');" src="//img.echosting.cafe24.com/design/skin/admin/en_US/btn_prd_zoom.gif" style="cursor:pointer"/> </div>
</div>
</div>
------------------------------------------------------------
<span class="soldout_icon"></span>
------------------------------------------------------------
------------------------------------------------------------
<div class="thumbnail">
</div>
------------------------------------------------------------
<span class="soldout_icon"></span>
------------------------------------------------------------
'''
Regards...
Screenshot of Page I am trying to recreate a pc part picker type of application using bootstrap and express. When trying to display all the cases available on "my" website, I am loading all of the cases from my database in an ejs file and then displaying them in a thumbnail with four in each row. I have used flexboxes on every four elements to make the heights for all thumbnails in one row the same, however it only works on the first row and does not work after. I have tried to add the code underneath, however this is my first time asking a question so if you have any suggestions to make it more readable please do let me know. I have also included the link to the picture of the page at the beginning of the paragraph.
<% var start = 0 %>
<% cases.forEach(function(qcase) { %>
<% if (start % 4 == 0) { %>
<div class="row text-center display-flex">
<% }; %>
<div class="col-md-3 col-md-6">
<div class="thumbnail">
<img src="<%=qcase.image%>">
<div class="caption">
<h4><%=qcase.name%></h4>
</div>
<div>
More Information
</div>
</div>
</div>
<% if (start % 4 == 3) { %>
</div>
<% }; %>
<% start += 1 %>
<% }); %>
I need to make reactive a class inside a const (exported from a module).
export const messageControls = '
<div id="controls"">
<i id="idcont" class="{{starred}}"></i>
</div>
'
This class belongs to an HTML block who's inserted as innerHTML of a createElement.
var newElement = document.createElement('div');
newElement.id = i._id;
newElement.className = "single_message";
newElement.innerHTML = messageControls;
document.getElementById('conversation_details').appendChild(newElement);
The {{helper}} below is not rendering anything :
starred: function () {
return 'bob';
},
<i id="idcont" class="{{starred}}"></i> gives {{starred}} in plain text
<i id="idcont" class=" ' + {{starred}} + ' "></i> breaks all
Any idea?
Update - full Blaze template as requested
<template name="inbox">
<div class="searchmessages">
<input type="text" name="searchmessages" id="searchmessages" placeholder=" any word / any date">
</div>
<div class="row">
<div class="col-xs-4 l-O list_messages">
<div id="gridreceived" class="gridmessages">
{{#each incoming_all}}
<div id="{{_id}}" class="item {{readornot}}">
<div class="item-content">
<div class="task_inlist">
<div class="task_from">
{{{from}}}
</div>
<div class="task_date">
{{initialdate}}
</div>
<div class="task_subject">
{{{subject}}}
</div>
<div class="task_content">
{{{htmlbody}}}
</div>
</div>
</div>
</div>
{{/each}}
</div>
<div class="grid_nomatch">{{grid_noresult}}</div>
</div>
<div id="conversation_details" class="col-xs-8" media="print">
<!--
here are each selected message details
-->
</div>
</div>
</template>
You're trying to inject spacebars template markup directly into the DOM but meteor-blaze wants to use spacebars to build the DOM. It doesn't watch the DOM for arbitrary changes and then make template substitutions inside of it!
You can instead use Meteor's reactivity to automatically insert new items into the DOM for you based on changes to the underlying data. In your case it looks like you're trying to show the details of a message that's been clicked on. You probably have a template event handler already to catch the click. In that template handler you can set a Session variable which indicates which message is currently selected and then use that Session variable inside the helper that renders the message details.
For example:
<template name="inbox">
<div class="searchmessages">
<input type="text" name="searchmessages" id="searchmessages" placeholder=" any word / any date">
</div>
<div class="row">
<div class="col-xs-4 l-O list_messages">
<div id="gridreceived" class="gridmessages">
{{#each incoming_all}}
<div id="{{_id}}" class="item {{readornot}}">
// render summary of each message
</div>
{{/each}}
</div>
<div class="grid_nomatch">{{grid_noresult}}</div>
{{#with selectedMessage}}
<div id="conversation_details" class="col-xs-8" media="print">
// render selected message details
</div>
{{/with}}
</div>
</template>
Your js:
Template.inbox.events({
'click .item'(ev) {
Session.set('selectedMessageId',this._id);
}
});
Template.inbox.helpers({
selectedMessage() {
return Messages.findOne(Session.get('selectedMessageId'));
}
});
Now to your follow-up question about how to reactively style an element. Let's say your message* object has aisStarredboolean key. In the message detail section we've set the data context using{{#with currentMessage}}` so any key of the current message can be used directly in our spacebars template. Where you are displaying the message details you can do:
<div id="controls"">
<i id="idcont" class="{{#if isStarred}}starred{{/if}}"></i>
</div>
Depending on whether or not the message is starred this will render as class="" or class="starred".
I have the following code in my View.
#model MovieApp.Models.HomeIndexViewModel
#foreach (var item in Model.Movies)
{
<div class="container">
<div class="row">
<div class="col-xs-4">
<img src=item.posterPath id="picture1" class="img-responsive" />
</div>
</div>
</div>
}
I retrieve the image Url's on item.Posterpath as a string.
When I try to add my Url's on item.PosterPath as <img src=item.posterPath id="picture1" class="img-responsive"/>I can see that the item is not in scope.
My question is how i should iterate over my Model to stay in the scope and retrieve my paths?
have you tried src="#item.posterPath" ?
I am currently working my way through Michael Hartl's Rails Tutorial, and have been unable to make an rspec test work when he is saying it should. These are the tests right after listing 8.10. This is in the sign-in sign out chapter, and the troublesome authentication tests is as follows:
require 'spec_helper'
describe "Authentication" do
subject { page }
describe "signin" do
before { visit signin_path }
describe "with invalid information" do
before { click_button "Sign in" }
it { should have_selector('title', text: 'Sign in') }
it { should have_selector('div.alert.alert-error', text: 'Invalid') }
#describe "after visiting another page" do
# before { click_link "Home" }
# it { should_not have_selector('div.alert.alert-error') }
#end
end
end
I believe the two describe signin tests should be passing, but the "it { should have_selector('div.alert.alert-error', text: 'Invalid') }" test is currently showing:
Failure/Error: it { should have_selector('div.alert.alert-error', text: 'Invalid') }
expected css "div.alert.alert-error" with text "Invalid" to return something
# ./spec/requests/authentication_pages_spec.rb:21:in `block (4 levels) in <top (required)>'
My sessions controller is as follows:
class SessionsController < ApplicationController
def new
end
def create
user = User.find_by_email(params[:session][:email])
if user && user.authenticate(params[:session][:password])
#I haven't gotten to this tutorial part yet
else
flash.now[:error] = "Invalid email/password combination"
render 'new'
end
end
def destroy
end
end
When I test this with the built in Rails server, the browser source code contains:
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<header class="navbar navbar-fixed-top navbar-inverse">
<div class="navbar-inner">
<div class="container">
sample app
<nav>
<ul class="nav pull-right">
<li>Home</li>
<li>Help</li>
<li>Sign in</li>
</ul>
</nav>
</div>
</div>
</header>
<div class="container">
<div class="alert alert -error">Invalid email/password combination</div>
<h1>Sign in</h1>
<div class="row">
<div class="span6 offset3">
<form accept-charset="UTF-8" action="/sessions" method="post"><div style="margin:0;padding:0;display:inline"><input name="utf8" type="hidden" value="✓" /><input name="authenticity_token" type="hidden" value="Gh9r4Qf0R00A31u69ETFKeAt57nj6Qqai5iuBISWOWE=" /></div>
<label for="session_email">Email</label>
<input id="session_email" name="session[email]" size="30" type="text" />
<label for="session_password">Password</label>
<input id="session_password" name="session[password]" size="30" type="password" />
<input class="btn btn-large btn-primary" name="commit" type="submit" value="Sign in" />
</form>
I think, for my purposes, the critical line here is:
<div class="container">
<div class="alert alert -error">Invalid email/password combination</div>
<h1>Sign in</h1>
What I think should be happening is that my test is visiting this page, and should be seeing that an alert alert -error division (with acceptable text) exists in the produced html, and pass the test. I understand that this is not happening, but one question I do have is whether my high level understanding of this process is correct.
I have been looking around stackoverflow for other tutorial questions. While there are some similar questions, I have not been able to use them to answer my question, and so I am asking this question, because I think this qualifies as a new question. I did see that the tutorial questions gave a lot of files, and I am just trying to post the relavent files here. However, here is my current routes.rb file
SampleApp::Application.routes.draw do
resources :users
resources :sessions, only: [:new, :create, :destroy]
root to: 'static_pages#home'
match '/signup', to: 'users#new'
match '/signin', to: 'sessions#new'
match '/signout', to: 'sessions#destroy', via: :delete
match '/help', to: 'static_pages#help'
match '/about', to: 'static_pages#about'
match '/contact', to: 'static_pages#contact'
end
And here is my current new.html.erb file, which has file path in ~/rails_projects/sample_app/app/views/sessions/new.html.erb
<% provide(:title, "Sign in") %>
<h1>Sign in</h1>
<div class="row">
<div class="span6 offset3">
<%= form_for(:session, url: sessions_path) do |f| %>
<%= f.label :email %>
<%= f.text_field :email %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit "Sign in", class: "btn btn-large btn-primary" %>
<% end %>
<p>New user? <%= link_to "Sign up now!", signup_path %></p>
</div>
</div>
I plan on moving on with the tutorial, because it seems like the functionality is unhindered. However, I fear that later my lack of understanding in these tests will seriously mess things up. It would be great if someone has had a similar problem cold help point me towards a solution.
Thanks in advance!
Inspect from your web page source code:
<div class="alert alert -error">Invalid email/password combination</div>
The target div has class alert and -error. However, in your testcase, you are expecting a div with class alert and alert-error
it { should have_selector('div.alert.alert-error', text: 'Invalid') }
I think you have typed an extra space between alert and -error, it should be alert-error (without space).
You should check your layout view, because sessions/new.html.erb you pasted doesn't include the source that generates this line of HTML.
UPDATE: As commented by Dylan Markow, you might have typed an extra space in <div class="alert alert-<%= key %>">.