How to use "--replace" in wkhtmltopdf - replace

I saw all that content, didn't see about the content of the way to use '--replace'.
How to use "--replace" in wkhtmltopdf.
Please give me an example,Thanks.:)

Lets say you have a footer my_footer.html which contains the following:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script>
function substitutePdfVariables() {
function getParameterByName(name) {
var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
}
function substitute(name) {
var value = getParameterByName(name);
var elements = document.getElementsByClassName(name);
for (var i = 0; elements && i < elements.length; i++) {
elements[i].textContent = value;
}
}
['username'/*, 'topage', 'page',.. etc and any variable you would want to replace */]
.forEach(function(param) {
substitute(param);
});
}
</script>
</head>
<body onload="substitutePdfVariables()">
<span class="username"></span>
</body>
</html>
You can replace "username" with some value:
wkhtmltopdf my_super_html.html --footer-html my_footer.html --replace "username" "Veaer"
Notice that I used javascript to replace the named variable with my value.

I did some adjustments to #viniciux answer which is actually working so here is the improvements in footer.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script charset="utf-8">
function replaceParams() {
var url = window.location.href
.replace(/#$/, ""); // Remove last # if exist
// default params
//['page', 'section','sitepage','title','subsection','frompage','subsubsection','isodate','topage','doctitle','sitepages','webpage','time','date'];
var params = (url.split("?")[1] || "").split("&");
for (var i = 0; i < params.length; i++) {
var param = params[i].split("=");
var key = param[0];
var value = param[1] || '';
var regex = new RegExp('{' + key + '}', 'g');
document.body.innerText = document.body.innerText.replace(regex, value);
}
}
</script>
</head>
<body onload="replaceParams()">
name: {username}
age: {age}
url: {url}
page {page}
</body>
</html>
and then you can add multiple parameters to replace dynamically
wkhtmltopdf page.html --footer-html footer.html --replace "username" "Veaer" --replace "age" "20" --replace "url" "google.com"
notice that page will be current pdf page and will be included by default in the parameters list

A mixed solution from #dpineda and #viniciux. This solution doesn't break the stylesheet
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script charset="utf-8">
// For WKHTMLTOPDF Substitutions
window.onload = function()
{
function substitute(key, value)
{
var elements = document.getElementsByClassName(key);
for (var i = 0; elements && i < elements.length; i++)
{
elements[i].textContent = value;
}
}
var url = window.location.href.replace(/#$/, ""); // Remove last # if exist
// default params
//['page', 'section','sitepage','title','subsection','frompage','subsubsection','isodate','topage','doctitle','sitepages','webpage','time','date'];
var params = (url.split("?")[1] || "").split("&");
for (var i = 0; i < params.length; i++)
{
var param = params[i].split("=");
var key = param[0];
var value = param[1] || '';
var regex = new RegExp('{' + key + '}', 'g');
substitute(key, value);
}
}
</script>
</head>
<body onload="substitutePdfVariables()">
<span class="username"></span>
</body>
</html>

Related

Bootstrap Typeahead basic example not working in Django

I am trying to implement Bootstrap Typeahead to eventually use an Elasticsearch instance I have, but I cannot even get the basic example to work in Django (2.2.6). I am taking the majority of this code from the examples page. Here is the HTML I am using:
typeahead.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>
<script type="text/javascript">
var substringMatcher = function(strs) {
return function findMatches(q, cb) {
var matches, substringRegex;
// an array that will be populated with substring matches
matches = [];
// regex used to determine if a string contains the substring `q`
substrRegex = new RegExp(q, 'i');
// iterate through the pool of strings and for any string that
// contains the substring `q`, add it to the `matches` array
$.each(strs, function(i, str) {
if (substrRegex.test(str)) {
matches.push(str);
}
});
cb(matches);
};
};
var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
];
$('.typeahead').typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'states',
source: substringMatcher(states)
});
</script>
</head>
<body>
<div id="the-basics">
<input class="typeahead" type="text" placeholder="States of USA">
</div>
</body>
</html>
Here is the page/URL I am trying to access:
urls.py
from django.urls import path
from . import views
app_name = 'materials'
urlpatterns = [
path('typeahead/', views.typeahead_view, name='typeahead')
]
And this is the basic view I have set up for this page:
views.py
def typeahead_view(request):
return render(request, 'materials/typeahead.html')
Nothing happens when I start typing in the input...
There is a problem with your html page. First of all, jquery was not added in it and secondly add all the js file at the end of the body. Check below updated code for the html file.
typeahead.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div id="the-basics">
<input class="typeahead" type="text" placeholder="States of USA">
</div>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<script src="https://twitter.github.io/typeahead.js/releases/latest/typeahead.bundle.js"></script>
<script type="text/javascript">
var substringMatcher = function(strs) {
return function findMatches(q, cb) {
var matches, substringRegex;
// an array that will be populated with substring matches
matches = [];
// regex used to determine if a string contains the substring `q`
substrRegex = new RegExp(q, 'i');
// iterate through the pool of strings and for any string that
// contains the substring `q`, add it to the `matches` array
$.each(strs, function(i, str) {
if (substrRegex.test(str)) {
matches.push(str);
}
});
cb(matches);
};
};
var states = ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California',
'Colorado', 'Connecticut', 'Delaware', 'Florida', 'Georgia', 'Hawaii',
'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana',
'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota',
'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire',
'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota',
'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island',
'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont',
'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'
];
$('.typeahead').typeahead({
hint: true,
highlight: true,
minLength: 1
},
{
name: 'states',
source: substringMatcher(states)
});
</script>
</body>
</html>
It works properly. I hope this will help you :)

