I am using Browsershot, which is based on Puppeteer to create PDF from HTML. The HTML-source is rendered Laravel-Blade.
This is my blade-template that is being rendered:
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width,initial-scale=1.0" name="viewport">
<!-- Styles -->
<link href="{{ asset(mix('/css/app.css')) }}" rel="stylesheet">
<body>
<div class="relative h-screen">
#include('pdf.partials.header')
<div class="absolute inset-x-0 bottom-0">
#include('pdf.partials.footer')
</div>
</div>
</body>
</html>
app.css contains #font-faces like:
/* lato-100 - latin */
#font-face {
font-family: 'Lato';
font-style: normal;
font-weight: 100;
src: local('Lato Hairline'), local('Lato-Hairline'),
url('../fonts/lato-v16-latin-100.woff2') format('woff2'), /* Super Modern Browsers */ url('../fonts/lato-v16-latin-100.woff') format('woff'), /* Modern Browsers */ url('../fonts/lato-v16-latin-100.ttf') format('truetype'), /* Safari, Android, iOS */ url('../fonts/lato-v16-latin-100.svg#Lato') format('svg'); /* Legacy iOS */
font-display: swap;
}
/* lato-100italic - latin */
#font-face {
font-family: 'Lato';
font-style: italic;
font-weight: 100;
src: local('Lato Hairline Italic'), local('Lato-HairlineItalic'),
url('../fonts/lato-v16-latin-100italic.woff2') format('woff2'), /* Super Modern Browsers */ url('../fonts/lato-v16-latin-100italic.woff') format('woff'), /* Modern Browsers */ url('../fonts/lato-v16-latin-100italic.ttf') format('truetype'), /* Safari, Android, iOS */ url('../fonts/lato-v16-latin-100italic.svg#Lato') format('svg'); /* Legacy iOS */
font-display: swap;
}
Now if I try to create a pdf, those fonts are not loaded correctly.
If I trace that down using:
$view = view('pdf', compact('data'));
$body_html = $view->render();
$requests = \Spatie\Browsershot\Browsershot::html($body_html)->format('A4')
->margins(8, 22, 8, 22)->showBackground()->addChromiumArguments([
'font-render-hinting' => 'none',
])->waitUntilNetworkIdle()->ignoreHttpsErrors()
->triggeredRequests();
dump($requests);
I see those requests:
4 => array:1 [
"url" => "http://example.test/fonts/lato-v16-latin-300.woff2?98d8cf792834c0bef59c2be99dc3533d"
]
I am able to open this path using my browser and the virtual machine Laravel lives in, is able to do so, too:
root#example:~# http://example.test/fonts/ibm-plex-mono-v5-latin-200.woff2?4b65d6136cfc2097c4a2103960f00a2c
Resolving example.test (example.test)... 127.0.0.1, 127.0.1.1
Connecting to example.test (example.test)|127.0.0.1|:80... connected.
HTTP request sent, awaiting response... 200 OK
But the fonts are still not applied.
Now if I simply use Google fonts like this
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8">
<meta content="IE=edge" http-equiv="X-UA-Compatible">
<meta content="width=device-width,initial-scale=1.0" name="viewport">
<!-- Styles -->
<link href="{{ asset(mix('/css/app.css')) }}" rel="stylesheet">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:ital,wght#0,100;0,200;0,300;0,400;0,500;0,600;0,700;1,100;1,200;1,300;1,400;1,500;1,600;1,700&family=Lato:ital,wght#0,100;0,300;0,400;0,700;0,900;1,100;1,300;1,400;1,700;1,900&display=swap" rel="stylesheet"></head>
<body>
<div class="relative h-screen">
#include('pdf.partials.header')
<div class="absolute inset-x-0 bottom-0">
#include('pdf.partials.footer')
</div>
</div>
</body>
</html>
it works just fine.
So what did I do wrong?
We had success using this tool to get the base64 version of the google font we were trying to use locally. Embedding the font as base64 right in the CSS allowed us to get around this issue.
Related
To be honest, I'm having trouble understanding the concept of Laravel how to build in and use its assets (css, js). I guess I'm using a wrong but still working way even for production.
My approach for Production
import { defineConfig } from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
'resources/css/app.css',
'resources/js/app.js',
],
refresh: true,
}),
],
});
Step 1: npm run build
Step 2: Manually copy the newly generated js and css files into my public folder.
Step 3: Change the file names in my bladetemplate. So app.11111.js to app.js
Note: This doesn't feel right but it worked for Production. I would be very grateful for any hints on this.
Here is my layout.blade.php file
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="stylesheet" href="https://fonts.bunny.net/css2?family=Nunito:wght#400;600;700&display=swap">
<link rel="stylesheet" href="{{ asset('assets/css/main.css') }}">
<!-- Scripts -->
#vite(['resources/css/app.css', 'resources/js/app.js'])
</head>
<body class="font-sans antialiased">
<div class="min-h-screen bg-gray-100" style="min-height: 100vh; display:flex; flex-direction:column;">
#include('layouts.navigation')
<!-- Page Content -->
<main>
#yield('content')
</main>
#include('templateparts.footer')
</div>
<script src="{{ asset('assets/js/app.js') }}"></script>
</body>
</html>
Having an issue getting an image to move can someone give me some assistance? the web page is carymcclure.com trying to get the mail slot to move to the right of the door.
here is the html code:
body {
width:40%;
background-image: url("../img/background.gif");
background-repeat: no-repeat;
}
</style>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Welcome to Cary McClures' Portfolio</title>
<!-- Bootstrap -->
<link href="../css/bootstrap-4.4.1.css" rel="stylesheet">
</head>
<body background="../img/background.gif" class="embed-responsive">
<a href="mailto:chef#carymcclure.com">
<img
style="float:right; margin-left:1000px; margin-top:350px"
src="../img/slot.gif"
width="216"
height="89"
alt="email" />
</a>
<a href="library.html">
<img
style="position:absolute; left:542px"
src="../img/door.gif" width="850" height="1049" alt="door"/>
</a>
thanks
Well, If you just want to show the button to the right on the door. Then the following inline CSS code will work for you on the of the button.
<a href="mailto:chef#carymcclure.com" style="position: absolute;right: 100px;z-index: 100;">
<img style="float:right;margin-right:105px;margin-top:350px;position: relative;" src="../img/slot.gif" width="216" height="89" alt="email">
</a>
I have been working through a yt tutorial on Web Components by Brad Traversy, a great teacher with great content, as I'm sure many of you already know :)
I've gotten up to the 17 minute mark, though the problem I'm having is that the images are not displaying as they are in the tutorial...
They are being added to the document flow... I can tell this because the layout re-adjusts to accommodate the space for an image... it's just that the image is not displayed...
Just for comparison, I added a image of a similar nature directly in the html and it works fine.
Anyway, here is my code...
index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Components Example</title>
<style>
h3 {
color: purple;
}
</style>
</head>
<body>
<h3>Hello World... where's the images?!?!?</h3>
<!-- <user-card name="you oddo" avatar="https://randomuser.me/api/portraits/men/1.jpg"></user-card> -->
<user-card name="huik popp" avatar="38.jpg"></user-card>
<user-card name="som otha"></user-card>
<img src="95.jpg">
<style>h3 {color: green}</style>
<script src="userCard.js"></script>
</body>
</html>
and the Javascript...
UserCard.js:
const template = document.createElement('template');
template.innerHTML = `
<style>
h3 {
color: coral;
}
</style>
<div class="user-card">
<img />
<div>
<h3></h3>
</div>
</div>
`;
class UserCard extends HTMLElement {
constructor() {
super();
this.attachShadow({ mode: 'open'});
this.shadowRoot.appendChild(template.content.cloneNode(true));
this.shadowRoot.querySelector('h3').innerText = this.getAttribute('name');
this.shadowRoot.querySelector('img').innerText = this.getAttribute('avatar');
}
}
window.customElements.define('user-card', UserCard);
I'd appreciate any help with this very much. I've been enjoying following along with this tutorial so far and well, would like to keep up with how things look in the video.
Many thanks.
I'm answering my question here...
In userCard.js, I have:
this.shadowRoot.querySelector('img').innerText = this.getAttribute('avatar');
It should be:
this.shadowRoot.querySelector('img').src = this.getAttribute('avatar');
Tell Brad he can shorten the code to:
class UserCard extends HTMLElement {
constructor() {
super()
.attachShadow({ mode: 'open'})
.innerHTML = `
<style>
h3 {
color: coral;
}
</style>
<div class="user-card">
<img />
<div>
<h3></h3>
</div>
</div>
`;
...
}
);
I have the unfortunate task of making Bourbon Neat work with ie8. Thoughtbot's docs say you use Selectivizr for this. I followed Selectivizr's instructions and I see nothing different when testing in ie8. I also don't understand what if any fallback css is required. Any ideas or solutions? Most appreciated!
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" />
<meta name="description" content="">
<!-- FONTS -->
<!--Typekit - Adrianna Extended Demibold-->
<script type="text/javascript" src="//use.typekit.net/sjw4zgk.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>
<!-- AUTO RELOAD FOR HAMMER -->
<!-- Hammer reload -->
<script>
setInterval(function(){
try {
if(typeof ws != 'undefined' && ws.readyState == 1){return true;}
ws = new WebSocket('ws://'+(location.host || 'localhost').split(':')[0]+':35353')
ws.onopen = function(){ws.onclose = function(){document.location.reload()}}
ws.onmessage = function(){
var links = document.getElementsByTagName('link');
for (var i = 0; i < links.length;i++) {
var link = links[i];
if (link.rel === 'stylesheet' && !link.href.match(/typekit/)) {
href = link.href.replace(/((&|\?)hammer=)[^&]+/,'');
link.href = href + (href.indexOf('?')>=0?'&':'?') + 'hammer='+(new Date().valueOf());
}
}
}
}catch(e){}
}, 1000)
</script>
<!-- /Hammer reload -->
<!-- CSS/SCSS -->
<link rel='stylesheet' href='css/ostrich-sans.css'>
<link rel='stylesheet' href='css/font-awesome.css'>
<link rel='stylesheet' href='css/normalize.css'>
<link rel='stylesheet' href='css/responsive-nav.css'>
<link rel='stylesheet' href='css/style.css'>
<!-- IOS LINK STYLES -->
<style type="text/css">
/*.applelinks a {color:#c4d52d; display:inline-block; padding: 10px 0;}*/
/*Disable touch-highlight
-webkit-tap-highlight-color: rgba(0,0,0,0); */
</style>
<!-- JS MODERNIZR -->
<script src='js/modernizr.custom.87213.js'></script>
<link href="favicon.ico" rel="shortcut icon">
<link href="apple-touch-icon.png" rel="apple-touch-icon">
<title>Title</title>
<!-- ZEPTO FALLBACK TO JQUERY -->
<script>
document.write('<script src=' +
('__proto__' in {} ? 'js/zepto.min' : 'js/jquery.min') +
'.js><\/script>')
</script>
<!--[if lte IE 8]>
<script type="text/javascript" src="selectivizr.js"></script>
<![endif]-->
</head>
<body>
<header>
<nav class="nav-collapse">
<ul>
<li>Home</li>
<li>About</li>
<li>Projects</li>
<li>Contact</li>
</ul>
</nav>
</header>
<section class="sec-one">
<aside>Aside</aside>
<article>Article</article>
</section>
<section class="sec-two">
<aside>Aside</aside>
<article>Article</article>
</section>
<section class="sec-three">
<aside>Aside</aside>
<article>Article</article>
<p>Content copy</p>
</section>
<script src='js/responsive-nav.js'></script>
<script src='js/app.js'></script>
<!-- INITIATE RESONSIVE-NAV -->
<script>
var navigation = responsiveNav(".nav-collapse", {
label: '<i class=\"icon-reorder icon-2x\"></i>'
});
</script>
</body>
</html>
selectivizr.js is dependent on jquery (or similar libraries). Make sure that you're loading jquery BEFORE selectivizr...
<!--[if lte IE 8]>
**<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>**
<script type="text/javascript" src="selectivizr.js"></script>
<![endif]-->
Have you tried including HTML5 shiv?
Without that (or similar), IE8 won't be able to style elements that are new to HTML5 (eg. <section>, <nav>, etc). For me, selectivizr.js does indeed allow Neat to work with IE8, but if you're using HTML5 elements then even with selectivizr Neat won't be able to style them in IE8 without the HTML5 shiv. (nb. that's not actually a problem with Neat per se - it's a more general problem that stems from IE8 being a pre-HTML5 browser).
Effectively, selectivizr.js fixes the problems with selectors that IE8 doesn't recognise, while HTML5 shiv fixes the problems with unrecognised elements: if you're using HTML5 elements then in order to get everything working smoothly, you'll probably need both.
IE is a mystery to me. My web app is working on Safari, Firefox, Chrome, even iPhones and iPads, but when it comes to IE, I simply can't comprehend how hard it is to comply to the given standards. Anyway enough ranting.
My Twitter bootstrap buttons are completely ignored in IE8. Absolutely nothing happens when I click on any button. I couldnt find anything on google, has anyone come across this?
Many Thanks,
#Kave You uploaded only plain html to jsfiddle - which includes links to js which doesn't exists (so its kind of hard to debug when js is not attached)..
Try using a href instead of so many buttons.. twitter bootsrap supports styling of links to look like buttons, example is at first page of twitter bootstrap like this: (source copied & bit of modified):
<a class="btn btn-success btn-large" href="http://twitter.github.com/bootstrap/base-css.html">Example link with button styles</a>
Edit: Alternatively, full example with twitter bootstrap (modified from demo templates - link with button styles inside a hero unit) - copy & paste to file, save as testing.html and open with browser - enjoy!
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bootstrap, from Twitter</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="description" content="">
<meta name="author" content="">
<!-- Le styles -->
<link href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css" rel="stylesheet">
<style type="text/css">
body {
padding-top: 60px;
padding-bottom: 40px;
}
</style>
<link href="http://getbootstrap.com/2.3.2/assets/css/bootstrap-responsive.css" rel="stylesheet">
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<!-- Le fav and touch icons -->
<link rel="shortcut icon" href="http://getbootstrap.com/2.3.2/assets/ico/favicon.ico">
<link rel="apple-touch-icon-precomposed" sizes="144x144" href="http://getbootstrap.com/2.3.2/assets/ico/apple-touch-icon-144-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="http://getbootstrap.com/2.3.2/assets/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="http://getbootstrap.com/2.3.2/assets/ico/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="http://getbootstrap.com/2.3.2/assets/ico/apple-touch-icon-57-precomposed.png">
</head>
<body>
<div class="container-fluid">
<div class="row-fluid">
<div class="span12">
<div class="hero-unit">
<h1>Hello, world!</h1>
<p>This is a template for a simple marketing or informational website. It includes a large callout called the hero unit and three supporting pieces of content. Use it as a starting point to create something more unique.</p>
<p><a class="btn btn-success btn-large" onclick="alert('its working :)')">Learn more »</a></p>
</div>
</div>
</div>
<hr>
<footer>
<p>© Company 2012</p>
</footer>
</div><!--/.fluid-container-->
<!-- Le javascript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="http://getbootstrap.com/2.3.2/assets/js/jquery.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-transition.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-alert.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-modal.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-dropdown.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-scrollspy.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-tab.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-tooltip.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-popover.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-button.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-collapse.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-carousel.js"></script>
<script src="http://getbootstrap.com/2.3.2/assets/js/bootstrap-typeahead.js"></script>
</body>
</html>
IF still not working, make sure when you restart IE that you click "Allow blocked content" if pop-up for asking it is shown.
Allow blocked content referes to javascript content,the buttons are purelly CSS code,the problem is that IE 6....8 don't have a very good support for CSS3.
If you look on the getbootstrao.com website you dont see them using their own buttons :))
the best solution is create buttons using simple CSS,if someone using IE is browsing your website they might not see the border-radius effect but they will find actual square but working buttons.
I had the same problem and solved it using this jQuery/js:
<a href="http://www.example.com">
<button class="btn"><span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Button text</button>
</a>
<!--[if lt IE 9]>
<script>
$(".btn").click(function() {
var t = $(this).parent();
window.location.href = t.attr("href");
});
</script>
<!--[if lt IE 9]>