WebGUI Developers Workshop
-
Upload
plain-black-corporation -
Category
Technology
-
view
2.136 -
download
2
description
Transcript of WebGUI Developers Workshop
![Page 1: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/1.jpg)
WEBGUI DEV 101WebGUI Developer Workshop
![Page 2: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/2.jpg)
![Page 3: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/3.jpg)
INSTALL WEBGUI
![Page 4: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/4.jpg)
USB Drive
Copy the WebGUI Workshop folder to your hard disk
Pass the USB Drive off to someone else
(You’re going to need ~6GB of free space.)
![Page 5: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/5.jpg)
Install
Install VMWare Player (or Fusion if on Mac)
Decompress the Zip File
Open VMWare
Browse to the folder where you extracted WebGUI
Open WebGUI
(If you already have VMWare Player 2 or higher you can ignore this.)
![Page 6: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/6.jpg)
Test The Image
In the VMWare window log in to the command line
It should tell you what IP address to visit
Open your web browser and go to that IP address
![Page 7: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/7.jpg)
File Share
You can access the VM’s filesystem from your computer
Windows: \\192.168.47.131\data
Mac/Linux: cifs://192.168.47.131/data
Username: webgui
Password: 123qwe
(The IP may bedifferent on your
install.)
![Page 8: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/8.jpg)
CORPORATE PERL
![Page 9: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/9.jpg)
Fred Rogers Foundation
OUR USERSAnd 10000+ more...
![Page 10: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/10.jpg)
0
750,000
1,500,000
2,250,000
3,000,000
WebGUI®
MS Sharepoint®Oracle Portals®
Licensing Implementation Hardware
Figures based upon an actual client intranet project that was built in both Oracle Portals® and WebGUI®, and estimated for MS Sharepoint®.
0
20
40
60
80
Site Online Base Apps Full Suite
WebGUI® Oracle Portals®
Physical Cost (Dollars) Time Cost (Months)
![Page 11: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/11.jpg)
WEBGUI DEMO
![Page 12: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/12.jpg)
THE API
![Page 13: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/13.jpg)
Sprawling API
WebGUI’s API is huge, can’t cover it all today.
Your brain will hurt without it anyway.
View the full API at:http://www.plainblack.com/downloads/builds/7.7.20-stable/api/ - or -perldoc /data/WebGUI/lib/WebGUI/User.pm
We’ll cover some basics now, and the rest as we go.
![Page 14: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/14.jpg)
Application FrameworkApplication FrameworkApplication FrameworkApplication Framework
Plugin PointsPlugin PointsPlugin PointsPlugin Points
Template Processors Shipping Methods Payment Methods Product Types
Taxes Form Controls Cache Utility Scripts
Translations Content Packages Workflow Activities Authentication Handlers
Macros Assets URL Handlers Content Handlers
Core APICore APICore APICore API
File Storage Image Processing Search Sessions
Database Access HTTP Interaction Mail LDAP Access
Users Groups Privileges Other Utilities
DatabaseDatabaseDatabaseDatabase
![Page 15: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/15.jpg)
WRITING MACROS
![Page 16: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/16.jpg)
WebGUI::Session
$session is the circulatory and nervous system of WebGUI
Here’s how you create or reopen one:my $session = WebGUI::Session->open($rootPath, $config);
Here’s how you close one:$session->close;
Here’s how you destroy one:$session->var->end;$session->close;
![Page 17: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/17.jpg)
Macros Are Easy
Used to put programmer power into an easy package content publishers can handle.
Macros reside in /data/WebGUI/lib/WebGUI/Macro
Single subroutine API
Gets a single argument, $session
Start by copying the _macro.skeleton file.
![Page 18: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/18.jpg)
Hello Worldpackage WebGUI::Macro::HelloWorld;
use strict;
sub process {my ($session) = @_;return ‘Hello World!’;
}
1;
![Page 19: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/19.jpg)
YOU DO IT
![Page 20: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/20.jpg)
Hello Worldpackage WebGUI::Macro::HelloWorld;
use strict;
sub process {my ($session) = @_;return ‘Hello World!’;
}
1;
![Page 21: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/21.jpg)
How do we know it works?
In your workshop folder find macroRunner.pl
Copy into /data/WebGUI/sbin
Type: perl macroRunner.pl \--config=www.example.com.conf \--macro=HelloWorld
And you should get:Hello World!
![Page 22: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/22.jpg)
Install It
Edit /data/WebGUI/etc/www.example.com.conf
Find the ‘macros’ section
Add the following to your config file:
“HelloWorld” : “HelloWorld”,
![Page 23: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/23.jpg)
Use It
wreservice.pl --restart modperl
Adding the following to your content:^HelloWorld;
Should produce:Hello World!
![Page 24: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/24.jpg)
$session | Current User
A reference to the current user:my $user = $session->user;
ISA WebGUI::User object.
Get a param:my $username = $user->username;
Set a param:$user->username($username);
![Page 25: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/25.jpg)
Username Macro
Create a macro called ‘Username’
Output the current user’s username.
WRITE IT!
Hint: $session->user
Hint 2: $session->user->username
![Page 26: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/26.jpg)
Usernamepackage WebGUI::Macro::Username;
use strict;
sub process {my ($session) = @_;return $session->user->username;
}
1;
![Page 27: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/27.jpg)
Does it work?
Test itmacroRunner.pl
Use it^Username;
![Page 28: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/28.jpg)
Macros Can Have Params
^Sum(1,2,3,4,5);
Should produce: 15
Parameters are passed in to process() after $session
WRITE IT!
Hint: my ($session, @args) = @_;
Hint 2: $total += $_ foreach @args;
![Page 29: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/29.jpg)
Sumpackage WebGUI::Macro::Sum;
use strict;
sub process {my ($session, @args) = @_;my $total = 0;$total += $_ foreach @args;return $total;
}
1;
![Page 30: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/30.jpg)
Does it work?
Test itmacroRunner.pl
Use it^Sum(1,2,3,4,5);
![Page 31: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/31.jpg)
WRITING CONTENT HANDLERS
![Page 32: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/32.jpg)
Content Handlers Are Powerful
As easy to write as a macro, but way more powerful.
Can write a full web app with just a content handler.
Used mainly for writing simple round trip services.
Receives a single parameter of $session.
![Page 33: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/33.jpg)
Hello Worldpackage WebGUI::Content::HelloWorld;
use strict;
sub handler {my ($session) = @_;return ‘Hello World!’;
}
1;
![Page 34: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/34.jpg)
YOU DO IT
![Page 35: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/35.jpg)
Hello Worldpackage WebGUI::Content::HelloWorld;
use strict;
sub handler {my ($session) = @_;return ‘Hello World!’;
}
1;
![Page 36: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/36.jpg)
Install It
Edit /data/WebGUI/etc/www.example.com.conf
Find the ‘contentHandlers’ section
Add the following to your config file:
“WebGUI::Content::HelloWorld”,
Order is important. If something returns content before your content handler, then your content handler will never be called.
![Page 37: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/37.jpg)
Use It
Visiting http://localhost:8081/
Should produce:Hello World!
![Page 38: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/38.jpg)
$session | Forms
A reference to the form processormy $form = $session->form
Fetch a form parametermy $value = $form->get(“foo”);
Validate it against a specific field typemy $value = $form->get(“foo”,”integer”);
![Page 39: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/39.jpg)
Conditionality
Content handlers should be conditional
Based on some setting
A specific URL
A parameter in the URL
A time of day
Anything else you choose
![Page 40: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/40.jpg)
Conditional Hello World
Modify HelloWorld so that it only displays if a form parameter called ‘op’ has a value of ‘helloworld’.
WRITE IT!
Hint: my $value = $session->form->get(‘op’);
![Page 41: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/41.jpg)
Hello Worldpackage WebGUI::Content::HelloWorld;
use strict;
sub handler {my ($session) = @_;if ($session->form->get(‘op’) eq ‘helloworld’) {
return ‘Hello World!’;}return undef;
}
1;
![Page 42: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/42.jpg)
SumTask:
Triggered by form variable called ‘op=Sum’
User enters comma separated list of numbers in form variable called ‘values’
Sum them
Display the result
Test: http://localhost:8081/?op=Sum;values=1,2,3,4,5
WRITE IT!
![Page 43: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/43.jpg)
Sumpackage WebGUI::Content::Sum;use strict;
sub handler {my ($session) = @_;if ($session->form->get(‘op’) eq ‘Sum’) {
my @values = split(‘,’, $session->form->get(‘values’));my $total = 0;$total += $_ foreach @values;return $total
}return undef;
}1;
![Page 44: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/44.jpg)
WebGUI::HTMLForm
Draw forms quickly and easily.
Simple OO API
Dozens of form controls already in existence
![Page 45: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/45.jpg)
Making A Formuse WebGUI::HTMLForm;my $f = WebGUI::HTMLForm->new($session);$f->hidden( name=>”ip”, value=>$ip );$f->text( name=>”username”, label=>”Username”);$f->integer( name=>”guess”, label=>”Pick a number”);$f->date( name=>”birthday”, label=>”Birth Date”);$f->submit;return $f->print;
![Page 46: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/46.jpg)
Sum with Form
Task:
Now add a form to make it easier for users to use
WRITE IT!
Hint: my $f = WebGUI::HTMLForm->new($session);
![Page 47: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/47.jpg)
Sumuse WebGUI::HTMLForm;
my $f = WebGUI::HTMLForm->new($session);$f->hidden( name=>’op’, value=>’Sum’ );$f->text( name=>’values’, defaultValue=>$session->form->get(‘values’), label => ‘Values to Sum’, subtext => ‘Separated by commas’);$f->submit;
return $total . “<br />” . $f->print;
![Page 48: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/48.jpg)
$session | Styles
You can easily wrap output in a style to make it prettier.
You get the style reference from $session.my $style = $session->style;
Then you just wrap your output in the style using the userStyle() method.return $style->userStyle($output);
![Page 49: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/49.jpg)
Sum with Style
Add a style wrapper to Sum
WRITE IT!
![Page 50: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/50.jpg)
Sum
return $session->style->userStyle($total . “<br />” . $f->print);
![Page 51: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/51.jpg)
OTHER PLUGINS
![Page 52: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/52.jpg)
So Far
Macros
Content Handlers
But there are 17 plugin types for WebGUI currently
![Page 53: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/53.jpg)
URL Handler
Like a content handler, but has direct access to the Apache request cycle
![Page 54: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/54.jpg)
Asset
The main content application object.
Features version control, metadata, direct URLs, and lineage based relationships
![Page 55: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/55.jpg)
Packages
Bundle asset configurations as a importable package.
![Page 56: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/56.jpg)
Sku
A special type of asset that plugs into WebGUI shop as a sellable item.
![Page 57: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/57.jpg)
Auth
Customize the authentication / login process.
![Page 58: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/58.jpg)
i18n / Help
i18n allows you to internationalize any other plugins
Help allows you to document your plugins using the i18n system.
![Page 59: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/59.jpg)
Shipping , Payment, and Tax Drivers
Tie in to shippers like UPS, Fedex, USPS, DHL, etc.
Tie in to payment gateways like PayPal, Google Checkout, Authorize.net, etc.
Tie in to various tax mechanisms set up by regional governments.
![Page 60: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/60.jpg)
Template Engine
Tie your own template parsers to WebGUI.
![Page 61: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/61.jpg)
Workflow Activities
Extend the workflow engine to run your asynchronous tasks
![Page 62: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/62.jpg)
Utility Scripts
Run maintenance and administrative tasks from the command line.
![Page 63: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/63.jpg)
Form Controls
Add to the more than two dozen form controls with input validation already in the system.
![Page 64: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/64.jpg)
Cache
Add new ways of speeding up WebGUI by caching complex items.
![Page 65: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/65.jpg)
QUESTIONS?
![Page 66: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/66.jpg)
APPENDIX
![Page 67: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/67.jpg)
Database
A reference to your WebGUI database:my $db = $session->db;
ISA WebGUI::SQL object.
Read:my $sth = $db->read($sql, \@params);
Write:$db->write($sql, \@params);
![Page 68: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/68.jpg)
Database CRUD
Create:my $id = $db->setRow($table, $keyname, \%properties);
Read:my $row = $db->getRow($table, $keyname, $id);
Update:$db->setRow($table, $keyname, \%properties);
Delete:$db->deleteRow($table, $keyname, $id);
![Page 69: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/69.jpg)
Database Helpers
Get a rowmy @array = $db->quickArray($sql, \@params);my %hash = $db->quickHash($sql, \@params);
Get a columnmy @array = $db->buildArray($sql, \@params);my %hash = $db->buildHash($sql, \@params);
Get a single column from a single rowmy $scalar = $db->quickScalar($sql, \@params);
![Page 70: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/70.jpg)
Log
A reference to the log filemy $log = $session->log;
Write to the log$log->error($message);$log->warn($message);$log->info($message);$log->debug($message);
![Page 71: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/71.jpg)
HTTP
Interact with HTTPmy $http = $session->http;
Set a redirect$http->setRedirect($url);
Send header$http->sendHeader;
![Page 72: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/72.jpg)
HTTP Continued
Set headers$http->setCacheControl($seconds);$http->setCookie($name, $value);$http->setMimeType(‘text/xml’);$http->setFilename($filename, $mimetype);$http->setStatus(404,$notFoundMessage);
Get Cookiesmy $hashRef = $http->getCookies;
![Page 73: WebGUI Developers Workshop](https://reader038.fdocuments.us/reader038/viewer/2022110307/55614d6dd8b42a857d8b4c3f/html5/thumbnails/73.jpg)
Output
Output back to browsermy $output = $session->output;
Print some content$output->print($content);
Don’t process macros as printing:$output->print($content,1);
Set the output handle$output->setHandle($someFileHandle);