Skip to content

Template Examples

Overview

Practical examples of using Tera templates with RNode Server.

Basic Examples

Simple Welcome Page

html
<!-- templates/welcome.html -->
<!DOCTYPE html>
<html>
<head>
  <title>{{ title }}</title>
  <style>
    body { font-family: Arial, sans-serif; margin: 40px; }
    .welcome { text-align: center; }
    .user-info { background: #f5f5f5; padding: 20px; border-radius: 8px; }
  </style>
</head>
<body>
  <div class="welcome">
    <h1>{{ title }}</h1>
    <p>Welcome to our application!</p>
  </div>
  
  <div class="user-info">
    <h2>User Information</h2>
    <p><strong>Name:</strong> {{ user.name }}</p>
    <p><strong>Email:</strong> {{ user.email }}</p>
    <p><strong>Member since:</strong> {{ user.joinDate }}</p>
  </div>
  
  <div class="stats">
    <h2>Your Statistics</h2>
    <p>Total posts: {{ stats.postCount }}</p>
    <p>Total comments: {{ stats.commentCount }}</p>
    <p>Last activity: {{ stats.lastActivity }}</p>
  </div>
</body>
</html>

Server-side Rendering

javascript
app.get('/welcome', (req, res) => {
  const result = app.renderTemplate('welcome.html', {
    title: 'Welcome to RNode Server',
    user: {
      name: 'John Doe',
      email: 'john@example.com',
      joinDate: '2024-01-15'
    },
    stats: {
      postCount: 42,
      commentCount: 128,
      lastActivity: '2 hours ago'
    }
  });
  
  const parsed = JSON.parse(result);
  if (parsed.success) {
    res.html(parsed.content);
  } else {
    res.status(500).json({ error: parsed.error });
  }
});

Advanced Examples

Blog Post Template

html
<!-- templates/post.html -->
<!DOCTYPE html>
<html>
<head>
  <title>{{ post.title }} - {{ site.name }}</title>
  <meta name="description" content="{{ post.excerpt }}">
  <style>
    .post { max-width: 800px; margin: 0 auto; padding: 20px; }
    .post-header { border-bottom: 2px solid #eee; padding-bottom: 20px; }
    .post-meta { color: #666; font-size: 14px; }
    .post-content { line-height: 1.6; }
    .post-tags { margin-top: 30px; }
    .tag { background: #007bff; color: white; padding: 4px 8px; border-radius: 4px; margin-right: 8px; }
  </style>
</head>
<body>
  <div class="post">
    <header class="post-header">
      <h1>{{ post.title }}</h1>
      <div class="post-meta">
        <span>By {{ post.author.name }}</span>
        <span>•</span>
        <span>{{ post.publishDate | date(format="%B %d, %Y") }}</span>
        <span>•</span>
        <span>{{ post.readTime }} min read</span>
      </div>
    </header>
    
    <div class="post-content">
      {{ post.content | safe }}
    </div>
    
    {% if post.tags %}
    <div class="post-tags">
      <strong>Tags:</strong>
      {% for tag in post.tags %}
        <span class="tag">{{ tag }}</span>
      {% endfor %}
    </div>
    {% endif %}
    
    {% if post.comments %}
    <div class="comments">
      <h3>Comments ({{ post.comments | length }})</h3>
      {% for comment in post.comments %}
        <div class="comment">
          <strong>{{ comment.author }}</strong>
          <small>{{ comment.date | date(format="%Y-%m-%d %H:%M") }}</small>
          <p>{{ comment.content }}</p>
        </div>
      {% endfor %}
    </div>
    {% endif %}
  </div>
</body>
</html>

User Dashboard Template

html
<!-- templates/dashboard.html -->
<!DOCTYPE html>
<html>
<head>
  <title>Dashboard - {{ user.name }}</title>
  <style>
    .dashboard { display: grid; grid-template-columns: 250px 1fr; gap: 20px; }
    .sidebar { background: #f8f9fa; padding: 20px; }
    .main-content { padding: 20px; }
    .card { background: white; border: 1px solid #ddd; border-radius: 8px; padding: 20px; margin-bottom: 20px; }
    .stats-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 20px; }
    .stat-card { text-align: center; padding: 20px; background: #007bff; color: white; border-radius: 8px; }
    .stat-number { font-size: 2em; font-weight: bold; }
  </style>
</head>
<body>
  <div class="dashboard">
    <aside class="sidebar">
      <div class="user-profile">
        <h3>{{ user.name }}</h3>
        <p>{{ user.email }}</p>
        <p><strong>Role:</strong> {{ user.role | title }}</p>
        <p><strong>Member since:</strong> {{ user.joinDate | date(format="%B %Y") }}</p>
      </div>
      
      <nav class="sidebar-nav">
        <ul>
          <li><a href="/dashboard">Overview</a></li>
          <li><a href="/dashboard/posts">My Posts</a></li>
          <li><a href="/dashboard/comments">My Comments</a></li>
          <li><a href="/dashboard/settings">Settings</a></li>
        </ul>
      </nav>
    </aside>
    
    <main class="main-content">
      <h1>Welcome back, {{ user.name }}!</h1>
      
      <div class="stats-grid">
        <div class="stat-card">
          <div class="stat-number">{{ stats.totalPosts }}</div>
          <div class="stat-label">Total Posts</div>
        </div>
        <div class="stat-card">
          <div class="stat-number">{{ stats.totalComments }}</div>
          <div class="stat-label">Total Comments</div>
        </div>
        <div class="stat-card">
          <div class="stat-number">{{ stats.totalViews }}</div>
          <div class="stat-label">Total Views</div>
        </div>
        <div class="stat-card">
          <div class="stat-number">{{ stats.thisMonth }}</div>
          <div class="stat-label">This Month</div>
        </div>
      </div>
      
      {% if recentPosts %}
      <div class="card">
        <h3>Recent Posts</h3>
        <ul>
          {% for post in recentPosts %}
            <li>
              <a href="/post/{{ post.id }}">{{ post.title }}</a>
              <small>{{ post.publishDate | date(format="%Y-%m-%d") }}</small>
            </li>
          {% endfor %}
        </ul>
      </div>
      {% endif %}
      
      {% if recentActivity %}
      <div class="card">
        <h3>Recent Activity</h3>
        <ul>
          {% for activity in recentActivity %}
            <li>
              <span class="activity-type">{{ activity.type }}</span>
              <span class="activity-desc">{{ activity.description }}</span>
              <small>{{ activity.date | date(format="%H:%M") }}</small>
            </li>
          {% endfor %}
        </ul>
      </div>
      {% endif %}
    </main>
  </div>
</body>
</html>

Form Templates

Contact Form

html
<!-- templates/contact.html -->
<!DOCTYPE html>
<html>
<head>
  <title>Contact Us - {{ site.name }}</title>
  <style>
    .contact-form { max-width: 600px; margin: 0 auto; padding: 20px; }
    .form-group { margin-bottom: 20px; }
    label { display: block; margin-bottom: 5px; font-weight: bold; }
    input, textarea, select { width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 4px; }
    button { background: #007bff; color: white; padding: 12px 24px; border: none; border-radius: 4px; cursor: pointer; }
    .error { color: #dc3545; font-size: 14px; }
    .success { color: #28a745; font-size: 14px; }
  </style>
</head>
<body>
  <div class="contact-form">
    <h1>Contact Us</h1>
    
    {% if message %}
      <div class="{% if success %}success{% else %}error{% endif %}">
        {{ message }}
      </div>
    {% endif %}
    
    <form method="POST" action="/contact">
      <div class="form-group">
        <label for="name">Name *</label>
        <input type="text" id="name" name="name" value="{{ form.name | default(value='') }}" required>
        {% if errors.name %}
          <div class="error">{{ errors.name }}</div>
        {% endif %}
      </div>
      
      <div class="form-group">
        <label for="email">Email *</label>
        <input type="email" id="email" name="email" value="{{ form.email | default(value='') }}" required>
        {% if errors.email %}
          <div class="error">{{ errors.email }}</div>
        {% endif %}
      </div>
      
      <div class="form-group">
        <label for="subject">Subject</label>
        <select id="subject" name="subject">
          <option value="">Select a subject</option>
          <option value="general" {% if form.subject == "general" %}selected{% endif %}>General Inquiry</option>
          <option value="support" {% if form.subject == "support" %}selected{% endif %}>Technical Support</option>
          <option value="feedback" {% if form.subject == "feedback" %}selected{% endif %}>Feedback</option>
          <option value="other" {% if form.subject == "other" %}selected{% endif %}>Other</option>
        </select>
      </div>
      
      <div class="form-group">
        <label for="message">Message *</label>
        <textarea id="message" name="message" rows="6" required>{{ form.message | default(value='') }}</textarea>
        {% if errors.message %}
          <div class="error">{{ errors.message }}</div>
        {% endif %}
      </div>
      
      <button type="submit">Send Message</button>
    </form>
  </div>
</body>
</html>

E-commerce Templates

Product List

html
<!-- templates/products.html -->
<!DOCTYPE html>
<html>
<head>
  <title>{{ category.name }} - {{ site.name }}</title>
  <style>
    .products-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 20px; }
    .product-card { border: 1px solid #ddd; border-radius: 8px; padding: 15px; text-align: center; }
    .product-image { width: 100%; height: 200px; object-fit: cover; border-radius: 4px; }
    .product-price { font-size: 1.2em; font-weight: bold; color: #007bff; }
    .product-title { margin: 10px 0; }
    .filters { margin-bottom: 20px; padding: 20px; background: #f8f9fa; border-radius: 8px; }
  </style>
</head>
<body>
  <h1>{{ category.name }}</h1>
  
  <div class="filters">
    <form method="GET" action="/products/{{ category.slug }}">
      <label>Price Range:</label>
      <input type="number" name="min_price" value="{{ filters.minPrice | default(value='') }}" placeholder="Min">
      <input type="number" name="max_price" value="{{ filters.maxPrice | default(value='') }}" placeholder="Max">
      
      <label>Sort by:</label>
      <select name="sort">
        <option value="name" {% if filters.sort == "name" %}selected{% endif %}>Name</option>
        <option value="price_low" {% if filters.sort == "price_low" %}selected{% endif %}>Price: Low to High</option>
        <option value="price_high" {% if filters.sort == "price_high" %}selected{% endif %}>Price: High to Low</option>
        <option value="newest" {% if filters.sort == "newest" %}selected{% endif %}>Newest</option>
      </select>
      
      <button type="submit">Apply Filters</button>
    </form>
  </div>
  
  <div class="products-grid">
    {% for product in products %}
      <div class="product-card">
        <img src="{{ product.image }}" alt="{{ product.name }}" class="product-image">
        <h3 class="product-title">{{ product.name }}</h3>
        <p class="product-price">${{ product.price | round(precision=2) }}</p>
        <p>{{ product.description | truncate(length=100) }}</p>
        
        {% if product.inStock %}
          <button onclick="addToCart({{ product.id }})">Add to Cart</button>
        {% else %}
          <span class="out-of-stock">Out of Stock</span>
        {% endif %}
      </div>
    {% endfor %}
  </div>
  
  {% if pagination %}
  <div class="pagination">
    {% if pagination.prevPage %}
      <a href="?page={{ pagination.prevPage }}">Previous</a>
    {% endif %}
    
    <span>Page {{ pagination.currentPage }} of {{ pagination.totalPages }}</span>
    
    {% if pagination.nextPage %}
      <a href="?page={{ pagination.nextPage }}">Next</a>
    {% endif %}
  </div>
  {% endif %}
</body>
</html>

Next Steps

Released under the MIT License.