render multiple inline boxes/tables in xhtml2pdf - pdf-generation

I'm using xhtml2pdf library with Djanog to generate PDF reports. I am trying to generate a report where I'll be able to print multiple boxes for the context data.
Seems div width is not detected in xhtml2pdf, and my tables doesn't stay inlined as well.
Here's what I have done so far:
<!DOCTYPE html>
<html lang="en">
<head>
<style>
#page {
size: a4 landscape;
margin: 2cm;
}
</style>
</head>
<body>
{% for item in items %}
<table style="width: 20%; background-color: red;">
<tr style="width: 30%;">
<td style="width: 30%;">
<img class="logo" src="{{item.barcode | barcode_image}}" alt="Barcode" />
<p>{{ item.product_name }}</p> <br>
<small id="price">MRP: {{ barcode_item.price }} TK</small>
{% endif %}
</td>
</tr>
</table>
{% endfor %}
</body>
</html>
This code results:
Expected Result Format/Layout:
Is there any way to print the expected layout using xhtml2pdf?

Related

Why are images not showing until the window is resized?

I am utilizing the modal from Zurb Foundation and some Liquid. Running into a strange issue. Images in the modal are being rendered to the DOM, but only show up when the screen is resized either smaller or larger.
Here is the code I am working with (yes, some elements have in-line styles specified).
<div class="grid-x align-middle grid-margin-x grid-margin-y small-up-1 medium-up-2 large-up-3 padding text-center">
{% for item in this.items %}
<div data-open="wa-project-{{forloop.index}}" class="cell" style="background-image:url('{{item['Image1']}}?mode=max&height=270'); height: 270px; width: 340px; background-size:cover; background-position:center; background-color:#00577d; margin: 12px auto;">
<div class="grid-y" style="height:270px; width:100%; background-color:rgba(0,25,36,.5)">
<div class="cell auto"></div>
<div class="cell shrink padding">
<div><a class="color-white" alt="{{item['Name']}} link">{{item['Name']}}</a></div>
<hr style="width: 125px; margin: 20px auto 0 auto; border-top-color: #8dd535">
</div>
<div class="cell auto"></div>
</div>
</div>
<!-- Modal -->
<div class="reveal" id="wa-project-{{forloop.index}}" data-reveal data-animation-in="scale-in-up" data-overlay="true">
<div class="orbit" role="region" aria-label="GoMedia Projects" data-orbit>
<div class="orbit-controls">
<button class="orbit-previous"><span class="show-for-sr">Previous Slide</span>◀︎</button>
<button class="orbit-next"><span class="show-for-sr">Next Slide</span>▶︎</button>
</div>
<ul class="orbit-container">
{% if item.image1 != "" %}
<li class="orbit-slide is-active">
<figure class="orbit-figure">
<img class="orbit-image" src="{{item.image1}}?mode=max&width=600" alt="space">
</figure>
</li>
{% endif %}
{% if item.image2 != "" %}
<li class="orbit-slide">
<figure class="orbit-figure">
<img class="orbit-image" src="{{item['Image2']}}?mode=max&width=600" alt="Space">
</figure>
</li>
{% endif %}
{% if item.image3 != "" %}
<li class="orbit-slide">
<figure class="orbit-figure">
<img class="orbit-image" src="{{item['Image3']}}?mode=max&width=600" alt="Space">
</figure>
</li>
{% endif %}
{% if item.image4 != "" %}
<li class="orbit-slide">
<figure class="orbit-figure">
<img class="orbit-image" src="{{item['Image4']}}?mode=max&width=600" alt="Space">
</figure>
</li>
{% endif %}
</ul>
</div>
<h2 class="fontsize-30">{{item.name}}</h2>
<hr style="width: 100%; border-top-color: #8dd535">
<p>{{item.description}}</p>
<button class="close-button" data-close aria-label="Close modal" type="button">
<i class="fas fa-times-circle"></i>
</button>
</div>
{% endfor %}
</div>
I've been researching for a bit, but have not found an answer. A height and width is specified for the images in the CSS. I am seeing it happen across multiple browsers: Firefox, Chrome, Safari. I have even tried starting from scratch with the Zurb Foundation template for the modal to no avail.

Laravel Mail issue using nested #components with markdown

