<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: PraxTube</title>
    <description>The latest articles on DEV Community by PraxTube (@praxtube).</description>
    <link>https://dev.to/praxtube</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1128211%2Fd22fcaeb-f7af-43f3-be92-59831ef6b379.png</url>
      <title>DEV Community: PraxTube</title>
      <link>https://dev.to/praxtube</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/praxtube"/>
    <language>en</language>
    <item>
      <title>Fetching Bitcoin Mempool Data from the Terminal</title>
      <dc:creator>PraxTube</dc:creator>
      <pubDate>Fri, 08 Sep 2023 08:57:13 +0000</pubDate>
      <link>https://dev.to/praxtube/fetching-mempool-data-from-the-terminal-mln</link>
      <guid>https://dev.to/praxtube/fetching-mempool-data-from-the-terminal-mln</guid>
      <description>&lt;p&gt;For those of us who are doing most of their work in the terminal it can be very annoying to switch to a web browser for small tasks. For instance looking something up like the current Block height in the Bitcoin network or the current network fees. Granted, most people probably don't mind, but I do! So I wrote a little CLI to fetch some data from mempool.space and display the info in the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;╭─────806_715──────╮  ╭─────806_714──────╮  ╭─────806_713──────╮  ╭─────806_712──────╮
│   ≈ 19 sat/vB    │  │   ≈ 17 sat/vB    │  │   ≈ 19 sat/vB    │  │   ≈ 26 sat/vB    │
│ 16 - 1508 sat/vB │  │ 16 - 302 sat/vB  │  │ 17 - 302 sat/vB  │  │ 19 - 1213 sat/vB │
│                  │  │                  │  │                  │  │                  │
│     2.00 MB      │  │     1.74 MB      │  │     1.49 MB      │  │     1.61 MB      │
│    3,663 txs     │  │    2,790 txs     │  │    2,589 txs     │  │    3,516 txs     │
│      F2Pool      │  │   Foundry USA    │  │     AntPool      │  │      ViaBTC      │
│                  │  │                  │  │                  │  │                  │
│  20 minutes ago  │  │  30 minutes ago  │  │  39 minutes ago  │  │  54 minutes ago  │
╰──────────────────╯  ╰──────────────────╯  ╰──────────────────╯  ╰──────────────────╯
╭─────806_711──────╮  ╭─────806_710──────╮  ╭─────806_709──────╮  ╭─────806_708──────╮
│   ≈ 15 sat/vB    │  │   ≈ 16 sat/vB    │  │   ≈ 21 sat/vB    │  │   ≈ 18 sat/vB    │
│ 15 - 256 sat/vB  │  │ 15 - 317 sat/vB  │  │ 18 - 697 sat/vB  │  │ 16 - 302 sat/vB  │
│                  │  │                  │  │                  │  │                  │
│     1.86 MB      │  │     1.79 MB      │  │     1.66 MB      │  │     1.52 MB      │
│    4,706 txs     │  │    3,267 txs     │  │    3,141 txs     │  │    2,278 txs     │
│    MARA Pool     │  │     AntPool      │  │      F2Pool      │  │      ViaBTC      │
│                  │  │                  │  │                  │  │                  │
│   1 hours ago    │  │   1 hours ago    │  │   1 hours ago    │  │   2 hours ago    │
╰──────────────────╯  ╰──────────────────╯  ╰──────────────────╯  ╰──────────────────╯

╭───────Halving in: 7 months, 84%────────╮  ╭────Difficulty Adj. in: 11 days, 16%────╮
│█████████████████████████████████       │  │██████                                  │
╰────────────────────────────────────────╯  ╰────────────────────────────────────────╯
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output is pretty self-explanatory and is kept as similar to the mempool.space layout as possible. However it is static data, meaning we only get the receive data once. If you are looking for a live data feed (like it is on the mempool.space website) then check out &lt;a href="https://github.com/mempool/mempool-cli"&gt;mempool-cli&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In order to be able to get the same output as shown above, you can install &lt;a href="https://github.com/PraxTube/mrtui"&gt;Mr. TUI (Mempool Rust Terminal UI)&lt;/a&gt; by simply running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cargo install mrtui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then whenever you want to output the current blockchain data you can run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mrtui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it! Now you can get simple information from the bitcoin network through the terminal.&lt;/p&gt;

