how to export variables from svelte:head to the html section? - html

Rationale
I'm making a small website using svelte and sveltekit, and a library (roslibjs) that seems to be only usable within <head>.
It worked only in those 2 types of scenarios for me:
put everything in <head> and output to the console
import the library in <head>, but only by using <script src='https link here'></script>.
Everything else goes into onMount, outside of <head>.
1 is not acceptable, and while 2 is a temporary fix, I really don't want to rely on external links. (the site might be used in an offline environment)
What I tried
Since if I have all the code relying on the library inside <head> it works just fine, I tried to do so. But so long I couldn't find a way to export variables from <head>.
Example:
<svelte:head>
<script>
let a = 10
</script>
</svelte:head>
<p>{a}</p>
This throws an error saying 'a' is not defined.
Change the import line to <script src="node_modules/roslib/build/roslib.js"></script>, directly from the node_modules folder.
While this works in npm run dev, it doesn't once after npm run build.
What I expect
To be able to use the library with svelte3, but by using it from npm, not an external link.
One way to tackle this might be to export variables from <head>, but I couldn't find a way to do so.

Related

How to use requirejs on your client side code

So recently I was making a website and I added a login page. I wanted to check if the username and password entered existed in the database and if not it would give an alert saying invalid username or password. My code is:
<form>
<label>Enter Username:</label>
<input type="text" id="username">
<br>
<label>Enter Password:</label>
<input type="password" id="password">
<br>
<input type="submit" onclick="submitLoginInfo()">
</form>
and the js is
const { LoginSchemaModel } = require('./dbconfig.js')
// import { LoginSchemaModel } from './dbconfig'
requirejs()
function submitLoginInfo () {
let usernameElement = document.querySelector('#username')
let passwordElement = document.querySelector('#password')
console.log(`Username Element is HTMLElement: ${usernameElement instanceof HTMLElement}`);
console.log(`Username Element is HTMLElement: ${passwordElement instanceof HTMLElement}`);
alert(`usernameElement = ${usernameElement}`);
alert(`passwordElement = ${passwordElement}`);
alert(`username = ${usernameElement.value}`);
alert(`password = ${passwordElement.value}`);
}
Now the problem is with the require because that is not supported. So I decided to use imports instead and added "type"="module" to my package.json but was still getting an error in the console saying I can't use it. Then I used requirejs and ran into this issue where I couldn't import requirejs without using the require function. When I tried to add
var requirejs = require('requirejs')
requirejs.config({
nodeRequire: require
});
it would say that I couldn't use require(). When I tried to do it in a seperate file I realized I had to require that file to use requirejs which wouldn't work. I have no idea on how to fix this, I have been searching stack overflow and other websites but nothing mentions this. I want to know if there is a different way which I have just been missing this whole time.
I will assume that you are just declaring the js in some HTML with a script that will run in the client. Like that <script src="./myscript.js"></script>
Why you couldn't use require
require is the way we import modules in Node.js(an engine that runs javascript outside the browser) or any other javascript engine that adopts the CommonJs modules pattern. Browsers uses what is called ESModules.
Why did changing type="module" in package.json didn't solve this problem?
The package.json file is completely ignored by the browser, it doesn't affect anything in the javascript you import from the script tag. package.json is file used by node.js(and other engines). And type="module" is used in Node.js to use import instead of require, so wouldn't fix even if the browser read it.
How can we import things in browser javascript
Firstly I have to say that browsers usually expect people to use some bundling tool like webpack. (bundler is just a program that transforms all your .js files into a single .js file) instead of importing modules directly, but if you want to do it only using a web-browser and nothing more you can:
Add the type="module" in the script tag.
<script type="module" src="./myscript.js"></script>
Use something like the live server extension of vscode
Because, browsers cannot give .html files to have full access to your files, so you need to simulate a server in a folder.
So now you can simple use import {thing} from "./myscript.js" that will work.
How to use the require.js lib in the browser.
I have to say that you shouldn't use it, it is used by people that want some packages made for node.js to work on browser. But if one would want to use requires only using the browser they would have to remember that when we do npm i requirejs it creates downloads it into the node_modules folder, so we would have to import from there. But again, you shouldn't do that to solve your problem. Stick to the import.

