Eclectic Media Git eclecticmedia.space / d137a4f
Final draft of rss-atom-feeds.md Ariana Giroux 19 days ago
1 changed file(s) with 31 addition(s) and 31 deletion(s). Raw diff Collapse all Expand all
00 ## Ensuring Less Notifications
11
22
3 Many sources have shown that [multitasking reduces our productivity](https://www.apa.org/research/action/multitask). As this [research from the APA](https://www.apa.org/research/action/multitask) shows, "*[...] multitasking may seem efficient on the surface but may actually take more time in the end and involve more error.*" In short, each time you check your phone you are polluting what cognitive processing you have.
4
5 It is no secret that notifications are the leading cause for pulling us away from our work. According to this [research](https://www.businessofapps.com/marketplace/push-notifications/research/push-notifications-s), "*the average user receives 46 app push notifications per day*", and "*40% of web push notification senders belong to either the e-commerce or media, publishing & blogging sectors.*" In a world where we are being pulled away from reality more and more by our phones, it is vitally important to me to not contribute to the growing amount of noise.
3 It is no secret that notifications are the leading cause for pulling us away from our work. According to [Business of Apps](https://www.businessofapps.com/marketplace/push-notifications/research/push-notifications-s), "*the average user receives 46 app push notifications per day*", and "*40% of web push notification senders belong to either the e-commerce or media, publishing and blogging sectors.*" In today’s world we are increasingly being pulled away from reality by our phones. The distractions caused by notifications lower our productivity, and as such I wish not to contribute to the growing amount of notification based distractions.
4
5 Many sources have shown that [multitasking reduces our productivity](https://www.apa.org/research/action/multitask). As this [research from the APA](https://www.apa.org/research/action/multitask) shows, "*[...] multitasking may seem efficient on the surface but may actually take more time in the end and involve more error.*" With our phones and computers becoming more and more prominent in our lives, the notifications they bring become more and more regular distractions from our work. In short, each time you check your phone you are polluting what cognitive processing you have.
66
77 ## Enter RSS/Atom
88
1212
1313 RSS allows low bandwidth update and content syndication in a method that allows a user to choose for themselves how those notifications are consumed. Many apps are available to collect RSS feeds and provide "push" notifications for your device. Due to the purely opt in design of the standard, it puts the power in the user's hands without forcing them to trade their time and concentration (*or their data privacy*).
1414
15 Using RSS/Atom instead of a more modern solution allows not only stability, but also user freedom. Due to the design of RSS/Atom, a user's device does not inherently need to maintain a regular or constant connection to the server, instead only fetching updates when the user decides. Take [CommaFeed](https://www.commafeed.com/#/welcome) (*an open source and self hosted feed reader app*) for example. CommaFeed can operate by only searching for new feed content on login, instead of continuously in the background. This can help prevent contribution to the aforementioned *46 notifications an hour* by allowing the user to dictate their own reading habits, instead of letting the site dictate the user's habits.
15 Using RSS/Atom instead of a more modern solution allows not only stability, but also user freedom. Due to the design of RSS/Atom, a user's device does not inherently need to maintain a regular or constant connection to the server, instead only fetching updates when the user decides. [CommaFeed](https://www.commafeed.com/#/welcome) (*an open source and self hosted feed reader app*) showcases the effectiveness of RSS/Atom very well. CommaFeed can operate by only searching for new feed content on login, instead of continuously in the background. This can help prevent contribution to the aforementioned *46 notifications an hour* by allowing the user to dictate their own reading habits, instead of letting the site dictate the user's habits.
1616
1717 ## The Implementation
1818
19 Implementing an RSS/Atom feed for the website is not a difficult process. As of now, the syndication needs for the blog/site are simple, "when an article is published, you should know about it". Due to the [blog article discovery module](https://git.eclecticmedia.space/public/eclecticmedia.space/blob/899e28c6a0efae47f85c4d04b297b8cadac25293/utilities/__init__.py) (*a simple file discovery and markdown rendering module*), patching in an RSS/Atom feed only requires some simple extension.
19 Implementing an RSS/Atom feed for the website is not a difficult process. Currently, the syndication needs for the blog/site are simple, "when an article is published, you should know about it". Due to the [blog article discovery module](https://git.eclecticmedia.space/public/eclecticmedia.space/blob/899e28c6a0efae47f85c4d04b297b8cadac25293/utilities/__init__.py) (*a simple file discovery and markdown rendering module*), patching in an RSS/Atom feed only requires some simple extension.
2020
2121 So here's our patch outline:
2222
3030
3131 ---
3232
33 Due to the standard's simplicity, setting up a basic template that can produce our entire feed should be a relatively easy process. We can obtain a full "[example](https://www.w3schools.com/xml/xml_rss.asp)" file, and apply some basic ``Jinja2 for loops``.
33 Due to the standard's simplicity, setting up a basic template that can produce the entire feed should be a relatively easy process. We can obtain a full "[example](https://www.w3schools.com/xml/xml_rss.asp)" file, and apply some basic ``Jinja2 for loops``.
3434
3535 First, the [sample file](https://www.w3schools.com/xml/xml_rss.asp) mentioned above:
3636
5858
5959 </rss>
6060
61 As is pointed out in my added comments in the above text, we can almost instantly reduce the amount of handwritten XML by adding a for loop to the `<item>` keys:
61 As is pointed out in my added comments in the above code, I can almost instantly reduce the amount of handwritten XML by adding a for loop to the `<item>` keys:
6262
6363 {% for item in items %} {# assuming items is a dict containing relavent data #}
6464 <item> <!--a single entry in the feed-->
6868 </item>
6969 {% endfor %}
7070
71 > For those not familiar with Jinja2, `{% for ... %}` simply tells our template to repeat the code within the beginning and end tag for each data point in a list.
71 > For those not familiar with Jinja2, `{% for ... %}` simply tells the template to repeat the code within the beginning and end tag for each data point in a list.
7272 > Furthermore, the `{{ item['key'] }}` is Python syntax for accessing dictionary data.
7373
74 We're now able to avoid any potential errors with hand crafting each item in the feed! The only thing thats left for our template is to add Jinja2 data where necessary:
74 We're now able to avoid any potential errors with hand crafting each item in the feed! The only thing thats left for the template is to add Jinja2 data where necessary:
7575
7676 <?xml version="1.0" encoding="UTF-8" ?>
7777 <rss version="2.0">
8585
8686 </rss>
8787
88 Put it all together and add a few extra pieces of meta data, and we end up with a fully serviceable (and extendible) RSS feed file
88 Put it all together and add a few extra pieces of meta data, and I end up with a fully serviceable (and extendible) RSS feed file
8989
9090 <?xml version="1.0" encoding="UTF-8" ?>
9191 <rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
111111
112112 ---
113113
114 Now that we have a template file set up we can use it to render the feed, perfectly up to date (to the moment the request for content is made) with the current state of the site. This allows us to provide a simple content upload mechanism (like the currently used *git* system), and keep the feed up to date without worrying about potentially blocking database queries. Each time an end-user RSS reader attempts to get the feed, we can populate the above template with details mostly already present in the discovery engine.
114 Now that I have a template file set up, I can use it to render the feed perfectly up to date (to the moment the request for content is made) with the current state of the site. This allows me to provide a simple content upload mechanism (like the currently used *git* system), and keep the feed up to date without worrying about potentially blocking database queries. Each time an end-user RSS reader attempts to get the feed, the site can populate the above template with details mostly already present in the discovery engine.
115115
116116 <h2 style="margin-top: 2rem;">Using the Discovery Module to obtain additional data for the RSS feed</h2>
117117
131131
132132 > <small>Follow <a href="https://git.eclecticmedia.space/public/eclecticmedia.space/blob/899e28c6a0efae47f85c4d04b297b8cadac25293/utilities/__init__.py">this link</a> to view the code in full.</small>
133133
134 ### Using the module to populate our feed
135
136 Because `sort_blog()` gives us all the data we need for our `RSS` template feed, all we need to do is collect its' data in a context variable and pass it on to the template. Jinja2 has an excellent method to interact with data in python `dictonaries`, so that will be our data object.
137
138 > Note: Jinja2 holds the *entire* context for its template within a dict, and we will be overriding it with ours. Therefore, we will end up with a `dictionary` that only contains a list of items.
134 ### Using the module to populate the feed
135
136 Because `sort_blog()` yields all the data the function needs for the `RSS` template feed, all I need to do is collect its' data in a context variable and pass it on to the template. Jinja2 has an excellent method to interact with data in python `dictonaries`, so that will be the data object.
137
138 > Note: Jinja2 holds the *entire* context for its template within a `dict`, and I will be overriding it with ours. Therefore, the function will end up with a `dictionary` that only contains a list of items.
139139
140140 First, lets collect that data:
141141
153153
154154 This is where I ran into my first problem however. The description text that is returned by `sort_blog()` (and therefore *`__get_blog_text()`*) is the HTML that has been rendered from the plain-text markdown. `HTML` and `XML` syntax are far too similar to have this be a safe option, and will often end up in syntax errors and the feed failing to render.
155155
156 Due to this, we need to write a new description parser for the rss feed. Because we need plain-text and our `markdown` files are human readable, we can simply grab the first body line from the file:
156 Due to this, I need to write a new description parser for the RSS feed. Because the function needs plain-text and the `markdown` files are human readable, I can simply grab the first body line from the file:
157157
158158
159159 def parse_description(path):
178178 )
179179 ...
180180
181 With all of this in place, we can use Jinja2 and our [blog discovery module](https://git.eclecticmedia.space/public/eclecticmedia.space/blob/899e28c6a0efae47f85c4d04b297b8cadac25293/utilities/__init__.py) to render a fully valid RSS feed file! Now let's patch it in to a new endpoint.
181 With all of this in place, I can use Jinja2 and my [blog discovery module](https://git.eclecticmedia.space/public/eclecticmedia.space/blob/899e28c6a0efae47f85c4d04b297b8cadac25293/utilities/__init__.py) to render a fully valid RSS feed file! Now let's patch it in to a new endpoint.
182182
183183 ## Setting up the RSS endpoint
184184
185 All that is left to do now is to add a new endpoint to the [flask](https://palletsprojects.com/p/flask/) app-file (*`./app.py`*). To do so, we'll first set up some scaffolding with flask:
186
187
188 @app.route('/rss/feed.xml', methods=['GET'])
189 def feed():
190 return 'our feed!'
191
192
193 Once we have this function added to our app-file, we can start plugging in the code from the previous step. First, the context setup:
185 All that is left to do now is to add a new endpoint to the [flask](https://palletsprojects.com/p/flask/) app-file (*`./app.py`*). To do so, I'll first set up some scaffolding with flask:
186
187
188 @app.route('/rss/feed.xml', methods=['GET'])
189 def feed():
190 return 'our feed!'
191
192
193 Once this function has been added to the app-file, I can start plugging in the code from the previous step. First, the context setup:
194194
195195 @app.route('/rss/feed.xml', methods=['GET'])
196196 def feed():
211211
212212 return 'our feed!'
213213
214 And now we can plug in that parsing function. Instead of adding it to the general namespace and scope of the app-file, it is probably more ideal to simply declare it in the endpoint function itself (*a lesser known feature of python*). This allows the code to stay leaner, and allows easier maintenence in the future.
214 Now I can plug in that parsing function. Instead of adding it to the general name space and scope of the app-file, it is probably more ideal to simply declare it in the endpoint function itself (*a lesser known feature of python*). This allows the code to stay leaner, and allows easier maintenance in the future.
215215
216216 @app.route('/rss/feed.xml', methods=['GET'])
217217 def feed():
227227 ...
228228 return render('feed.xml', context=context) # use our rendering function to return the feed file
229229
230 Experienced Flask developers may have already noticed my error. In the above snippet, I added a call to the [jinja renderer](https://git.eclecticmedia.space/public/eclecticmedia.space/blob/master/utilities/renderer.py#L-10) and thought it would work out in my favor. I should know by know that it's never as simple as just popping in the previous step with code. Turns out I needed to add a Flask class to set up the response as `XML` instead of `HTML` as flask is want to do.
230 Experienced Flask developers may have already noticed my error. In the above snippet, I added a call to the [Jinja2 renderer](https://git.eclecticmedia.space/public/eclecticmedia.space/blob/master/utilities/renderer.py#L-10) and thought it would work out in my favor. I should know by now that it's never as simple as just popping in the previous step with code. Turns out I needed to add a Flask class to set up the response as `XML` instead of `HTML` as flask is want to do.
231231
232232 @app.route('/rss/feed.xml', methods=['GET'])
233233 def feed():
236236 mimetype='text/xml')
237237
238238
239 Now that we've told Flask to return an XML file instead of an `HTML` response, my feed is set up and ready for syndication! Now, any time I update or publish an article, feed readers around the world can notify users of those changes according to their own rules.
239 Now that I've told Flask to return an XML file instead of an `HTML` response, my feed is set up and ready for syndication! Now, any time I update or publish an article, feed readers around the world can notify users of those changes according to their own rules.
240240
241241 ## Wrapping it all up
242242
243 In conclusion, it is in keeping with my goals for this site to offer lightweight, privacy respecting, and flexible systems and solutions to my readers and users. Rolling our own `RSS` feed has allowed me to not only take a step closer to achieving those goals, but also to forever extend the funcitonality of the webiste in a simple and efficient matter. With the feed in place, maintenence of the site has become easier without sacrificing the potential of returning visitors.
243 Through my work I have shown that it is in keeping with my goals for this site to offer lightweight, privacy respecting, and flexible systems and solutions to my readers and users. Rolling my own `RSS` feed has allowed me to not only take a step closer to achieving those goals, but also to forever extend the functionality of the website in a simple and efficient matter. With the feed in place, maintenance of the site has become easier without sacrificing the potential of returning visitors.
244244
245245 Make sure to subscribe to the feed at [https://eclecticmedia.space/rss/feed.xml](https://eclecticmedia.space/rss/feed.xml) to get any updates!