</description>
      <category>bitcoin</category>
      <category>rust</category>
      <category>terminal</category>
      <category>ui</category>
    </item>
    <item>
      <title>Creating Terminal UI in Rust</title>
      <dc:creator>PraxTube</dc:creator>
      <pubDate>Fri, 28 Jul 2023 08:55:51 +0000</pubDate>
      <link>https://dev.to/praxtube/creating-great-terminal-ui-in-rust-8d3</link>
      <guid>https://dev.to/praxtube/creating-great-terminal-ui-in-rust-8d3</guid>
      <description>&lt;p&gt;Creating CLI tools with good looking UI can be a tricky undertaking. This is especially true for big projects, where you can quickly run into the issue of having to handle many different edge cases. Rust is a great language to create CLI tools in, given that it's both safe and performant and simply a joy to write code in.&lt;/p&gt;

&lt;p&gt;One popular crate for creating TUI is the &lt;a href="https://github.com/ratatui-org/ratatui" rel="noopener noreferrer"&gt;&lt;code&gt;ratatui&lt;/code&gt;&lt;/a&gt; crate.&lt;br&gt;
It's quite powerful and you can basically create any TUI you would want to. However I found that there is a lack of articles for newcomers to get a foot in the door.&lt;br&gt;
So that's why I am writing this article!&lt;/p&gt;

&lt;p&gt;In the following sections I will walk you through some of the main features to know about the &lt;code&gt;ratatui&lt;/code&gt; crate.&lt;br&gt;
Note that I won't be using any explicit examples, instead I will try my best to explain what kind of architecture you could create. I advice you to take a look at the &lt;a href="https://github.com/ratatui-org/ratatui/tree/main/examples" rel="noopener noreferrer"&gt;ratatui examples&lt;/a&gt; which are very useful to tip your toes into the world of TUI. With that out of the way, let's take a look at the core of &lt;code&gt;ratatui&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The Main Loop
&lt;/h2&gt;

&lt;p&gt;Every TUI system has three important features:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

- struct App
- fn run_app&amp;lt;B: Backend&amp;gt;(terminal: &amp;amp;mut Terminal&amp;lt;B&amp;gt;, mut app: App) -&amp;gt; io::Result&amp;lt;()&amp;gt;
- fn ui&amp;lt;B: Backend&amp;gt;(f: &amp;amp;mut Frame&amp;lt;B&amp;gt;, app: &amp;amp;App)


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;App&lt;/code&gt; contains all the relevant information about our current app. We use it to store data between frame updates. The &lt;code&gt;run_app&lt;/code&gt; contains the main loop which we use to update our terminal. It handles user input and calling the UI update through the &lt;code&gt;ui&lt;/code&gt; function. The &lt;code&gt;ui&lt;/code&gt; handles everything related to drawing our UI on our terminal. Of course the names can be arbitrary, but this is what all examples in the &lt;code&gt;ratatui&lt;/code&gt; crate use and there is no good reason to not use them here as well.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to draw UI
&lt;/h2&gt;

&lt;p&gt;As stated above, we draw our UI in the &lt;code&gt;ui&lt;/code&gt; function.&lt;br&gt;
To draw UI components we must define a &lt;a href="https://docs.rs/ratatui/latest/ratatui/widgets/index.html" rel="noopener noreferrer"&gt;widget&lt;/a&gt;,&lt;br&gt;
For instance to define a simple block we can write&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;upper_block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.borders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Borders&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NONE&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"My Title"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;lower_block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.borders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Borders&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ALL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Second Title"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;This defines &lt;em&gt;what&lt;/em&gt; we render. Now we also need to define &lt;em&gt;where&lt;/em&gt; to render it. We do that by creating a &lt;a href="https://docs.rs/ratatui/latest/ratatui/layout/struct.Rect.html" rel="noopener noreferrer"&gt;Rect&lt;/a&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.direction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Vertical&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.constraints&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nn"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nn"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
    &lt;span class="nf"&gt;.split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;In this case &lt;code&gt;chunks&lt;/code&gt; is of type &lt;code&gt;Rc&amp;lt;[Rect]&amp;gt;&lt;/code&gt; with a length of 2. The &lt;code&gt;f&lt;/code&gt; we use here is the &lt;code&gt;f&lt;/code&gt; we pass into the function as a parameter. We tell the code to use the whole terminal screen and split it into two sections along the vertical axis. We get one area which is 3 lines in height and another that will take up the remaining space available. Because we didn't specify anything for the horizontal axis yet it will take up the entire length of the terminal screen (because &lt;code&gt;f.size()&lt;/code&gt; is the entire length). To now finally render this, we call&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.render_widget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;upper_block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.render_widget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lower_block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;which renders as&lt;/p&gt;