Gatsby site - CSS in index.js doesn't load on first access

i'm building my first gatsby site and i've run into a few css issues during deployment.
first off, when i load the site, none of the css loads - but when i click on latest promotions/hktaxi (completed pages) and then epayment services (links back to index.js - same as homepage), the css loads. i initially thought this was a netlify issue, which is why i decided to deploy it to github pages too - but the page looks exactly the same on both platforms.
the page is responsive on web, but not on mobile. i've read solutions online that the meta tag for the viewport should be put in my html file - however, i don't have one. should i be creating a html.js file and inserting the meta tag there?
put the repo here for reproducibility: github.com/claudiahleung/gatsby-learnings
thanks!
There's a lack of implementation but a few cents and a bunch of plausible causes:
It seems, according to the described behavior that you have some hydration issues. At the initial render point, none of your styles are being loaded or applied but when you move back and forwards (where rehydration occurs) it loads. This issue normally appears when you block that hydration by pointing directly to the DOM instead of React's virtual DOM (vDOM), for instance, when asking for window or document outside React's scope (without hooks).
That said, this is an implementation issue, not a Netlify's or GitHub issue. This should (and must) happen when building your project locally, since, in the end, what Netlify's does is to build your project on their server and you should be able to reproduce it locally by gatsby build && gatsby serve. If locally things work as expected, you may start thinking in a Netlify issue (normally related with mismatching Node versions between environments).
In your case, I'm pretty sure that your issue comes because you are using styled-components but you haven't read the implementation details in Gatsby's docs because you are missing the required plugins and details in your gatsby-config.js such as:
module.exports = {
plugins: [`gatsby-plugin-styled-components`],
}
That's not true at all, you can customize the HTML output (because Gatsby allows you to do it) and manipulate it as you wish, adding the needed meta tags (which is not the solution to your issues). Simply run:
cp .cache/default-html.js src/html.js
Or manually copy the default-html.js from .cache folder to /src and rename it to html.js. If Gatsby, when compiling your project, finds that file under /src folder, will use it as a "template" for your compiled code. It will look like:
import React from "react"
import PropTypes from "prop-types"
export default function HTML(props) {
return (
<html {...props.htmlAttributes}>
<head>
<meta charSet="utf-8" />
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, shrink-to-fit=no"
/>
{props.headComponents}
</head>
<body {...props.bodyAttributes}>
{props.preBodyComponents}
<div
key={`body`}
id="___gatsby"
dangerouslySetInnerHTML={{ __html: props.body }}
/>
{props.postBodyComponents}
</body>
</html>
)
}
HTML.propTypes = {
htmlAttributes: PropTypes.object,
headComponents: PropTypes.array,
bodyAttributes: PropTypes.object,
preBodyComponents: PropTypes.array,
body: PropTypes.string,
postBodyComponents: PropTypes.array,
}
Outside the scope of the question. I would recommend ignoring the .cache and the public folders by adding them in the .gitignore file. They are autogenerated in each project compilation and it may lead you to some Git conflicts (unless you are the only contributor) but it's a good practice to don't push it to avoid noise in the repository.

First steps with Polymer, elements not displaying correctly (in Plunker!)

I'm just starting with web development, and I'm trying to use some polymer elements:
http://embed.plnkr.co/o4OKkE/
I'm kind of half managing the import. The elements display (in some manner). The paper element works well, apart from the margins. The button is good, the paper-input completely fails, same with tabs. The text/formatting is all default. Does polymer dictate the font etc, or is it managed using CSS separately?
I think I'm not attaching the theme correctly. Can anyone point out the errors?
Edit: Thanks to Neil John Ramal, I've got the basics working without any errors:
http://run.plnkr.co/AD3ETQOsMwajnSBt/
I just can't seem to get the elements to import using polygit, just rawgit.
This here:
works fine. However this produces an error:
Redirect at origin 'http://polygit.org' has been blocked from loading by Cross-Origin Resource Sharing policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://run.plnkr.co' is therefore not allowed access.
Presumably because Plunker is not allowing redirects and that's how polygit works. How it functions with polymer.html I'm not sure...
You are mixing up your imports. You have to make sure you are importing your components from a single source so no variable/name clashing would occur. On your example, you are importing both from your own repository and polygit's.
Evidence is on the error logs:
VM199 polymer-micro.html:363 Uncaught NotSupportedError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'dom-module'. A type with that name is already registered.
This just means that you have imported polymer.html more than once and from different sources. HTML imports only dedupe if they came from the same source.
Also at your index.html:
<script data-require="polymer#*" data-semver="1.0.0" src="http://polygit.org/components/polymer/polymer.html"></script>
Should be:
<link rel="import" src="//polygit.org/components/polymer/polymer.html">