Leaflet grouping layer doesn't show on the map

I am working in GeoDjango. I am trying to add leaflet group from here. I copied files from the dist folder to my folder with the static files and imported them into HTML file. Anyway I have some problem with this part of code:
//GROUP LAYER
var osm =
'http://{s}.tile.openstreetmap.org/{z}{y}{x}.png';
var baseLayers = {
"OSM":osm
}
var groupedOverlays = {
"layers": {
"layer1": datasets_buildings,
"layer2": datasets_roads,
"layer3": datasets_railways,
"layer4": datasets_natural
}
};
L.control.groupedLayers(baseLayers, groupedOverlays, options).addTo(map);
When I typed this, I don't even get my layers on the map, I get just the empty leaflet map and without this part of the code, I get it.
Also, I would like to make functionality to this layer group which allows only one layer to be active.
This is all my code:
<html lang="en">
{% load static %}
{% load leaflet_tags %}
<head>
{% leaflet_js %}
{% leaflet_css %}
<style type="text/css">
#gis {
width: 100%;
height: 870px;
}
</style>
<link rel="stylesheet" type = 'text/css' href="{% static 'maps/dist/leaflet.groupedlayercontrol.css' %}">
<script type="text/javascript" src="{% static 'maps/dist/leaflet.ajax.js'%}"></script>
<script type="text/javascript" src="{% static 'maps/dist/leaflet.groupedlayercontrol.js' %}"></script>
</head>
<body>
<script type="text/javascript">
function our_layers(map,options){
//buildings
var datasets_buildings = new L.GeoJSON.AJAX("
{% url 'buildings_json_data' %}",{
onEachFeature : function (feature, layer) {
layer.bindPopup(feature.properties.name.toString())
}
});
//roads
var datasets_roads = new L.GeoJSON.AJAX("{% url 'roads_json_data' %}",{
onEachFeature : function (feature, layer) {
layer.bindPopup(feature.properties.name.toString())
}
});
//railways
var datasets_railways = new L.GeoJSON.AJAX("{% url 'railways_json_data' %}",{
onEachFeature : function (feature, layer) {
layer.bindPopup(feature.properties.name.toString())
}
});
//natural
var datasets_natural = new L.GeoJSON.AJAX("{% url 'natural_json_data' %}",{
onEachFeature : function (feature, layer) {
layer.bindPopup(feature.properties.name.toString())
}
});
datasets_natural.addTo(map);
datasets_railways.addTo(map);
datasets_roads.addTo(map);
datasets_buildings.addTo(map);
//GROUP LAYER
var osm = 'http://{s}.tile.openstreetmap.org/{z}{y}{x}.png';
var baseLayers = {
"OSM":osm
}
var groupedOverlays = {
"layers": {
"layer1": datasets_buildings,
"layer2": datasets_roads,
"layer3": datasets_railways,
"layer4enter code here": datasets_natural
}
};
L.control.groupedLayers(baseLayers, groupedOverlays, options).addTo(map);
}
</script>
{% leaflet_map "gis" callback="window.our_layers" %}
</body>
</html>
And the error when I get in the console when I go on inspect is:
leaflet.js:5 Uncaught TypeError: Cannot create property '_leaflet_id' on string 'http://{s}.tile.openstreetmap.org/{z}{y}{x}.png'
at Object.n [as stamp] (leaflet.js:5)
at e._addLayer (leaflet.groupedlayercontrol.js:131)
at e.initialize (leaflet.groupedlayercontrol.js:26)
at new e (leaflet.js:5)
at Function.L.control.groupedLayers (leaflet.groupedlayercontrol.js:373)
at Object.our_layers [as callback] ((index):96)
at Function.L.Map.djangoMap (leaflet.extras.js:234)
at loadmap ((index):112)
Thank you in advance :)
I found a mistake. I knew it was stupid, but I lost so much time on this and I posted a question..
Anyway, the line:
var osm = 'http://{s}.tile.openstreetmap.org/{z}{y}{x}.png';
should be replace with this line:
var osm = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}{y}{x}.png');

image slide not working properly in Java script

i am new here and trying add a image slider in my webpage. but i have tried several codes, the problem is my IE just showing only first image. then there is no image. MY IE is IE 11 and i am using netbeans8.0.2 and xampp.
what is the problem of not showing all the images in the slide?
here is the code:
<!DOCTYPE html>
<html>
<head>
<title>image slider!</title>
<script type="text/javascript">
var im1 = new Im();
im1.src = "1.jpg";
var im2 = new Im();
im2.src = "2.jpg";
var im3 = new Im();
im3.src = "3.jpg";
var im4 = new Im();
im.src = "4.jpg";
var im5 = new Im();
im5.src = "5.jpg";
</script>
</head>
<body>
<center>
<img src="slides/1.jpg" name="slider1" width=800 height=380 />
<script type="text/javascript">
var i=1;
function slidimage()
{
document.images.slider1.src = eval("im"+i+".src");
if (i<5)
{
i++;
}
else
{
i=1;
}
setTimeout("slidimage()",2000);
}
slidimage();
</script>
</center>
</body>
</html>
i have got this code from another post in stackoverflow by amin
sorry for the copy.