&lt;p&gt;
    &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldxzp0k15b6ktt5tc3xs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fldxzp0k15b6ktt5tc3xs.png" alt="First Example"&gt;&lt;/a&gt;
    &lt;br&gt;
    Basic UI components in a simple arrangement.
    &lt;a href="https://github.com/PraxTube/blog/blob/master/ratatui-intro/src/example_1.rs" rel="noopener noreferrer"&gt;source&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;It's helpful to really think about these two fields as the &lt;em&gt;what&lt;/em&gt; and the &lt;em&gt;where&lt;/em&gt; in terms of our UI component. Note that they are independent of each other, you can render any kind of &lt;code&gt;widget&lt;/code&gt; with any kind of &lt;code&gt;area&lt;/code&gt;. Let's take a deeper look at how you can fine-tune these.&lt;/p&gt;

&lt;h3&gt;
  
  
  Widgets (The What)
&lt;/h3&gt;

&lt;p&gt;There are quite a lot of built in widgets like the &lt;code&gt;List, Table, Chart, Gauge&lt;/code&gt; just to name of few. You can pretty much create anything you would need in a UI with the built-ins, so if you ever find yourself thinking that you must create your own widget really take a step back and consider what you need. In order to understand the widgets deeper you can take a look at the previously mentioned &lt;a href="https://github.com/fdehau/tui-rs/tree/master/examples" rel="noopener noreferrer"&gt;examples in the tui repository&lt;/a&gt;. This should cover pretty much most use cases you would encounter in the early to mid stages of a project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Area (The Where)
&lt;/h3&gt;

&lt;p&gt;There are multiples  way you could define areas,&lt;br&gt;
but the most common one is to split the main frame into the desired areas. You do this by setting the &lt;code&gt;direction&lt;/code&gt;, which states along which axis to create the chunks, and the &lt;code&gt;constraints&lt;/code&gt;, which lets you define how many chunks to create and in what ratio to create them. Lets consider the following&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.direction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Horizontal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.constraints&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nn"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Percentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nn"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Percentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;70&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
    &lt;span class="nf"&gt;.split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Here we create two areas with the left one taking up 30% of the area &lt;code&gt;size&lt;/code&gt; and the right one 70%. The Orientation is horizontal (left to right). In order to further cut these we could write&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sub_chunks_left&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.direction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Vertical&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.constraints&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nn"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Percentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nn"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Percentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
    &lt;span class="nf"&gt;.split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;sub_chunks_right&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.direction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Vertical&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.constraints&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nn"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Percentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nn"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Percentage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
    &lt;span class="nf"&gt;.split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;this will give us&lt;/p&gt;

&lt;p&gt;
    &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnun9qy25t7dmtkjpk04x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnun9qy25t7dmtkjpk04x.png" alt="Second Example"&gt;&lt;/a&gt;
    &lt;br&gt;
    4 blocks rendered to different areas on the screen.
    &lt;a href="https://github.com/PraxTube/blog/blob/master/ratatui-intro/src/example_2.rs" rel="noopener noreferrer"&gt;source&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Which would create 4 areas in total. This alone is already enough to create most UI arrangements, however there are two more things you should be aware of: Margins and Constraints&lt;/p&gt;

&lt;p&gt;It can be useful to set Margins for certain areas, for example when you have one widget inside another one, e.g. when you want to have text surrounded by a block.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.size&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.title&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Border"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="nf"&gt;.borders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Borders&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;ALL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.render_widget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Layout&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="nf"&gt;.direction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Direction&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Vertical&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.margin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.constraints&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nn"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nn"&gt;Constraint&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
    &lt;span class="nf"&gt;.split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;size&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="n"&gt;message_top&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Paragraph&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hello World&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Some text&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s"&gt;Even more text"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nf"&gt;.block&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Block&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;default&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="nf"&gt;.borders&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nn"&gt;Borders&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;NONE&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="nf"&gt;.render_widget&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message_top&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;chunks&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;which will result in&lt;/p&gt;

