| 1 | #? stdtmpl(subsChar = '$', metaChar = '#') |
| 2 | #proc renderMain*(v: View): string = |
| 3 | # result = "" |
| 4 | # let f = $v.filter |
| 5 | # if v.total > 0: |
| 6 | <section class="main"> |
| 7 | <input id="toggle-all" class="toggle-all" type="checkbox"${checkedIf(v.total == v.completed)}> |
| 8 | <label for="toggle-all">Mark all as complete</label> |
| 9 | <form class="inline" method="post" action="/todos/toggle-all"><input type="hidden" name="filter" value="$f"><button class="toggle-all-button" data-action="toggle-all">Mark all as complete</button></form> |
| 10 | <ul class="todo-list"> |
| 11 | # for t in v.todos: |
| 12 | # let editing = t.id == v.editing |
| 13 | # let title = h(t.title) |
| 14 | <li${classes(t.completed, editing)} data-id="${t.id}"> |
| 15 | <div class="view"> |
| 16 | <input class="toggle" type="checkbox"${checkedIf(t.completed)}> |
| 17 | <label>$title</label> |
| 18 | <form class="inline" method="post" action="/todos/${t.id}/toggle"><input type="hidden" name="filter" value="$f"><button class="toggle-button" data-action="toggle">${if t.completed: "Mark as active" else: "Mark as complete"}</button></form> |
| 19 | <a class="edit-link" data-action="edit" href="${filterPath(v.filter)}?edit=${t.id}">edit</a> |
| 20 | <form class="inline" method="post" action="/todos/${t.id}/destroy"><input type="hidden" name="filter" value="$f"><button class="destroy" aria-label="Delete"></button></form> |
| 21 | </div> |
| 22 | # if editing: |
| 23 | <form class="inline" method="post" action="/todos/${t.id}/edit"><input type="hidden" name="filter" value="$f"><input class="edit" name="title" value="$title" autofocus></form> |
| 24 | # else: |
| 25 | <input class="edit" value="$title"> |
| 26 | # end if |
| 27 | </li> |
| 28 | # end for |
| 29 | </ul> |
| 30 | </section> |
| 31 | <footer class="footer"> |
| 32 | <span class="todo-count"><strong>${v.total - v.completed}</strong> ${if v.total - v.completed == 1: "item" else: "items"} left</span> |
| 33 | <ul class="filters"> |
| 34 | # for (filter, name) in [(fAll, "All"), (fActive, "Active"), (fCompleted, "Completed")]: |
| 35 | <li> |
| 36 | <a${if filter == v.filter: " class=\"selected\"" else: ""} href="${filterPath(filter)}">$name</a> |
| 37 | </li> |
| 38 | # end for |
| 39 | </ul> |
| 40 | # if v.completed > 0: |
| 41 | <form class="inline" method="post" action="/todos/clear-completed"><input type="hidden" name="filter" value="$f"><button class="clear-completed">Clear completed</button></form> |
| 42 | # end if |
| 43 | </footer> |
| 44 | # end if |
| 45 | #end proc |
| 46 | # |
| 47 | #proc renderPage*(v: View): string = |
| 48 | # result = "" |
| 49 | <!doctype html> |
| 50 | <html lang="en"> |
| 51 | <head> |
| 52 | <meta charset="utf-8"> |
| 53 | <meta name="viewport" content="width=device-width, initial-scale=1"> |
| 54 | <title>TodoMVC</title> |
| 55 | <script>document.documentElement.classList.add("js")</script> |
| 56 | <link rel="stylesheet" href="/static/base.css"> |
| 57 | <link rel="stylesheet" href="/static/index.css"> |
| 58 | <link rel="stylesheet" href="/static/app.css?v=${h(v.version)}"> |
| 59 | <script type="module" src="/static/app.js?v=${h(v.version)}"></script> |
| 60 | </head> |
| 61 | <body> |
| 62 | <section class="todoapp" data-filter="${v.filter}"> |
| 63 | <header class="header"> |
| 64 | <h1>todos</h1> |
| 65 | <form class="inline" method="post" action="/todos"><input type="hidden" name="filter" value="${v.filter}"><input class="new-todo" name="title" placeholder="What needs to be done?" autocomplete="off"${if v.editing == 0: " autofocus" else: ""}></form> |
| 66 | </header> |
| 67 | ${renderMain(v)} </section> |
| 68 | <footer class="info"> |
| 69 | <p>Double-click to edit a todo</p> |
| 70 | <p>Created by <a href="https://bakeoff.bfj.oncarlos.com">the CARLOS bakeoff</a> · Nim</p> |
| 71 | <p>Part of <a href="http://todomvc.com">TodoMVC</a></p> |
| 72 | </footer> |
| 73 | </body> |
| 74 | </html> |
| 75 | #end proc |
| 76 | |