Line | acb84c08c1bbcc83036b9cad70f6a3c5d60865c4 | current |
1 | <!DOCTYPE html> | <!DOCTYPE html> |
2 | <html> | <html> |
3 | <head> | <head> |
⋮ | ⋮ | ⋮ |
42 | <link rel="alternate" type="application/rss+xml" title="tech.interfluidity.com updates" href="../../../../feed/index.rss"> | <link rel="alternate" type="application/rss+xml" title="tech.interfluidity.com updates" href="../../../../feed/index.rss"> |
43 | <link rel="alternate" type="application/rss+xml" title="interfluidity - all blogs" href="https://www.interfluidity.com/unify-rss/all-blogs.rss"> | <link rel="alternate" type="application/rss+xml" title="interfluidity - all blogs" href="https://www.interfluidity.com/unify-rss/all-blogs.rss"> |
44 | <link rel="alternate" type="application/rss+xml" title="interfluidity - all blogs and microblogs" href="https://www.interfluidity.com/unify-rss/all-blogs-and-microblogs.rss"> | <link rel="alternate" type="application/rss+xml" title="interfluidity - all blogs and microblogs" href="https://www.interfluidity.com/unify-rss/all-blogs-and-microblogs.rss"> |
45 | | <link rel="alternate" type="application/x-single-item-rss+xml" title="Feedletter tutorial" href="index.rss"> |
46 | <link rel="stylesheet" href="../../../../css/style.css"> | <link rel="stylesheet" href="../../../../css/style.css"> |
47 | <link rel="stylesheet" href="../../../../css/highlightjs/steve-night-owl.css"><!-- theme for highlight.js --> | <link rel="stylesheet" href="../../../../css/highlightjs/steve-night-owl.css"><!-- theme for highlight.js --> |
48 | <script src="../../../../js/highlight/highlight.min.js"></script> | <script src="../../../../js/highlight/highlight.min.js"></script> |
⋮ | ⋮ | ⋮ |
83 | <h1><a href="index.html">Feedletter tutorial</a></h1> | <h1><a href="index.html">Feedletter tutorial</a></h1> |
84 | <hr class="below-title"> | <hr class="below-title"> |
85 | </div> | </div> |
86 | | <div class="update-prepend rss-description-exclude"> |
87 | | <em> ➣ This post was meaningfully revised at 2024-06-20 @ 01:10 PM EDT. The previous revision is <a href="index-oldcommit-acb84c08c1bbcc83036b9cad70f6a3c5d60865c4.html">here</a>, diff <a href="index-diff-acb84c08c1bbcc83036b9cad70f6a3c5d60865c4-to-current.html">here</a>. (See <a href="index.html#update-history">update history</a>.) </em> |
88 | | <hr> |
89 | | </div> |
90 | <div class="entry-body"> | <div class="entry-body"> |
91 | <div class="flexmark markdown"> | <div class="flexmark markdown"> |
92 | <p>I've been working for some time on a service to turn RSS feeds into e-mail newsletters, which I've called <a href="https://github.com/swaldman/feedletter"><em>feedletter</em></a>.</p> | <p>I've been working for some time on a service to turn RSS feeds into e-mail newsletters, which I've called <a href="https://github.com/swaldman/feedletter"><em>feedletter</em></a>.</p> |
⋮ | ⋮ | ⋮ |
987 | </ul> | </ul> |
988 | <p>For each subscribable, you can define just one of each kind of customizer, but customers can perform any number of steps internally.</p> | <p>For each subscribable, you can define just one of each kind of customizer, but customers can perform any number of steps internally.</p> |
989 | <p>For an example, we'll build a content customizer. Both of our feeds frequently embed YouTube videos as <code>iframe</code> HTML elements in their blog posts. Unfortunately, mail clients generally do not render this form of embedded content, leaving awkward empty-spaces in and sometimes mangling the formatting of our newsletters.</p> | <p>For an example, we'll build a content customizer. Both of our feeds frequently embed YouTube videos as <code>iframe</code> HTML elements in their blog posts. Unfortunately, mail clients generally do not render this form of embedded content, leaving awkward empty-spaces in and sometimes mangling the formatting of our newsletters.</p> |
990 | | <div class="note"> |
991 | | <p>As of <code>feedletter-v0.0.13</code> (released June 19, 2024), the API has changed slightly from that documented in this tutorial.</p> |
992 | | <ol> |
993 | | <li> |
994 | | <p><code>Customizer</code> is no longer in the package <code>com.mchange.feedletter.style</code>, but in the base <code>com.mchange.feedletter</code> package. (This is because customizers now apply more broadly than styling nowtifications. They can be used, for example, to filter subscribables by author or category.)</p></li> |
995 | | <li> |
996 | | <p>Individual <code>Customizer</code> types — which are just functions — no longer include a <code>withinTypeId : String</code> argument. <code>withinTypeId</code> is how <code>feedletter</code> binds multiple items into a single notification (for example in a weekly digest feed). The several posts that will be notified share a <code>withinTypeId</code>. However, the nature and format of these IDs are really implementation details of <code>feedletter</code> and its <code>SubscriptionManager</code> classes, so we are not exposing them to customizers.</p></li> |
997 | | </ol> |
998 | | <p>Just use <code>com.mchange.feedletter.Customizer</code>, and</p> |
999 | | <pre><code class="language-scala">( subscribableName : SubscribableName, subscriptionManager : SubscriptionManager, feedUrl : FeedUrl, contents : Seq[ItemContent] ) => Seq[ItemContent] |
1000 | | </code></pre> |
1001 | | <p>under newer versions of <code>feedletter</code>.</p> |
1002 | | </div> |
1003 | <p>So let's build a content customizer that replaces these with well-behaved <code>div</code> elements containing links to the resources that would have been in the <code>iframe</code>. We'll include a <code>class="embedded"</code> attribute on the <code>div</code> elements, so that we will be able to style them however we want.</p> | <p>So let's build a content customizer that replaces these with well-behaved <code>div</code> elements containing links to the resources that would have been in the <code>iframe</code>. We'll include a <code>class="embedded"</code> attribute on the <code>div</code> elements, so that we will be able to style them however we want.</p> |
1004 | <p>Writing customizers in writing Scala code. We'll use the excellent <a href="https://jsoup.org/">jsoup</a> library to manipulate HTML. We'll give ourselves space to work by creating a <code>tutorial</code> package in our installation's <code>src</code> directory, and then exiting a file called <code>core.scala</code> inside that.</p> | <p>Writing customizers in writing Scala code. We'll use the excellent <a href="https://jsoup.org/">jsoup</a> library to manipulate HTML. We'll give ourselves space to work by creating a <code>tutorial</code> package in our installation's <code>src</code> directory, and then exiting a file called <code>core.scala</code> inside that.</p> |
1005 | <pre><code class="language-plaintext">$ mkdir src/tutorial | <pre><code class="language-plaintext">$ mkdir src/tutorial |
⋮ | ⋮ | ⋮ |
1095 | </div> | </div> |
1096 | <div class="entry-footer"> | <div class="entry-footer"> |
1097 | <div class="post-metainfo"> | <div class="post-metainfo"> |
1098 | <a href="index.html">10:30 AM EST</a> | <div class="updated-note"> |
1099 | | <a href="index.html#major-updates">Last major update at 2024-06-20 @ 01:10 PM EDT</a> |
1100 | | </div> |
1101 | | <div> |
1102 | | <a href="index.html" class="pubtime">10:30 AM EST</a> |
1103 | | </div> |
1104 | </div> | </div> |
1105 | </div> | </div> |
1106 | </article> | </article> |
⋮ | ⋮ | ⋮ |
1116 | <a href="../../../02/04/style-by-mail-in-feedletter/index.html">Style-by-mail in feedletter →</a> | <a href="../../../02/04/style-by-mail-in-feedletter/index.html">Style-by-mail in feedletter →</a> |
1117 | </div> | </div> |
1118 | </div> | </div> |
1119 | | <div id="update-history" class="update-history"> |
1120 | | <h3 class="update-history-title"><a id="major-updates" href=""></a>Major revisions:</h3> |
1121 | | <ul> |
1122 | | <li><span class="update-timestamp"><i>2024-06-20 @ 01:10 PM EDT</i></span> — Add note to Section 16, "Advanced: Customize the content" documenting <i>feedletter</i> API changes that slightly modify this section of the tutorial. (<a href="index-diff-acb84c08c1bbcc83036b9cad70f6a3c5d60865c4-to-current.html">diff</a>)</li> |
1123 | | <li><span class="update-timestamp"><i> <a href="index-oldcommit-acb84c08c1bbcc83036b9cad70f6a3c5d60865c4.html">2024-01-29 @ 10:30 AM EST</a></i></span> — Initial publication.</li> |
1124 | | </ul> |
1125 | | <div class="update-history-note"> |
1126 | | Timestamps represent "major", substantative revisions. There may have been subsequent typo fixes and language reworkings within a major revision, after the time displayed. For a more complete and fine-grained update history, you can view the <a href="https://github.com/swaldman/tech.interfluidity.com/commits/main/">git repository commit history</a>. The most recent minor modification of this entry occurred 2024-11-10 @ 08:30 PM EST. |
1127 | | </div> |
1128 | | </div> |
1129 | </div><!-- after-article --> | </div><!-- after-article --> |
1130 | </div> | </div> |
1131 | <div id="right-sidebar"> | <div id="right-sidebar"> |
1132 | </div> | </div> |
1133 | </div> | </div> |
1134 | </body> | </body> |
1135 | </html> | </html> |