Download file from a HTML GET method with Matlab

I've used StackOverflow for long but I've never had to ask because there is a lot of already answered questions.
Now I am stuck in a Matlab problem I cannot solve:
I am working with Google Trends and I need to download a CSV file with Matlab, as the one you can download from the following link:
https://www.google.com/trends/trendsReport?hl=es&q=dji&tz=Etc%2FGMT-2&content=1&export=1
which is easy to get from its page ( https://www.google.es/trends/explore#q=ford )
My problem is:
I can download it with any browser, even Matlab web browser works, however I haven't found a way to automatize that download.
I have tried with urlread() and I get an HTML file instead of a CSV file:
<html><head><title>Redireccionando</title>
<script type="text/javascript" language="javascript">
// Accessing window.external members can cause IE to throw exceptions.
// Any code that acesses window.external members must be try/catch wrapped
/** #preserveTry */
try {
if (top == self) {
if (window.gtbExternal) {
window.gtbExternal.setM();
} else {
window.external.setM();
}
}
}
catch(err) {
}
</script>
<meta http-equiv="refresh" content="0; url='https://www.google.com/trends#q=dji&hl=es&tz=Etc/GMT-2&content=1'"></head>
<body bgcolor="#ffffff" text="#000000" link="#0000cc" vlink="#551a8b" alink="#ff0000"><script type="text/javascript" language="javascript">
location.replace("https://www.google.com/trends#q\x3ddji\x26hl\x3des\x26tz\x3dEtc/GMT-2\x26content\x3d1")
</script></body></html>
I have also tried with urlread2() which I found around here, and also with a downloadUrl() function that looks like it is based on Java, but my Java knowledge is tiny and I have no idea of what that function does or if I can modify it to suit my problem.
I'm sure someone has already solved that problem in Matlab but I have not been able to find a solution on my own by now. I guess that it is something related to the GET method which I do not know how to handle properly.
If you don't mind your code opening up a window in your system browser, you can automate the download by
url = 'https://www.google.com/trends/trendsReport?hl=es&q=dji&tz=Etc%2FGMT-2&content=1&export=1'
web(url, '-browser');
The problem with using urlread (or webread, which is preferred) is that your link doesn't actually point to the CSV file you want to download; it points to a webpage which contains redirection Javascript. That page is what you see above when you run urlread. When you load this in a browser, the Javascript is executed, which redirects to another page and ultimately the CSV file is generated. But urlread and webread will not execute the Javascript. As far as I know, Matlab can't execute Javascript directly, hence you may need to open a browser to execute the Javascript and generate the CSV file.

WkHTMLtoPDF not loading local CSS and images

I've seen multiple questions that are very similar to this one, so I was hesitant at first to post it. But nothing suggested resolved my issue and I can't seem to figure out what's wrong myself.
For a project I made for one client they wanted to ability to convert quotes for their customers (generated using an online form) to PDFs. Simple enough. As the entire project was in PHP, I used the following simple process:
Save the quote as a temporary HTML file
Use WkHTMLtoPDF to convert the HTML file to a PDF
Output this PDF file
Clean up (delete temporary files)
This worked until they changed servers. The new server has a firewall.
At first the PDF conversion step was returning a firewall page saying that the server couldn't make outbound connections. To resolve this I fed the HTML file directly instead of linking to it (/var/www/mysite/temp/18382.html instead of www.example.com/temp/18382.html). This converted the HTML, but the firewall prevented the loading of CSS and images
I can overcome the CSS by simply embedding it directly in the site instead of linking to it (using the <style> tags), but this doesn't work for images
I tried using relative links first. I changed <img src="http://www.example.com/temp/image.jpg" /> to <img src="./image.jpg" />. This didn't work.
Next I tried <img src="file:///var/www/mysite/temp/image.jpg" /> but this didn't work, either
I read around and look through the WkHTMLtoPDF manual and I tried several different command line arguments like --enable-local-file-access, --enable /var/www/mysite/temp/, and --images but nothing seems to fix it
In my case - wkhtmltopdf version 0.12.2.1 (with patched qt) - adding a base tag to the head section with the absolute path made sure images and css did get loaded.
<html>
<head>
...
<base href="http://www.example.com/">
<link href="/assets/css/style.css" rel="stylesheet">
...
</head>
If your are on linux check the ownership of your images. For windows you will find some info on http://code.google.com/p/wkhtmltopdf/wiki/Usage.
I tried different kind of paths to the image:
<img src="file:///var/www/testpdf/flowers.jpg"><br>
<img src="./flowers.jpg"><br>
<img src="flowers.jpg"><br>
<img src="/var/www/testpdf/flowers.jpg"><br>
all images are showed correct. I didn't use any command line arguments
(only wkhtmltopdf /var/www/testpdf/makepdf.html makepdf.pdf)
For Windows you need to use absolute file system paths in your markup. For instance:
<link href='C:\Projects\Hello\Hello.Web\Content\custom\home.css' rel='stylesheet' type='text/css' />
! not http://localhost/Hello.Web/Content/custom/home.css
In order to have them embed, you can insert base64 encoded images like :
<img src="data:image/png;base64,someBase64content"/>
When a browser renders your HTML, it uses a relative path (sometimes with a URL at the beginning of it) like this:
<img src="/static/images/some_picture.png">
<img src="http://www.example.com/static/images/some_picture.png">
But when WkHTMLtoPDF is running on your server, it's interfacing with your local files directly through the filesystem, not through a web server. So for local files, unlike a browser, WkHTMLtoPDF wants the actual filepath:
<img src="/var/www/myapplication/static/images/some_picture.png">
(This worked for me with Python Flask)
on Windows use path: file:///C:/some/dir/some/file.img (notice the tripple /)
It is may be too late :)
BTW, just add this config into your options in last.
options = {'enable-local-file-access': None}
pdfkit.from_string(html, 'filename.pdf', options=options)
After taking in everyone's kind assistance from here and around the net, I discovered something that worked for me - coding in asp.net (c#).
I needed to access the image by url (not file path), as the original source html still needed to be accessed. Through troubleshooting, I discovered these points.
These flags had to be passed in to the command line process:
"-q -n --disable-smart-shrinking --images --page-size A4"
URL still has to be absolute.
Image must be a jpg! I was originally trying to do a gif, to no avail.
I discovered adding "--enable-local-file-access" didn't help, as it requires '\' slashes in the image path instead of '/' slashes, which doesn't help if you also hope to use the source html (in some browsers). Also, if you need to access the local file system, you need to provide an absolute path, as it reads straight from the root and goes from there.
Hope this helps others.
Cheers
-y
I know this is quite old topic, but I've just faced the same issue and maybe it will help to someone.
I tried different approaches, like css background image and using string as base64 encoded data image. Sometimes it helped, sometimes not - no particular rule I could found.
It turned out that upgrading library wkhtmltopdf solved the problem.
I was using version 0.12.0 and upgraded to 0.12.3
What fixed it for me was removing the references to my CSS files. It turned out I had was setting img { max-height: 100%; } in an otherwise-empty div so that was being interpreted as max-height: 0.
So check out your CSS and there might an issue there. This worked:
<div><img src="image.png"/></div>
And running command line in the directory with image.png:
wkhtmltopdf example.html example.pdf
But this does not:
<div><img src="image.png" style = "max-height: 100%; "/></div>
Because the image gets squished to 0 height. Firefox seems to correct this so it wasn't obvious.
This is probably due to SE Linux or firewall rules that prevent you from going out on the internet and back to your own server. You can update your host file to point calls to your domain back to your machine's home address.
make sure you have the latest version of wkhtmltopdf with patched qt.
you can implement a helper that flask jinja uses it to distinguish if the template is for rendering or only generating pdf, or maybe both.
let' say that tmpl_bind is the data object to bind in the template, add a new key tmpl_bind["pdf"] set it True or False.
when using wkhtmltopdf or pdfkit, add enable-local-file-access to options object.
now create a helper function called static_file
def static_file(filename, pdf=False):
# wkhtmltopdf only read absolute path
if pdf:
basedir = os.path.abspath(app.root_path)
return "".join([basedir, "/static/", filename])
else:
return url_for('static', filename = filename)
as we say, wkhtmltopdf for some os only read files when you include their absolute path. Note that you may add or remove parts from the app.root_path, according to your app structure, but this will work in most of cases.
in app configuration add this line after importing static_file function if it is in another file
app.jinja_env.globals['static'] = static_file
finally, in the template import files, images by calling the static_file helper function
<link href="{{ static('css/style.css', pdf) }}" rel="stylesheet" />
<img src="{{ static('assets/images/logo.svg', pdf) }}" class="logo">
For me the problem was resolved by doing two things:
1: In your app/config/config.yml
- Under the knp_snappy
- For the option temporary_folder write ./
- i.e: temporary_folder: ./
2: Now in your html.twig pages remove the asset and write:
From: <link rel="stylesheet" type="text/css" href="{{ asset('css/default_template.css') }}">
To: <link rel="stylesheet" type="text/css" href="css/default_template.css">
And after that, it worked for me.
Hopefully i've helped somebody. Thank you !
To generate your pdf with your images or styles you need to provide the server path as follows:
<img src="https://upload.wikimedia.org/wikipedia/...image.png" />
<link href="http://localhost:8080/css/file.css" media="all" rel="stylesheet" type="text/css" />
Note this second link, it's the local address to your stylesheet, or could be a remote like the first link. The file path didn't work for me, only the server path to the resource.
Ps: In my situation, I am using spring boot in Intellij IDE and I needed to invalidate cache of IDE and not run in debug mode in order to work, otherwise it may be not update things.
URL of images must be absolute not relative.
Check this working example in a twig template:
<img src="{{ absolute_url(asset('images/example.png')) }}"/>
Just spent a few days on getting a Flask/ Blueprint /static file/ css to be read by wkhtmltopdf, so I thought I'd share what I learned.
Win 7, Flask 0.12 on Python 3.4.4, using Pycharm pro, latest pdfkit and wkhtmltopdf.
download the wkhtmltopdf here
install it -mine installed on:
C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe
right after you import pdfkit into your flask routes.py script ,insert the lines:
path_wkthmltopdf = r'C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe'
config = pdfkit.configuration(wkhtmltopdf=path_wkthmltopdf)
(note the "r" in the first line here !! )
when you use pdfkit in a route, add ",configuration = config" as an argument, eg:
pdfkit.from_string(html_text, output_filename, configuration = config)
this tells pdfkit where to look for wkhtmltopdf. Yes, you need to do this.
NOW in your flask BASE TEMPLATE add , _external = True to your css route, eg:
(this will keep wkhtmltopdf from throwing error cant find css)
NOW (serious bootstrap template juju warning):
go into your flask /external libraries /site-packages /flask_bootstrap /templates /base.html template and:
a. fix CSS link:
<link href="{{bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')}}" rel="stylesheet" media="screen">
add "http:" so it looks like:
<link href="http:{{bootstrap_find_resource('css/bootstrap.css', cdn='bootstrap')}}" rel="stylesheet" media="screen">
b. fix JS links:
add "http:" so the JS links look like:
<script src="http:{{bootstrap_find_resource('jquery.js', cdn='jquery')}}"></script>
<script src="http:{{bootstrap_find_resource('js/bootstrap.js', cdn='bootstrap')}}"></script>
and with all this
your flask html to pdf conversion
using pdfkit and wkhtmltopdf
should run without errors.
note: I moved to flask from PHP and if you are a flask-er, please post your solutions up here. The flask community is MUCH smaller than the PHP community so we all have to pitch in.
opt = dict()
opt["orientation"] = "landscape"
opt["enable-local-file-access"] = ""
config = pdfkit.configuration(wkhtmltopdf='/usr/bin/wkhtmltopdf')
enable local file access to access images