SVG icon in twig template - php

I'm struggling with svg icons. I'm creating menu and to do this I have to use several of svg icons. I already know, that if I want to manipulate colour with help CSS (for example when icon is active/hover) I have to use in HTML <svg> tag not <img src="path-to-icon.svg"/>.
How can I solve this problem in a nice way?
I don't want use full path of svg in my HTML file, because sometimes it is has a hundred of lines d="..." attribute. I try to avoid use <use xlink:href="path-to-icon.svg" /> as well, because is not supported by IE or Edge browsers.
I can add that I use .twig template, so maybe there is a 'PHP' way to add icon.
HTML:
<label id="menuIcon" for="menu" onclick="openNav()">
{# svg icon #}
</label>
CSS
.icon:hover path {
fill: green;
}

I would generate my own font file with all the icons used in the application... just like fontawesome or ionicons.

Please see this Craft Function within Twig it may be useful:
https://craftcms.com/docs/3.x/dev/functions.html#svg
You can also put your code into a .twig template and include that like you would any other twig file.

Related

Generating a PDF with non-printable background

In Adobe Acrobat there is an option to add a "background" to a PDF file and set the default settings that this image should be visible when opening the document but should not be printed out. I want to automate the process by a PHP script.
I checked all the popular PHP PDF libs (TCPDF, FPDF, mPDF, ...) but none of them seems to provide such an option. All I found is adding images by the ->Image method and place it behind the text. This does work when viewing the document, but of course it is also printed out.
A second approach is to render plain HTML and include custom stylesheets. I created the simple HTML
<h1>Simple text.</h1>
<div>
<p>Should be printed.
<img src="..."></p>
</div>
<div class="no-print">
<p>Should NOT be printed.
<img src="..."></p>
</div>
and saved the CSS in print.css
.no-print {
display: none;
}
and included it by:
<link rel="stylesheet" media=“print” type="text/css" href="print.css">
The result does not show the second div. I guess the PDF libs do not evaluate the media in the link tag. To be honest this approach does not feel right, especially because PDF !== HTML.
Nevertheless I cannot imagine that this is so difficult. How do all the big companies manage this? I'm grateful for every hint!

MPDF div not working inside table

I am working on mpdf and it is a good library to convert html page to pdf, but when I put block element e.g <div><p> inside table cell it doesn't behave like a block element, it behaves like inline element.
code:
<td><div>Block Element</div></td>
or
<td><p>Block Element</p></td>
Is there a way to make it block element?
Or should I use other library?
Thanks in advance.
Looking for solutions to the same problem I just realized that according to the documentation, it's not a bug, it's a feature limitation:
Block-level tags (DIV, P etc) are ignored inside tables, including any
CSS styles - inline CSS or stylesheet classes, id etc. To set text
characteristics within a table/cell, either define the CSS for the
table/cell, or use in-line tags e.g. <SPAN style=”…“>
Seems like there's currently no way around it.
In my case I had to use s to indent (fake-center) a <h4> headline.
See https://mpdf.github.io/tables/tables.html

PHP - Dynamically creating a svg with embedded fonts

I want to dynamically create an svg that I can use in an <img/> tag. This in itself is easy; create an svg, set the header and echo the generated parts in their correct place.
The problem is, I want to be able to embed fonts in the svg.
I've tried using the #font-face rule in the css of the svg, but that didn't work (MDN says that it only works on Android and Safari).
Is there any cross-browser way to do this?
Solutions I've Considered:
Possible Solution #01:
The solution:
In my main file, create an svg file which uses the #font-face css rule, and then use exec() to use inkscape to convert that svg into another svg, which converts all letters into paths. I then could use echo file_get_contents($inkscape_file) with the correct headers to output it as a svg which can be used with an <img/> tag.
The problem with this:
This creates 2 additional files, so seems very inefficient. Furthermore, since each user will end up generating several images, the space it takes up would grow phenomenally.
Possible Solution #02:
The solution:
Make a template in illustrator, then save it as svg, and tick the embed all glyphs option. Then replace the text & the styles with the options from the PHP script. Use the correct header and output this.
The problem with this:
This severely limits the amount of fonts that can be used, as it is limited to only those which I create a template for. My desired behaviour was to add the option for users to upload their own fonts and use them. This solution does not allow for that.
Additional information that may be of some relevance:
My development server runs fedora, and the production server uses redhat.
The #font-face rule I am currently using is as follows:
#font-face {
font-family: Potato;
src: url("/fonts/potato.otf");
}
You can't load any external resources declared in the svg from the <img> tag.
The only solutions would be some crappy ways to append the glyphs or the fonts into the svg file itself.
Actually there is a not so crappy way to do it as you found in this answer by lèse-majesté.
The best way is then still IMO to not use an <img> tag to display the svg documents, but rather use an <iframe> or an <object> tag, with the #font-face declared inside the svg file, or even directly include an inline version into the document. These methods do allow the loading of external resources such as fonts.
Then you just have to save the fonts on your server or just an url to the font in the #font-face declaration.

In Drupal 8 views, how can I rewrite the output of image field to become a div with this image as a background image?

I have a view to display a content that have an image field, and I need to display this image as a background image of a div so I can apply some CSS on it.
what I tried to do is to rewrite the output of this field using twig to be like this:
<div class="page-image" style="background-image: url({{ field_image }});">
</div>
the problem is that Drupal strips style attribute so the output will be like this:
<div class="page-image">
</div>
In D7 I used to fix this kind of issues by overriding the template for the specific field, but I couldn't figure out what is the name of the needed template in D8. when I enabled twig debug it turned out that the field is using the template file views-view-field.html.twig which is the default template for all fields in views, but I couldn't find the needed template name for this specific field in this view.
any suggestions?
I am also getting started with D8 development and was figuring out how views templating works.
You would copy /core/modules/views/templates/views-view-field.html.twig into your theme directory and name the template with the following convention.
views-view-fields--articles-[view machine name]--[view display id].html.twig
I know this after reading this really useful post.
Here's a preprocessor solution that I'm using:
In my .theme file I have:
function THEMENAME_preprocess_page(&$variables) {
if ($node = \Drupal::request()->attributes->get('node')) {
if ($node->field_hero_background_image->entity) {
$variables['hero_background_image_url'] = file_create_url($node->field_hero_background_image->entity->getFileUri());
}
}
}
then in my page.html.twig
style="background-image: url('{{ hero_background_image_url }}')
You can also use 'blazy' (https://www.drupal.org/project/blazy) for displaying images. In views then there is an option to display blazy-images as background-images. So you don't have to change the general way for all images.

Font Awesome page load speed vs. css image?

I want to know which one is faster. Using the font awesome to call the icon is faster or using css url to call the icon?
Font. If you are using the same Font Awesome as me, it is faster to use them as a font, instead of an image. The font is there as a collection of icons which you can use just by inserting a class to an element, or setting up a pseudo class to a class and inserting the icon you want in content.
HTML:
<i class="fa fa-search"></i>
CSS:
.element:before { content: "\f002"; }
Using the background property you have to insert an image url which means you either have to have multiple images in your folder taking up space and finding each and every one, or you have one image and you have to set your background-position for each icon.

Categories