The code samples that I posted were meant to illustrate how to implement the print to window functionality into your own scripts, not to be used as a step by step guide.
Here is a tutorial to add the print to window functionality to the Contact entity:
First we need to let EspoCRM know that we want to use a custom view to render the Contact detail display, which is where the "Print to Window" drop down menu option will appear and we do this by creating a custom clientDefs file for "Contact" as follows:
custom\Espo\Custom\Resources\metadata\clientDefs\C ontact.json
Code:
{
"recordViews": {
"detail": "custom:views/contact/record/detail"
}
}
client\custom\src\views\contact\record\detail.js
Code:
Espo.define('custom:views/contact/record/detail', 'crm:views/contact/record/detail', function (Dep) {
return Dep.extend({
setupActionItems: function () {
Dep.prototype.setupActionItems.call(this);
this.dropdownItemList.push({
name: 'printWindow',
label: 'Print to Window'
});
},
// print a record to a new window using a template
actionPrintWindow: function () {
// find out if the model has a templateId attribute
if(this.model.attributes.templateId) {
var templateId = this.model.attributes.templateId;
window.open('?entryPoint=printToWindow&entityType='+this.model.name+'&entityId='+this.model.id+'&templateId=' + templateId, '_blank');
// if not, open the select template model and wait for the user to select a template
} else {
this.createView('windowTemplate', 'views/modals/select-template', {
entityType: this.model.name
}, function (view) {
view.render();
this.listenToOnce(view, 'select', function (model) {
this.clearView('windowTemplate');
window.open('?entryPoint=printToWindow&entityType='+this.model.name+'&entityId='+this.model.id+'&templateId=' + model.id, '_blank');
}, this);
});
}
}
});
});
Function "actionPrintWindow" will look for a Template object already linked to the Contact object or it will display a modal window to allow the user to select the template to be used to render the Contact object.
Once a template is defined, the function will invoke a back end Entry Point:
custom\Espo\Custom\EntryPoints\PrintToWindow.php
Code:
namespace Espo\Custom\EntryPoints;
use \Espo\Core\Exceptions\NotFound;
use \Espo\Core\Exceptions\BadRequest;
class PrintToWindow extends \Espo\Core\EntryPoints\Base {
public static $authRequired = true;
public function run() {
if (empty($_GET['entityId']) || empty($_GET['entityType']) || empty($_GET['templateId'])) {
throw new BadRequest();
}
$entityId = $_GET['entityId'];
$entityType = $_GET['entityType'];
$templateId = $_GET['templateId'];
$entity = $this->getEntityManager()->getEntity($entityType, $entityId);
$template = $this->getEntityManager()->getEntity('Template', $templateId);
if (!$entity || !$template) {
throw new NotFound();
}
$this->getContainer()->get('serviceFactory')->create('PrintToWindowService')->buildFromTemplate($entity, $template, true);
exit;
}
}
custom\Espo\Custom\Services\PrintToWindowService.p hp
Code:
namespace Espo\Custom\Services;
use \Espo\Core\Exceptions\Forbidden;
use \Espo\Core\Exceptions\NotFound;
use \Espo\Core\Exceptions\Error;
use \Espo\ORM\Entity;
use \Espo\Core\Htmlizer\Htmlizer;
class PrintToWindowService extends \Espo\Core\Services\Base {
protected $fontFace = 'freesans';
protected $fontSize = 10;
protected $removeMassFilePeriod = '1 hour';
protected function init() {
$this->addDependency('fileManager');
$this->addDependency('acl');
$this->addDependency('metadata');
$this->addDependency('serviceFactory');
$this->addDependency('dateTime');
$this->addDependency('number');
$this->addDependency('entityManager');
$this->addDependency('defaultLanguage');
}
protected function getAcl() {
return $this->getInjection('acl');
}
protected function getMetadata() {
return $this->getInjection('metadata');
}
protected function getServiceFactory() {
return $this->getInjection('serviceFactory');
}
protected function getFileManager() {
return $this->getInjection('fileManager');
}
protected function createHtmlizer() {
return new Htmlizer(
$this->getFileManager(),
$this->getInjection('dateTime'),
$this->getInjection('number'),
$this->getAcl(),
$this->getInjection('entityManager'),
$this->getInjection('metadata'),
$this->getInjection('defaultLanguage')
);
}
protected function printEntity(Entity $entity, Entity $template, Htmlizer $htmlizer) {
$htmlFooter='';
$pageOrientation = 'Portrait';
$pageFormat = 'A4';
if ($template->get('fontFace')) {
$fontFace = $template->get('fontFace');
}
if ($template->get('printFooter')) {
$htmlFooter = $htmlizer->render($entity, $template->get('footer'));
}
if ($template->get('pageOrientation')) {
$pageOrientation = $template->get('pageOrientation');
}
if ($template->get('pageFormat')) {
$pageFormat = $template->get('pageFormat');
}
$htmlHeader = $htmlizer->render($entity, $template->get('header'));
$htmlBody = $htmlizer->render($entity, $template->get('body'));
return $htmlHeader.$htmlBody.$htmlFooter;
}
public function buildFromTemplate(Entity $entity, Entity $template) {
$entityType = $entity->getEntityType();
$service = $this->getServiceFactory()->create($entityType);
$service->loadAdditionalFields($entity);
if ($template->get('entityType') !== $entityType) {
throw new Forbidden();
}
if (!$this->getAcl()->check($entity, 'read') || !$this->getAcl()->check($template, 'read')) {
throw new Forbidden();
}
$htmlizer = $this->createHtmlizer();
$output = $this->printEntity($entity, $template, $htmlizer);
echo $output;
}
}
Files PrintToWindow.php and PrintToWindowService.php can now be downloaded as a package here: https://github.com/telecastg/print-t...ow-for-espocrm
Changes to client\custom\src\views\contact\record\detail.js and to custom\Espo\Custom\Resources\metadata\clientDefs\C ontact.json remain the same
UPDATE for Espo 7.x +
Unfortunately Espo Core has been heavily refactored and previous custom implementations are no longer compatible. The files above are no longer available and using the old scripts will trigger errors.

Leave a comment: