I could not see tutorial how to add image (any HTML tags) to header or footer. I found only 'content' attribute which cannot add HTML tags.
With the content property you can use a url(...) value which will insert an image. However there is no way to style the components of content individually, so only way to size the image is to use e.g. image-resolution: 300dpi.
You can also use background-image and background-size on the page box or page-margin boxes.
Finally, any element with position: fixed is repeated on every page. You can use something like bottom: 100%; margin-bottom: 1em to position it in the top page margin. However the content must be the same on every page, you can not use a page counter there.
Do any of these work for you?
Nice solution! Thanks.
Please close the bug if you find a solution that works for you.
I'm trying to display an image in the header using a @top-center. Using the content property, the image is correctly displayed but indeed, I cannot size it.
So then, I tried using the background-image property but I cannot manage to have the image displayed in the header: nothing is draw. However, I can manage to display it using this technique if I do this on a normal div....
Here is my code:
@top-center {
background: url('../icons/image.png') no-repeat 0 0;
background-size: 10%;
}
The page-margin box might not be rendered, or have a zero size if it doesn鈥檛 have content. Try something like:
@top-center {
content: "";
width: 100%;
height: 100%;
background: ...
}
Percentages in width and height refer to the size of the containing block, which is described here for page-margin boxes. See also the diagrams in the table here. On each of the four sides, three non-corner page-margin boxes share the same containing block.
Alternatively, you can also set a background (or multiple backgrounds, even) on @page itself, and size/position it with background-size and background-position.
Thanks it was actually the reason why nothing was drawn.
My problem was somewhat related to this thread so this is my solution if anyone finds it. I needed a footer image per page.
def content_to_boxes(style, parent_box, quote_depth, counter_values, get_image_from_uri, context=None):
"""
Dirty hack to allow page counts within a image url (used for the QRCODE).
Pulled from weasyprint 0.31
"""
from weasyprint.formatting_structure.build import boxes, counters
texts = []
for type_, value in style.content:
if type_ == 'STRING':
texts.append(value)
elif type_ == 'URI':
# hacked bit
# interpolate counter
def repl(m):
counter_name = m.group(1)
counter_value = counter_values.get(counter_name, [0])[-1]
return counters.format(counter_value, 'decimal')
value = re.sub('\$([^$]+)\$', repl, value)
# end hacked bit
image = get_image_from_uri(value)
if image is not None:
text = ''.join(texts)
if text:
yield boxes.TextBox.anonymous_from(parent_box, text)
texts = []
yield boxes.InlineReplacedBox.anonymous_from(parent_box, image)
elif type_ == 'counter':
counter_name, counter_style = value
counter_value = counter_values.get(counter_name, [0])[-1]
texts.append(counters.format(counter_value, counter_style))
elif type_ == 'counters':
counter_name, separator, counter_style = value
texts.append(separator.join(
counters.format(counter_value, counter_style)
for counter_value in counter_values.get(counter_name, [0])
))
elif type_ == 'string' and context is not None:
text = context.get_string_set_for(*value)
texts.append(text)
else:
assert type_ == 'QUOTE'
is_open, insert = value
if not is_open:
quote_depth[0] = max(0, quote_depth[0] - 1)
if insert:
open_quotes, close_quotes = style.quotes
quotes = open_quotes if is_open else close_quotes
texts.append(quotes[min(quote_depth[0], len(quotes) - 1)])
if is_open:
quote_depth[0] += 1
text = ''.join(texts)
if text:
yield boxes.TextBox.anonymous_from(parent_box, text)
weasyprint.formatting_structure.build.content_to_boxes = content_to_boxes
so now I can place a image per page
@bottom-left {
font-style: italic;
font-size: 0.7em;
vertical-align: bottom;
content: url("myprotocol://{{ datafromview }}$page$:$pages$")
}
dont know if this is the best solution or if it is worth to make a hook on content_to_boxes but here it is.
Most helpful comment
With the
contentproperty you can use aurl(...)value which will insert an image. However there is no way to style the components ofcontentindividually, so only way to size the image is to use e.g.image-resolution: 300dpi.You can also use
background-imageandbackground-sizeon the page box or page-margin boxes.Finally, any element with
position: fixedis repeated on every page. You can use something likebottom: 100%; margin-bottom: 1emto position it in the top page margin. However the content must be the same on every page, you can not use a page counter there.Do any of these work for you?