Why name is not displayed using $el.html() in backbonejs

I have folowing code:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.3.3/underscore-min.js" type="text/javascript"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/0.9.2/backbone-min.js" type="text/javascript"></script>
var myView = Backbone.View.extend({
tagName : 'li',
className : 'myClass'
});
var aView = new myView();
console.log(aView.el);
var Person = Backbone.Model.extend({
defaults: {
name: 'User1',
age: 27,
occupation: 'SE'
}
});
var anotherView = Backbone.View.extend({
tagName : 'li',
initialize : function(){
console.log("called View");
this.render();
},
render : function (){
console.log("model : " + this.model.get('name'));
this.$el.html(this.model.get('name'));
}
});
var person = new Person();
var fstView = new anotherView({model:person});
console.log(fstView.el);
here, this.$el.html(this.model.get('name')); is not displaying anything on browser.
In anotherView you have specified tagName as li. This creates a li element but does not add it to DOM and hence nothing is displayed in the browser. So, if you are creating view's el from tagName, className or id then you need to make sure you add it to DOM.
Add the last line below to you code.
var person = new Person();
var fstView = new anotherView({model:person});
console.log(fstView.el);
$('body').html(fstView.el);
Have a look at view.el and what is el.
NOTE: Make sure you have a ul and then add corresponding li's to it.

Input not being displayed

I have an input field. When the user clicks it some javascript converts the text to a Raphael JS library variable. I want to put each letter into a Raphael variable called string followed by a \n. When the user clicks on the button nothing is displayed. Can someone help me fix this?...
<html>
<head>
<script src="raphael.js"></script>
<script src="jquery-1.7.2.js"></script>
<script type="text/javascript">
var string = "";
function animate() {
var txt = document.getElementById("words").value;
var splittxt = txt.split("");
var i;
for (i = 0; i < splittxt.length; i++) {
var string = splittxt[i] + "\n\n";
}
}
</script>
<style type="text/css">
#letters
{
text-align:center;
margin-left:10px;
width:25px;
float:left;
text-shadow:10px 5px 1px #4D4D4D;
filter:DropShadow(Color=#4D4D4D, OffX=10, OffY=5);
font-weight:bold;
}
</style>
</head>
<body>
Text: <input type="text" id="words" />
<input type="button" value="Animate" onclick="animate()" />
<div id='letters'></div>
<div id="draw-here-raphael" style="height: 200px; width: 400px; margin-top:0px; background-color:blue;">
</div>
<div id="elps" style="ma
rgin-left:100px;"/>
<script type="text/javascript"> //all your javascript goes here
var r = new Raphael("draw-here-raphael");
var string = r.text(50,50, string);
</script>
</body>
</html>
Instead of setting the variable string, you want add to it. Also, there were quite a few other updates I made to your excerpt...
Setting variables to reserved words can also cause a lot of problems.
http://jsfiddle.net/fN9Me/
<html>
<head>
<script src="raphael.js"></script>
<script src="jquery-1.7.2.js"></script>
<script type="text/javascript">
var alpha = "";
var something = "";
var r = "";
var txt = "";
var splittxt = "";
$(function() {
r = new Raphael("draw-here-raphael");
$("#animate").click(function() {
txt = $("#words").val();
splittxt = txt.split("");
var i;
for (i = 0; i < splittxt.length; i++) {
something += splittxt[i] + "\n\n";
}
alpha = r.text(50, 50, something);
});
});
</script>
<style type="text/css">
#letters
{
text-align:center;
margin-left:10px;
width:25px;
float:left;
text-shadow:10px 5px 1px #4D4D4D;
filter:DropShadow(Color=#4D4D4D, OffX=10, OffY=5);
font-weight:bold;
}
</style>
</head>
<body>
Text: <input type="text" id="words" value="" />
<input id="animate" type="button" value="Animate" />
<div id='letters'></div>
<div id="draw-here-raphael" style="height: 200px; width: 400px; margin-top:0px; background-color:blue;">
</div>
<div id="elps" style="margin-left:100px;"/>
</body>
</html>
Update:
To remove the previous text, it is just a matter of utilizing the Raphael remove function. Also we have to reset the variable something
if (alpha) alpha.remove();
http://jsfiddle.net/fN9Me/1/
You're not actually displaying anything. This line:
document.getElementById("letters").innerHTML + splittxt[i] + "<br>";
needs to be something like:
document.getElementById("letters").innerHTML += splittxt[i] + "<br>";
The value of the words input is blank => when you call the split method var splittxt = txt.split(""); the splittxt has a length == 0, and therefore the body of the for statement is never executed.