&lt;p&gt;
    &lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycktqoqnhu5slnz2tcgy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fycktqoqnhu5slnz2tcgy.png" alt="Third Example"&gt;&lt;/a&gt;
    &lt;br&gt;
    Block with text inside using margin.
    &lt;a href="https://github.com/PraxTube/blog/blob/master/ratatui-intro/src/example_3.rs" rel="noopener noreferrer"&gt;source&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Here &lt;code&gt;block&lt;/code&gt; is a simple border and the two text components will be inside of this border. Also take note of the &lt;code&gt;Constraint&lt;/code&gt; here. We already saw a few different ones like &lt;code&gt;Percentage, Min, Length&lt;/code&gt;. The &lt;code&gt;Constraint&lt;/code&gt; is really powerful, as it allows you to create pretty much any Ratios you would need. This is also why creating the areas relative to the terminal size is the recommended way. It's pretty easy and most flexible, the size of the user's terminal is of no concern to you the developer.&lt;/p&gt;

&lt;p&gt;Okay so now that we have seen how we can&lt;br&gt;
define our &lt;em&gt;what&lt;/em&gt; and &lt;em&gt;where&lt;/em&gt;, it's time to look at how to store our data using the &lt;code&gt;App&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to store Data
&lt;/h2&gt;

&lt;p&gt;Managing information in programming is generally a tricky part. This is no exception. The easiest way for us to store information throughout frame updates is to do so directly in the &lt;code&gt;App&lt;/code&gt;. This however quickly becomes unfeasible as we need to store more and more data. One possible way to solve this is to store &lt;code&gt;struct&lt;/code&gt;s in the &lt;code&gt;App&lt;/code&gt;, which then store the data relevant to them. So for instance&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="k"&gt;struct&lt;/span&gt; &lt;span class="n"&gt;App&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;confirmation_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;confirmation&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;text_prompt_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;text_prompt&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;song_data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nn"&gt;song&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This might seem a little overkill for very small&lt;br&gt;
projects, but I assure that you will quickly need&lt;br&gt;
to split up the logic as your projects grows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Managing multiple Controllers
&lt;/h2&gt;

&lt;p&gt;You will eventually want to have multiple controllers for different UI states. For instance you might have a UI component that asks the user for a string input and another one that is a simple confirmation pop up. You can't have the same controller for both of these, instead you have two separate ones, and you call whichever is currently in use. Here we could write&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="k"&gt;pub&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Controller&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;FuzzyFinder&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Confirmation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;and then we check which controller to call with&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight rust"&gt;&lt;code&gt;

&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="n"&gt;run_app&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Backend&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;terminal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;Terminal&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;tick_rate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;io&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;Result&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;last_tick&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nn"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;loop&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;terminal&lt;/span&gt;&lt;span class="nf"&gt;.draw&lt;/span&gt;&lt;span class="p"&gt;(|&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="nf"&gt;ui&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;match&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="py"&gt;.controller&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nn"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Main&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;main_controller&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tick_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;last_tick&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nn"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;FuzzyFinder&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;fuzzy_finder&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tick_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;last_tick&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nn"&gt;Controller&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="n"&gt;Confirmation&lt;/span&gt; &lt;span class="k"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;confirmation&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="nn"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;::&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;B&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tick_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="k"&gt;mut&lt;/span&gt; &lt;span class="n"&gt;last_tick&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;?&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In each controller we can now define custom key bindings and have completely separate logic in them. Of course this is only a suggestion, there are absolutely other ways to structure your code. This is simply the way I have been writing it in my project and I wanted to give you a point to start. This goes for everything I have been showing you here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article I went over the bigger picture of how to&lt;br&gt;
structure a TUI rust project using the &lt;code&gt;ratatui&lt;/code&gt; crate. We saw how to create &lt;code&gt;widgets&lt;/code&gt; and &lt;code&gt;areas&lt;/code&gt; and how to store data throughout frame updates in an &lt;code&gt;App&lt;/code&gt;. I also showed you how to create multiple controllers to handle different logic for your UI components. All in all this was merely an overview of what you can do and how you might want to structure your project. It's still highly advisable to look through the &lt;a href="https://github.com/ratatui-org/ratatui/tree/main/examples" rel="noopener noreferrer"&gt;ratatui examples&lt;/a&gt; to get a basic understanding of how to create UI components.&lt;br&gt;
Remember that nothing I displayed here is a must, you are free to structure your code in any way you want. It's simply a guideline which you can follow if you want to, in case you are unsure how to structure your TUI project.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>terminal</category>
      <category>ui</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