I am experiencing a problem where the code works but sometimes it fails to display the proper info in the outermost #component; the logo it shows is wrong, like if it's caching the outermost layout and using it on the next call, but with outdated info
The issue happens while sending emails, which are run on queues.
The relevant part of the code is as follows:
1: the mail I'm trying to send (works 100% of the time)
markdown.blade.php
#component('mail::message')
# #lang('emails.bookingRequestReceipt', ['user' => $association->person->account->first_name, 'school' => $bookingRequest->school->name])
{!! html_entity_decode($custom_intro) ?? '' !!}
#endcomponent
2: the message component (works 100% of the time)
#component('mail::layout')
<!-- THIS IS THE RELEVANT PART -->
{{-- Header --}}
#slot('header')
#component('mail::header', ['url' => $school['url'] ?? config('app.url')])
#if(!empty($school['logo']) && !$school['logo']['default'])
<img src="{{ $school['logo']['url'] }}" class="logo" alt="{{ $school['logo']['alt'] }}" />
#elseif(empty($school))
<img src="https://[redacted]/public/img/logo.png" class="logo" alt="{{ config('app.name') }}" />
#else
{{ $school->name }}
#endif
#endcomponent
#endslot
<!-- END OF RELEVANT PART -->
{{-- Body --}}
{{ $slot }}
#endcomponent
3: the layout (fails)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<table class="wrapper" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<tr>
<td align="center">
<table class="content" width="100%" cellpadding="0" cellspacing="0" role="presentation">
<!-- THIS IS THE RELEVANT PART -->
{{ $header ?? '' }}
<!-- END OF RELEVANT PART -->
<!-- Email Body -->
<tr>
<td class="body" width="100%" cellpadding="0" cellspacing="0">
<table class="inner-body" align="center" width="570" cellpadding="0" cellspacing="0" role="presentation">
<!-- Body content -->
<tr>
<td class="content-cell">
{{ Illuminate\Mail\Markdown::parse($slot) }}
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
Any idea what I'm doing wrong? The informations regarding the $school inside the message are always correct
Is it beacause I haven' used php artisan make:component to create the layout?
EDIT: removed leftover code
I've added the mail files you provided locally to test whats causing the issues. Without knowing how and what you are returning from your Mail class (return $this->markdown(...) ??), I noticed a few things about the code examples:
About the wrong shown logo:
You aren't passing the $school variable to the message blade, so your logo never could be shown and the #elseif(empty($school)) will always be true.
// message.blade.php
#component('mail::message', ['school' => $school])
Your message.blade.php contains too many #end directives, the last two # directives causing errors in the blade, remove these:
...
{{-- Body --}}
{{ $slot }}
#endcomponent
{{-- #endslot -- }} // Causes problems
{{-- #endcomponent -- }} // Causes problems
If I fix the code snippets you provided like I explained in the steps above, everything is working fine.
Please let me know if this fix your problems.
In this case, if you are sure 100% that all code lines are correct. Then it would be best if you tried to restart the queue worker on the server.

#yield working on home page, but not on other pages using same layout

Really scratching my head on this one. I'm hoping a fresh pair of eyes can spot my error.
I've got a section heading on each page, but the heading is only showing on home.blade.php but not other pages.
master.blade.php
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="csrf-token" content="{{ csrf_token() }}" />
<title>#yield('title')</title>
#stack('styles')
</head>
<body class="bg-light">
<div class="container-fluid h-100">
#yield('app')
</div>
#include('sweetalert::alert')
{{ Session::forget('alert') }}
#stack('scripts')
</body>
</html>
app.blade.php
#extends('layout.master')
#prepend('styles')
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/flatpickr/dist/flatpickr.min.css">
<link rel="stylesheet" type="text/css" href="{{ URL::asset('css/overrides.css') }}" />
#endprepend
#section('app')
<div class="row">
<div class="col-12 no-padding">
#include('layout.includes.header')
</div>
</div>
<div class="row h-100">
<div class="col-12">
<!-- Begin nav/content row -->
<div class="row h-100">
<div id="sidebar-wrapper" class="visible">
#include('layout.includes.nav')
</div>
<!-- Begin main column -->
<div class="col content" style="overflow-x:auto;">
#if (Request::path() === '/')
<div class="row no-padding">
<div class="col d-none d-sm-block">
<h4>#yield('content-heading')</h4> <!-- [my #yield directive is here] -->
</div>
<div class="col flex-grow-1">
#include('layout.includes.searchform')
</div>
</div>
#endif
<div class="row no-padding inner-box shadow p-3 mb-5 bg-white rounded">
#yield('content')
</div>
</div>
<!-- END main column-->
</div>
<!-- END nav/content row-->
</div>
</div>
#endsection
#prepend('scripts')
#include('layout.js.footer-js')
#yield('form-js')
#endprepend
home.blade.php
#extends('layout.app')
#section('title', 'Asset Management')
#section('content-heading', 'View All Assets') //This works
#section('content')
<div class="table-responsive">
<table class="table table-striped text-nowrap">
<caption>Recently Added Assets</caption>
<thead>
<tr>
<th scope="col">Tag #</th>
<th scope="col">Type</th>
<th scope="col">Device</th>
<th scope="col">Serial #</th>
<th scope="col">Assigned</th>
<th scope="col">To</th>
<th scope="col">Status</th>
</tr>
</thead>
<tbody>
#foreach ($assets as $asset)
<tr>
<td>{{ $asset->asset_tag }}</td>
<td>{{ $asset->cat_name }}</td>
<td>{{ $asset->man_name }} {{ $asset->model_name }}</td>
<td>{{ $asset->serial }}</span></td>
<td>{{ \Carbon\Carbon::parse($asset->assign_date)->format('D M d, Y g:iA') }}</td>
<td>{{ $asset->name }}</td>
<td>{{ $asset->status }}</td>
</tr>
#endforeach
</tbody>
</table>
</div>
#endsection
#section('form-js')
#endsection
#push('scripts')
#endpush
My other pages are all laid out the same as home.blade.php, e.g:
#extends('layout.app')
#section('title', 'Checkout Asset')
#section('content-heading', 'Checkout Asset') //Does not output to template
#section('content')
Content here...
#endsection
#push('scripts')
#endpush
Why is <h4>#yield('content-heading')</h4> only working on home.blade.php?
The code which displays #yield('content-heading') is wrapped in:
#if (Request::path() === '/')
...
#endif
which is restricting the display to just that url.
:)

Vue.js and Laravel integration issue

Ran into a bit of a problem with combining Laravel and Vue.js to populate a table.
Essentially, I was trying to use the v-repeat property in combination with a http:get request using the vue-resources extension. The problem is that no values appear to be getting passed through by Vue - I simply get the {{first_name}} and {{email_address}} in brackets.
I can confirm that the API method that is called by the http:get request is in fact spitting out data (manually accessing the URL in the browser reveals data).
Here is the code in the routes.php file that is responsible for outputting the data:
get('api/v1_users',function()
{
return App\User::all()->toJson();
});
And here is what it spits out in the browser:
[{"email_address":"test123#gmail.com,"first_name":"John","password":"test123"}]
The Chrome console displays no errors nor warnings.
Here is my blade file:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="../../favicon.ico">
<title>Navbar Template for Bootstrap</title>
<!-- Bootstrap core CSS -->
<link media="all" type="text/css" rel="stylesheet" href="{{ URL::asset('css/bootstrap.min.css') }}">
<!-- Custom styles for this template -->
{!! Html::style('css/navbar.css') !!}
</head>
<body>
<div class="container">
<!-- Static navbar -->
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">User Password Operations</a>
</div>
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="inactive">Reset New User</li>
<li class="inactive">Pending Users</li>
</ul>
</div><!--/.nav-collapse -->
</div><!--/.container-fluid -->
</nav>
<!-- Main component for a primary marketing message or call to action -->
<div class="jumbotron">
<h1>Pending 1.0 Users</h1>
<p>A list of 1.0 users that have a change!me password as a result of this tool, and are awaiting password change.</p>
</div>
<table class="table table-bordered">
<tr>
<td>
<b>Name</b>
</td>
<td>
<b>Email</b>
</td>
<td>
<b>Select</b>
</td>
</tr>
<div id = "user">
<tr v-repeat = "user: v1_user">
<td>
#{{ first_name }}
</td>
<td>
#{{ email_address }}
</td>
<td>
<button type="button" class="btn btn-success">Revert Password To Original</button>
</td>
</tr>
</div>
</table>
<div class="jumbotron">
<h1>Pending 2.0 Users</h1>
<p>A list of 2.0 users that have a change!me password as a result of this tool, and are awaiting password change.</p>
</div>
<table class="table table-bordered">
<tr>
<td>
<b>Name</b>
</td>
<td>
<b>Email</b>
</td>
<td>
<b>Select</b>
</td>
</tr>
<div>
<tr v-repeat = "user: v1_user">
<td>
#{{user.first_name}}
</td>
<td>
#{{user.email_address}}
</td>
<td>
<button type="button" class="btn btn-success" v-on= "click: onClick">Revert Password To Original</button>
</td>
</tr>
</div>
</table>
</div> <!-- /container -->
<!-- Bootstrap core JavaScript
================================================== -->
<!-- Placed at the end of the document so the pages load faster -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<!-- Vue.js file REP -->
<script src="/js/vue.js"></script>
<script src="/js/vue-resource.min.js"></script>
<!-- Main Vue file-->
<script src="/js/main.js"></script>
</body>
</html>
Here is the accompanying javascript file with the Vue.js code: (main.js)
new Vue({
el: "#user",
data:
{
v1_user:[],
},
ready : function()
{
this.fetchV1IntermediaryUsers();
},
methods:
{
fetchV1IntermediaryUsers: function() {
this.$http.get('/api/v1_users',function(v1users) {
this.$set('v1_user',v1users);
});
}
}
});
You have multiple DIV's with the same ID's. ID's in HTML must be unique. When you start a VUE instance you bind it to an element, in this case which is in your code twice. Remove the ID's and add an ID to the <Body> tag, then check your code.

CKeditor - How can I append <article> tags to the editable content body?

Trying to add <article> tag inside the body of CKeditor, so like this:
<iframe frameborder="0" src="" style="width: 100%; height: 100%;" class="cke_wysiwyg_frame cke_reset" title="Rich Text Editor, editor1" aria-describedby="cke_50" tabindex="0" allowtransparency="true">
<html lang="en" dir="ltr">
<body spellcheck="false" class="cke_editable cke_editable_themed cke_contents_ltr" contenteditable="true">
<article> <!-- Add this -->
<p>Content</p>
</article> <!-- Add this -->
</body>
</html>
</iframe>
Could not find how to get this into the editor. Any tips on how to go about this?

Resources