i
-
Upload
ricardo-signes -
Category
Technology
-
view
1.461 -
download
1
description
Transcript of i
![Page 1: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/1.jpg)
the 2009 PEP talk!!!
![Page 2: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/2.jpg)
...I work there!
![Page 3: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/3.jpg)
YAPC::NA 2006
![Page 4: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/4.jpg)
PEP: Thoughts from PoboxYAPC::NA 2006
![Page 5: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/5.jpg)
YAPC::NA 2007
![Page 6: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/6.jpg)
How I Learned To Stop Worrying and Love Email
YAPC::NA 2007
![Page 7: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/7.jpg)
YAPC::NA 2008
![Page 8: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/8.jpg)
EmailYAPC::NA 2008
hates the living!
![Page 9: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/9.jpg)
What’s the best way to deal with horrible code?
![Page 10: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/10.jpg)
Write more code!
...so I did! The last year has been really productive. Lots of obnoxious problems were sorted out. I’m really happy with what we got accomplished, and so finally I can with a straight face...
![Page 11: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/11.jpg)
rjbs<3
emailthe 2009 PEP talk!!!
![Page 12: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/12.jpg)
sending email
![Page 13: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/13.jpg)
MIME::LiteMail::Send
Mail::SenderMail::Sendmail
so, here are some of the libraries for sending mail. these all let you specify subject, to/from, and content -- so you can’t actually make an email just hwo you want and pass it in. worthless for any real use
![Page 14: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/14.jpg)
Mail::Mailer
this lets you send mail through pluggable backends, and you provide the mail message. not bad, but not great; it has this weird API where it isa IO::Handle and you print to it like a filehandle to send your message. subclassing is a pain because it’s a blessed globref
![Page 15: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/15.jpg)
Email::Send
Email::Send simplifies by expecting a string, being a hashref, and being in theory easier to extend (by using Module::Pluggable)unfortunately, this pluggability (and some other oddities) ends up making extending things harder and can cause it to silently lose mail. for real.
![Page 16: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/16.jpg)
this is probably about about as good as a number of them.
![Page 17: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/17.jpg)
system(“sendmail @opts < $tempfile”) && die sprintf “sendmail died: %s”, errstr($?);
this is probably about about as good as a number of them.
![Page 18: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/18.jpg)
Mail::Transport
So, Mail::Transport isn’t bad. It’s part of the Mail-Box distro, which means it tends to get things right, but it also tends to be confusing and overwhelming for new users. If you’re already using it happily, that’s great! We weren’t, though, and so we wrote something new, built using just the ideas we liked from Email::Send, and
![Page 19: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/19.jpg)
![Page 20: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/20.jpg)
Email::Sender
![Page 21: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/21.jpg)
Email::Sender
![Page 22: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/22.jpg)
Email::Sender
Email-Sender uses Møøse
![Page 23: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/23.jpg)
Email::Sender
Email-Sender uses MøøseEmail::Sender is a role
![Page 24: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/24.jpg)
Email::Sender
Email-Sender uses MøøseEmail::Sender is a roleyou use Email::Sender::Simple
![Page 25: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/25.jpg)
Email::Sender::Simple
use Email::Sender::Simple qw(sendmail);
my $email = $customer->build_welcome_email;
sendmail($email);
Yup. That’s about it. That will try to send mail with either sendmail or SMTP, depending on what’s available. If it can’t send the message, it will throw.
![Page 26: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/26.jpg)
use Email::Sender::Simple qw(sendmail);
my $email = $customer->build_welcome_email;
sendmail( $email, { to => \@rcpts, from => $sender, });
Email::Sender::Simple
In other words, you can specify the envelope separately from the header. This is of *vital* importance to real email work. VERP, mailing lists, especially.
![Page 27: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/27.jpg)
Email::Sender::Simple
my $smtp = Email::Sender::Transport::SMTP->new({ host => ‘sasl.pobox.com’, port => 26,});
sendmail($email, { transport => $smtp });
If you don’t like the auto-detected transport, you can specify one. Transports are really easy to write, and a bunch already exist:
![Page 28: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/28.jpg)
Transports
SQLite is especially handy because you can dump all mail from a forking program into an easy-to-test database.
![Page 29: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/29.jpg)
TransportsSendmail
SQLite is especially handy because you can dump all mail from a forking program into an easy-to-test database.
![Page 30: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/30.jpg)
TransportsSendmail
SMTP
SQLite is especially handy because you can dump all mail from a forking program into an easy-to-test database.
![Page 31: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/31.jpg)
TransportsSendmail
SMTP
Persist. SMTP
SQLite is especially handy because you can dump all mail from a forking program into an easy-to-test database.
![Page 32: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/32.jpg)
TransportsSendmail
SMTP
Persist. SMTP
Maildir, Mbox
SQLite is especially handy because you can dump all mail from a forking program into an easy-to-test database.
![Page 33: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/33.jpg)
TransportsSendmail
SMTP
Persist. SMTP
Maildir, Mbox
DevNull
SQLite is especially handy because you can dump all mail from a forking program into an easy-to-test database.
![Page 34: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/34.jpg)
TransportsSendmail
SMTP
Persist. SMTP
Maildir, Mbox
DevNull
SQLite is especially handy because you can dump all mail from a forking program into an easy-to-test database.
![Page 35: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/35.jpg)
TransportsSendmail
SMTP
Persist. SMTP
Maildir, Mbox
DevNull
Test
SQLite is especially handy because you can dump all mail from a forking program into an easy-to-test database.
![Page 36: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/36.jpg)
TransportsSendmail
SMTP
Persist. SMTP
Maildir, Mbox
DevNull
Test
SQLite
SQLite is especially handy because you can dump all mail from a forking program into an easy-to-test database.
![Page 37: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/37.jpg)
Email::Sender::Simple
my $smtp = Email::Sender::Transport::SMTP->new({ host => ‘sasl.pobox.com’, port => 26,});
sendmail($email, { transport => $smtp });
so, you can do this, that’s fine, and you can use any of those cool transports when you call sendmail...but what about if you want to change the whole default?
![Page 38: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/38.jpg)
Email::Sender::Simple
walrus!rjbs:~$ EMAIL_SENDER_TRANSPORT=Maildir my-awesome-program --auden
now *every* call to Email::Sender::Simple->send will deliver to ./Maildir so you can see exactly what it would have sent
![Page 39: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/39.jpg)
Programmable Failure
so, for example, we have a system that distributes mail across a cluster of hosts with various mechanisms to cope with failure
Failable lets me test them by using a mailer that always works wrapped in predictable failure, easily
![Page 40: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/40.jpg)
Programmable Failure
::Failable transport
so, for example, we have a system that distributes mail across a cluster of hosts with various mechanisms to cope with failure
Failable lets me test them by using a mailer that always works wrapped in predictable failure, easily
![Page 41: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/41.jpg)
Programmable Failure
::Failable transportwrap any transport
so, for example, we have a system that distributes mail across a cluster of hosts with various mechanisms to cope with failure
Failable lets me test them by using a mailer that always works wrapped in predictable failure, easily
![Page 42: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/42.jpg)
Programmable Failure
::Failable transportwrap any transportmake it fail when you want
so, for example, we have a system that distributes mail across a cluster of hosts with various mechanisms to cope with failure
Failable lets me test them by using a mailer that always works wrapped in predictable failure, easily
![Page 43: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/43.jpg)
Other Random Senderisms
![Page 44: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/44.jpg)
Other Random Senderisms
structured failure
![Page 45: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/45.jpg)
Other Random Senderisms
structured failurepartial successes
![Page 46: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/46.jpg)
making email messages
![Page 47: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/47.jpg)
Email::Simple
![Page 48: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/48.jpg)
Email::MIME
![Page 49: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/49.jpg)
these are pretty low level
![Page 50: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/50.jpg)
you probably want to send only a few messages
(but with differences)
![Page 51: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/51.jpg)
MIME Crap to Deal With
![Page 52: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/52.jpg)
MIME Crap to Deal With
header encoding
![Page 53: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/53.jpg)
MIME Crap to Deal With
header encodingcontent encoding
![Page 54: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/54.jpg)
MIME Crap to Deal With
header encodingcontent encodingbuilding html & plain parts
![Page 55: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/55.jpg)
MIME Crap to Deal With
header encodingcontent encodingbuilding html & plain partsattaching files
![Page 56: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/56.jpg)
Other Crap to Deal With
![Page 57: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/57.jpg)
Other Crap to Deal With
templated documents
![Page 58: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/58.jpg)
Other Crap to Deal With
templated documentsvalidate parameters
![Page 59: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/59.jpg)
Other Crap to Deal With
templated documentsvalidate parametersreusable hunks of content
![Page 60: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/60.jpg)
![Page 61: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/61.jpg)
hate!
![Page 62: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/62.jpg)
Existing Solutions
![Page 63: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/63.jpg)
Existing Solutionsnone?
![Page 64: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/64.jpg)
Existing Solutionsnone?horrible hacks
![Page 65: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/65.jpg)
Existing Solutionsnone?horrible hacks
make a template in TT
![Page 66: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/66.jpg)
Existing Solutionsnone?horrible hacks
make a template in TTrender to html
![Page 67: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/67.jpg)
Existing Solutionsnone?horrible hacks
make a template in TTrender to htmlhtml-to-text
![Page 68: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/68.jpg)
Existing Solutionsnone?horrible hacks
make a template in TTrender to htmlhtml-to-texthope you guess right at headers
![Page 69: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/69.jpg)
![Page 70: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/70.jpg)
Email::MIME::Kit
![Page 71: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/71.jpg)
Email::MIME::Kit
![Page 72: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/72.jpg)
Email::MIME::Kit
a bunch of files
![Page 73: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/73.jpg)
Email::MIME::Kit
a bunch of fileswith instructions on how to assemble them
![Page 74: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/74.jpg)
Email::MIME::Kit
a bunch of fileswith instructions on how to assemble themand some other data
![Page 75: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/75.jpg)
Kit Manifest{ "renderer" : "TT", "header" : [ { "Subject": "Hello [% user.name %]" }, { "From": "Test Sender <[email protected]>" }, { "To": "[% user.email %]" } ], "alternatives": [ { "type": "text/plain", "path": "body.txt" }, { "type": "text/html", "path": "body.html" } ], "attachments": [ { "path": "demands.rtf" } ]}
![Page 76: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/76.jpg)
Assembling the Kit
my $kit = Email::MIME::Kit->new({ source => ‘msg.mkit’ });
my $email = $kit->assemble({ user => $user_object });
sendmail($email);
![Page 77: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/77.jpg)
Dear ,
Thank you for being a customer since .
Your account has been due to . Please contact before at or we will be forcedto your lovely wife Tracy’s head.
Cheers,Anonymous
Ugh. Our $user_object was undef. Now we get crap that looks like mail but stinks and makes us look like idiots.
We can plug in a validator pretty easily, though...
![Page 78: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/78.jpg)
Kit Manifest{ "renderer" : "TT", “validator”: “Rx”, "header" : [ { "Subject": "Hello [% user.name %]" }, { "From": "Test Sender <[email protected]>" }, { "To": "[% user.email %]" } ], "alternatives": [ { "type": "text/plain", "path": "body.txt" }, { "type": "text/html", "path": "body.html" } ], "attachments": [ { "path": "demands.rtf" } ]}
![Page 79: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/79.jpg)
rx.json
{ “type”: “//rec”, “required”: { “user”: { “type”: “/perl/obj”, “isa” : “User::Account” } }}
![Page 80: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/80.jpg)
Assembling the Kit
my $kit = Email::MIME::Kit->new({ source => ‘msg.mkit’ });
my $email = $kit->assemble({ user => undef });
undefined value tag: [ “/err/nil” ], data path: [ “user” ], schema path: [ “user” ]at slide 42, line 3
![Page 81: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/81.jpg)
Annoying Crap: Dealt With
![Page 82: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/82.jpg)
Annoying Crap: Dealt With
if user.name is Ævar...
![Page 83: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/83.jpg)
Annoying Crap: Dealt With
if user.name is Ævar...if attachments are binary...
![Page 84: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/84.jpg)
Annoying Crap: Dealt With
if user.name is Ævar...if attachments are binary...text-only (singlepart) mail...
![Page 85: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/85.jpg)
Annoying Crap: Dealt With
if user.name is Ævar...if attachments are binary...text-only (singlepart) mail...HTML with images as attachments...
![Page 86: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/86.jpg)
...so what’s still annoying?
![Page 87: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/87.jpg)
Some Kits...
so, you love mkits and you’re writing them all the time... now you start having this problem...
![Page 88: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/88.jpg)
Some Kits..../body.html./body.txt./logo.jpg./background.jpg./manifest.json
so, you love mkits and you’re writing them all the time... now you start having this problem...
![Page 89: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/89.jpg)
Some Kits..../body.html./body.txt./logo.jpg./background.jpg./manifest.json
./body.html
./body.txt
./logo.jpg
./background.jpg
./manifest.json
so, you love mkits and you’re writing them all the time... now you start having this problem...
![Page 90: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/90.jpg)
Some Kits..../body.html./body.txt./logo.jpg./background.jpg./manifest.json
./body.html
./body.txt
./logo.jpg
./background.jpg
./manifest.json
./body.html
./body.txt
./logo.jpg
./background.jpg
./manifest.json
so, you love mkits and you’re writing them all the time... now you start having this problem...
![Page 91: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/91.jpg)
Some Kits..../body.html./body.txt./logo.jpg./background.jpg./manifest.json
./body.html
./body.txt
./logo.jpg
./background.jpg
./manifest.json
./body.html
./body.txt
./logo.jpg
./background.jpg
./manifest.json
./body.html
./body.txt
./logo.jpg
./background.jpg
./manifest.json
so, you love mkits and you’re writing them all the time... now you start having this problem...
![Page 92: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/92.jpg)
Some Kits..../body.html./body.txt./logo.jpg./background.jpg./manifest.json
./body.html
./body.txt
./logo.jpg
./background.jpg
./manifest.json
./body.html
./body.txt
./logo.jpg
./background.jpg
./manifest.json
./body.html
./body.txt
./logo.jpg
./background.jpg
./manifest.json
those files are identical everywhere. blaugh! duplication baaaaaaaaaad
![Page 93: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/93.jpg)
The Kit Reader
![Page 94: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/94.jpg)
The Kit Reader
EMKit gets at its contents with the kit reader
![Page 95: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/95.jpg)
The Kit Reader
EMKit gets at its contents with the kit readernormally, just looks for files in the kit directory
![Page 96: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/96.jpg)
SWAK!
/fs (can be chrooted)/dist/kit (default, too)
...and more...
![Page 97: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/97.jpg)
SWAK!
you can write your own kit reader
/fs (can be chrooted)/dist/kit (default, too)
...and more...
![Page 98: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/98.jpg)
SWAK!
you can write your own kit readerSWAK: Path::Resolver
/fs (can be chrooted)/dist/kit (default, too)
...and more...
![Page 99: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/99.jpg)
SWAK!
you can write your own kit readerSWAK: Path::Resolver
/kit/body.html
/fs (can be chrooted)/dist/kit (default, too)
...and more...
![Page 100: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/100.jpg)
SWAK!
you can write your own kit readerSWAK: Path::Resolver
/kit/body.htmlbody.html
/fs (can be chrooted)/dist/kit (default, too)
...and more...
![Page 101: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/101.jpg)
SWAK!
you can write your own kit readerSWAK: Path::Resolver
/kit/body.htmlbody.html/fs/usr/share/app/body.html
/fs (can be chrooted)/dist/kit (default, too)
...and more...
![Page 102: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/102.jpg)
SWAK in Use
./body.html
./body.txt
./manifest.json
./body.html
./body.txt
./manifest.json
./body.html
./body.txt
./manifest.json
So, we can take those common files and put them in our dist’s shared resources, and reference them with the “/dist/” prefix, which finds stuff in share-dirs.
So, awesome! What’s still annoying?
![Page 103: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/103.jpg)
SWAK in Use
./body.html
./body.txt
./manifest.json
./body.html
./body.txt
./manifest.json
./body.html
./body.txt
./manifest.json
/dist/YourApp/logo.jpg/dist/YourApp/background.jpg
So, we can take those common files and put them in our dist’s shared resources, and reference them with the “/dist/” prefix, which finds stuff in share-dirs.
So, awesome! What’s still annoying?
![Page 104: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/104.jpg)
SWAK in Use
./body.html
./body.txt
./manifest.json
./body.html
./body.txt
./manifest.json
./body.html
./body.txt
./manifest.json
/dist/YourApp/logo.jpg/dist/YourApp/background.jpg
almost certainly, the html and text parts are (a) really close to each other within one kit (b) contain really different parts between kits (c) contain common boilerplate between kits
![Page 105: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/105.jpg)
EMK::Assembler::Markdown
./body.mkdn
./manifest.json
./body.mkdn
./manifest.json
./body.mkdn
./manifest.json
/dist/YourApp/logo.jpg/dist/YourApp/background.jpg
So, let’s fix that, too. We replace the text and html parts with a single Markdown document. We’ll use the Markdown itself for the plaintext part and we’ll turn it into HTML to use in the HTML part.
Of course, this still needs work. We want wrapper stuff and copyright and so on in both parts.
![Page 106: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/106.jpg)
./body.mkdn
./manifest.json
./body.mkdn
./manifest.json
./body.mkdn
./manifest.json
/dist/YourApp/logo.jpg/dist/YourApp/background.jpg/dist/YourApp/wrapper.html/dist/YourApp/wrapper.text
EMK::Assembler::Markdown
![Page 107: i](https://reader031.fdocuments.us/reader031/viewer/2022013100/54bb83f84a79598e0b8b45f6/html5/thumbnails/107.jpg)
Thank you!