Hiding DIV in TPL file based on if an image exists? - image

<div><div style="margin-left:67px"><table style="border:1px #80A0BB solid;" padding="5px"><tr><td><img src="{$smarty.const.DOC_ROOT}/images/thumbs/{$link.ID}-300x225.png" alt="" /></td></tr></table></div></div>
I'm trying to hide a div based on if an image exists on my server. How would I check to see if an image exists and hide the div if it doesn't exist? Or is there a better way to do this?

The easiest way is just to use write a function in PHP and then use it in Smarty.
In PHP:
function linkImageExists($link){
//Check to see if image for link exists and return true if it does.
// otherwise:
return false;
}
In Smarty template:
{if linkImageExists($link)}
<div>
<div style="margin-left:67px">
<table style="border:1px #80A0BB solid;" padding="5px">
<tr>
<td>
<a href="{$link.URL|trim}" target="_blank">
<img src="{$smarty.const.DOC_ROOT}/images/thumbs/{$link.ID}-300x225.png" alt="" />
</a>
</td>
</tr>
</table>
</div>
</div>
{else}
{* image doesn't exist *}
{/if}
You may want to consider turning $link into an object and then you can call functions on it, rather than having to use global functions which may producer cleaner code in the future.

Related

React-Quill does not preserve HTML response and dictates its own tags - Messes up the layout

EDIT: We replaced Quill with TinyMCE and solved all our issues. We can successfully insert HTML response (as is) into tinyMCE's state as well as modify it!
We're experiencing a styling issue. We're building a mail templating
application and the user can create/modify their templates. We also provide preexisting templates for our users.
The issue we're experiencing is the following.
1- We send the user a mail template. The initial/original response sent to the user is the following HTML
<html>
<head>
<title>FINROTA</title>
<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">
</head>
<body bgcolor=\"#FFFFFF\" leftmargin=\"0\" topmargin=\"0\" marginwidth=\"0\" marginheight=\"0\" style=\"font-family: Verdana, Geneva, Tahoma, sans-serif\">
<table width=\"670\" border=\"0\" align=\"center\" cellpadding=\"0\" cellspacing=\"0\">
<tr>
<td bgcolor=\"#FFFFFF\">
<table bgcolor=\"#FFFFFF\" width=\"575\" align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">
<!-- Header -->
<tr>
<td bgcolor=\"#FFFFFF\">
<table width=\"575\" align=\"center\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\" style=\"border-bottom: 1px solid #F3F3F3;\">
<tr>
<td style=\"height: 94px;text-align: center;\">
<a href=\"https://portal.finrota.com/\">
<img width=\"120\" height=\"30\" style=\" display: initial;padding-top: 20px;\" src=\"https://cdnecozum.com/static/images/mailing/header.png\" alt=\"finrota-logo\" />
</a>
</td>
</tr>
</table>
</td>
</tr>
<!-- /Header -->
</table>
</td>
</tr>
</table>
</body>
</html>
2- We then take this html response and set the react-quill 'state' with it
import { textEditorOptions } from "lib/constants";
import React, { forwardRef, useImperativeHandle, useRef } from "react";
import ReactQuill from "react-quill";
const editorOptions = {
toolbar: false,
clipboard: {
matchVisual: false
}
},
TemplateEditor = forwardRef(({ formParamForQuill, setFormParamForQuill, shouldHideToolbar, data, stateData, update, communicationType }, ref) => {
const [quillState, setQuillState] = React.useState({ description: data || "" }),
editorRef = useRef(),
handleQuillChange = val => {
setQuillState(() => ({ description: val }));
update(`${communicationType}`, { ...stateData[`${communicationType}`], body: val });
};
useImperativeHandle(ref, () => ({ editorRef }));
React.useEffect(() => {
if (formParamForQuill.token !== null && formParamForQuill.explanation !== null)
setFormParamForQuill({ token: null, explanation: null, ref: null });
}, [formParamForQuill]);
return (
<>
<div className="communication-template-quill">
<ReactQuill
ref={editorRef}
modules={!shouldHideToolbar ? textEditorOptions : editorOptions}
value={typeof quillState.description === "string" ? quillState.description : quillState.description.join("")}
onChange={value => handleQuillChange(value)}
/>
</div>
</>
);
});
export default TemplateEditor;
'data' passed onto the editor component as a prop is the initial HTML response attached above. However, when the quill state is set with this 'data', quill state then becomes this (state modified by react-quill (attached below)), which does not preserve the original HTML thus leaving us with a messed up layout.
<p>FINROTA <a href=\"https://**.**.com/\" rel=\"noopener noreferrer\" target=\"_blank\">
<img src=\"https://*****.com/-/-/-/-.png\" alt=\"finrota-logo\" height=\"30\" width=\"120\">
</a>
<img src=\"https://*****.com/static/images/mailing/pay.png\" alt=\"top-images\" height=\"128\" width=\"123\"> Sayın <strong style=\"color: rgb(16, 16, 16);\">{{-}},</strong>
</p>
<p>---</p>
<p>---</p>
<p>
<strong>** ** **</strong> Sistem Destek E-Mail: <strong> **#**.com </strong> Telefon: <strong> 0(**) ** ** 00 </strong> Fax: <strong> 0(**) ** ** 00 </strong>
<a href=\"https://twitter.com/*****\" rel=\"noopener noreferrer\" target=\"_blank\">
<img src=\"https://******.com/static/images/mailing/twitter.png\" alt=\"twitter\" height=\"32\" width=\"32\">
</a>
<a href=\"https://www.linkedin.com/company/*****/mycompany/\" rel=\"noopener noreferrer\" target=\"_blank\">
<img src=\"https://*****.com/static/images/mailing/linkedin.png\" alt=\"linkedin\" height=\"32\" width=\"32\">
</a>
<a href=\"https://www.facebook.com/*****/\" rel=\"noopener noreferrer\" target=\"_blank\">
<img src=\"https://*****.com/static/images/mailing/facebook.png\" alt=\"facebook\" height=\"32\" width=\"32\">
</a>
<a href=\"https://www.instagram.com/EcozumAS/\" rel=\"noopener noreferrer\" target=\"_blank\">
<img src=\"https://*****.com/static/images/mailing/instagram.png\" alt=\"instagram\" height=\"32\" width=\"32\">
</a>
</p>
How could the original HTML be preserved ? How do we overcome this styling issue ?
Short answer
No, you can't just throw any markup into a WYSIWYG editor and expect it to be able to perfectly work with the structure. These editors work with a subset of HTML.
Emails usually use ancient styling techniques. Even if Quill is able to correctly parse each tag and attribute, the result would likely be terrible to work with while editing. Emails often put everything in a table and need to add inline styles to work in older clients.
You can get part of the way there by only injecting the actual visible body content into Quill, not an entire HTML document.
The document head is not something that you could edit in a WYSIWYG editor. As you can see Quill just removes all tags it doesn't "know about" from around the content. Then it adds p tags around orphaned text. Hence you see the document title in the output as a paragraph.
1- We send the user a mail template
You only need to send the user the part of the template they can edit. The outer HTML is something that can be added by your server when the mail is finally sent.
The second problem is that the email content seems to be from a pre-existing application that formatted everything as tables. Also it contains a bunch of inline styles.
Quill is not a sophisticated HTML parser. (I mean, come on, it doesn't even remove the head tag) Neither is it very good at outputting HTML.
So if you want to convert this text to an email with that specific mark up, you'll have to do this conversion yourself from the tags and style attributes returned by Quill's content.
You'll probably also have to do a one time effort to convert these old templates into a format Quill can work with. Or write a function that can convert between the formats.
You could also try quil-better-table. It might improve Quill's ability to pick up table markup in the input.
If you're sending your emails with PHP, you could try quil-delta-parser or php-quil-renderer.
That way you can send Quill's "deltas" to your back end, and transform them to the right HTML at save time, or even when the email is sent.
You can install both with Composer.
composer require nadar/quill-delta-parser
or
composer require deanblackborough/php-quill-renderer
Both libraries seem flexible enough to make it output the styles you want based on which attributes are in Quill's delta.
In any case it's probably very challenging if not impossible to make Quill understand and return the exact same markup of the template you post. Much easier to just take whatever it outputs and transform it afterwards.

(Vue + Laravel) v-if / v-else inside <td> throws no matching end tag error

I apologize in advance if my question is silly-- Vue newbie here but very eager to learn!
In order to create an interface to manage user privileges in a web app, I've made a component in which I want to create a table with nested v-fors.
For each row, I want 5 cells (): the first one includes text depending on the current iteration of object permisos and the other 4 should be created from the object tipos_permisos (which is an object with 'fixed' values).
The problem:
When I try to compile, I get multiple errors claiming that some tags have no matching end tag. I assume it is due to the v-for nested inside another v-for and/or the v-if inside the innermost v-for... or something like this. The claim is that has no matching tag or that the element uses v-else without corresponding v-if :/
I've tried writing out the last 4 cells manually (without using the tipos_permisos object) but even then, I get errors. In this case, claiming that , and have no matching end tag.
The desired result:
Please note that for some of the resources listed, some of the privileges might not apply (i.e., the log viewer is read-only always so it doesn't have the C (create), U (update) or D (delete) privileges, hence the conditional to show either a checkbox or an icon)
My component:
<template>
<form :action="usr.url.savepermisos" method="post" class="">
<div class="card">
<div class="card-header bg-gd-primary">
<h3 class="card-title">Privilegios de {{ usr.nombre }}</h3>
</div>
<div class="card-content">
<p class="mb-3">
El usuario
<span class="font-w700">{{ usr.nombre }}</span>
tiene los siguientes privilegios:
</p>
<table class="table">
<thead>
<tr>
<th>Recurso</th>
<th>Alta / Creación</th>
<th>Visualización</th>
<th>Edición</th>
<th>Eliminación</th>
</tr>
</thead>
<tbody>
<tr v-for="(recurso, idxrecurso) in permisos">
<td :data-order="recurso.id">{{ recurso.etiqueta }}</td>
<td class="align-middle" v-for="(color,tp) in tipos_permisos">
<label :class="'checkbox checkbox-' + color + ' mycheckbox'" v-if="(typeof recurso[tp] !== "undefined")">
<input type="checkbox" class="checkbox-input check_permiso" />
<span class="checkbox-indicator"></span>
</label>
<i class="fas fa-minus-square fa-lg text-muted" data-toggle="tooltip" title="N/A" v-else></i>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</form>
</template>
<script>
export default {
data() {
return {
tipos_permisos: {
'C': 'success',
'R': 'info',
'U': 'warning',
'D': 'danger'
}
}
},
props: [
'usr',
'permisos',
'perm_log'
]
}
</script>
If something is unclear please let me know so that I can provide further info.
There is a missing "=" after v-for:
<td class="align-middle" v-for"(color,tp) in tipos_permisos">
I didn't understand this part:
v-if="(typeof recurso[tp] !== "undefined")"
If undefined in your code is a string, your condition should be
v-if="recurso[tp] !== 'undefined'"
If it's a real undefined, it should be like this:
v-if="recurso[tp] !== undefiened"

Laravel Blade foreach loop in Laravel-DOMPDF output file

I'm having issues using DOMPDF and Laravel Blade. I'm using DOMPDF to render a blade view into PDF following their documentation, but when I have records that span more than a page, it cuts them off. It's like overflow:hidden is added to the page so the records won't show. You can see by the image below. You can clearly see there is another record at the bottom, but the next page is qualifications, not the next record in the list.
I have tried using page breaks and all sorts to try and get this working, but for the life of me this just does not want to play ball.
I can't find anything in their documentation that suggests this is an issue and I'm not sure what's causing it.
Package used: barryvdh/laravel-dompdf
The rendered PDF:
The section of the view that's being loaded:
Please excuse the tables, but as PDFs don't load CSS3, I have to go back to basics to get the proper styling results needed for the PDF.
<tr>
<td class="border-b-4 border-grey-200 pb-5 mb-5">
<table width="100%" class="mb-5" style="width:100%" border="0" cellpadding="0">
<tr>
<td>
<h1 class="text-6 text-grey-700 mb-3">Employment History</h1>
</td>
</tr>
</table>
#foreach ($employers as $employer)
<table width="100%" class="mb-5" style="width:100%" border="0" cellpadding="0">
<tr>
<td class="border border-grey-200 p-5 rounded">
<h2 class="capitalize text-grey-700 text-lg">{{ $employer->job_title }}</h2>
<span class="text-grey-600">{{ $employer->employer_name }}</span>
<p class="my-3 text-blue-500 text-sm">
<span>{{ date('jS F Y', strtotime($employer->from_date)) }}</span>
<span> — </span>
#if ($employer->current != 1)
<span>{{ date('jS F Y', strtotime($employer->to_date)) }}</span>
#else
<span>Present</span>
#endif
</p>
<div class="markdown text-grey-700">{!! $employer->description !!}</div>
</td>
</tr>
</table>
#endforeach
</td>
</tr>
The PDF controller:
PDF::setOptions([
'dpi' => 150,
'defaultFont' => 'sans-serif',
'fontHeightRatio' => 1,
'isPhpEnabled' => true,
]);
$pdf = PDF::loadView('pdf_cv', [
'cv' => $cv,
'awards' => $awards,
'employers' => $employers,
'hobbies' => $hobbies,
'images' => $images,
'languages' => $languages,
'projects' => $projects,
'qualifications' => $qualifications,
'skills' => $skills
]);
return $pdf->stream();
I've done the Googling, read their documentation countless times and I'm bemused by this issue, so hopefully, someone else has experienced this too and can lend a helping hand.
If you need more information, I can provide it.
The issue with this was the table setup. I don't know exactly what was happening because you can't inspect PDFs but the table seemed to keep overlapping causing it run off the page.

Fallback (default) image using Angular JS ng-src

I'm trying to set an image source using data returned from a modal. This is inside an ng-repeat loop:
<div id="divNetworkGrid">
<div id="{{network.id}}" ng-repeat="network in networks">
<span>
<table>
<tr>
<td class="imgContainer">
<img ng-src="{{ ('assets/img/networkicons/'+ network.actual + '.png') ||
'assets/img/networkicons/default.png' }}"/>
</td>
</tr>
</table>
</span>
</div>
</div>
As is apparent, I want to populate default.png when the network.actual model property is returned as null. But my code is not picking up the default image, though the first image is coming up fine when available.
I'm sure this is some syntax issue, but cant figure out what's wrong.
I have just found out, that you can use both ng-src and src on an img tag and if ng-src fails (variable used does not exists etc.), it will automatically fallback to src attribute.
What I imagine is happening is the src is returning a 404 even if network.actual is null. For example, first value:
('assets/img/networkicons/'+network.actual+'.png')
is evaluating to a 404 src URL, something like ('assets/img/networkicons/null.png'). So in the OR selection, it's truth-y, but the resource is 404. In that case, you can set the fallback via onError with something like:
<img ng-src="{{('assets/img/networkicons/'+network.actual+'.png')}}" onerror="this.src='assets/img/networkicons/default.png'" />
CodePen to demo use cases - http://codepen.io/jpost-vlocity/pen/zqqerL
angular.module('fallback',[]).directive('fallbackSrc', function () {
return{
link: function postLink(scope, element, attrs) {
element.bind('error', function () {
angular.element(this).attr("src", attrs.fallbackSrc);
});
}
}
});
<img ng-src="{{url}}" fallback-src="default-image.jpg"/>
angular.module('fallback', []).directive('actualSrc', function () {
return{
link: function postLink(scope, element, attrs) {
attrs.$observe('actualSrc', function(newVal, oldVal){
if(newVal != undefined){
var img = new Image();
img.src = attrs.actualSrc;
angular.element(img).bind('load', function () {
element.attr("src", attrs.actualSrc);
});
}
});
}
}
});
<img actual-src="{{url}}" ng-src="default.jpg"/>
link
Interesting way to use ng-src. I haven't tested how that expression would be handled but I would suggest doing it a more stable way:
<img ng-src="{{ networkIcon }}" />
And in your controller:
$scope.networkIcon = network.actual ? 'assets/img/networkicons/' + network.actual + '.png' : 'assets/img/networkicons/default.png';
Edit: Just to clarify, I'm not suggesting the best way to do this is to bind the image source directly to the scope but rather to move the image fallback logic outside of the view. In my applications I often do it in the services that retrieve the data or on the server itself and send an image URL so the client only has to worry about a single property.
Edit to address repeater:
angular.forEach($scope.networks, function(network) {
network.icon = network.actual ? 'assets/img/networkicons/' + network.actual + '.png' : 'assets/img/networkicons/default.png';
});
<tr ng-repeat="network in networks">
<td><img ng-src="{{ network.icon }}" /></td>
</tr>
<div id="divNetworkGrid">
<div id="{{network.id}}" ng-repeat="network in networks">
<span>
<table>
<tr>
<td class="imgContainer">
<img ng-src="{{'assets/img/networkicons/'+(network.actual || 'default' )+'.png'}}"/>
</td>
</tr>
</table>
</span>
</div>
</div>
The inline or will work if the the queried variable is undefined. The above will fix your issue
You can supply the alternative image after OR operator like this:
{{ book.images.url || 'Images/default.gif' }}

image (img) within anchor (a) not rendering correctly

I am trying to understand what I'm doing wrong,
I have two elements, image withing anchor with no style.
some how the anchor dose not cover the image area.
example: http://jsfiddle.net/L4ShV/1/
<a href="javascript:void(0)" id="downloadLink" >
<img src="http://toonimo.com/testing/clients_tests/somoto/flv_player/images/nlp/free_download_btn.jpg" border="0" style="width: 373px;height: 120px;" />
</a>
<div>
<h1>a dimantions:</h1>
width: <span id='width_c'></span><br>
height: <span id='height_c'></span><br>
<br>
when clearly its not possible!
How can i get the Real height?
</div>
<script>
var el = document.getElementById('downloadLink');
document.getElementById('width_c').innerHTML = el.offsetWidth;
document.getElementById('height_c').innerHTML = el.offsetHeight;
</script>
any reason or solution for this problem?
That is a normal behaviour of anchor as it expects for block-level elements. You can float a to cover the image.
<a href="javascript:void(0)" id="downloadLink" style="float:left">

Resources