# Frappe Portal UI

> Working with Frappe portal pages and jinja rendering.

- Skill: `av-dev2/frappe-portal-ui` (Agent Skill)
- Install (CLI): `npx skillmds@latest add av-dev2/frappe-portal-ui`
- Raw SKILL.md: https://api.skillmd.com/api/skills/av-dev2/frappe-portal-ui/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: av-dev2 (https://skillmd.com/u/av-dev2)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/av-dev2/frappe-portal-ui

---


# Portal Pages (Public Website)

Server-rendered Jinja templates for public-facing pages.

## Jinja templates

File: `apps/<app>/<app>/www/<page_name>.html`

```html
{% extends "templates/web.html" %}
{% block page_content %}
<h1>Expenses</h1>
{% for expense in expenses %}
<div>{{ expense.title }} — {{ expense.amount }}</div>
{% endfor %}
{% endblock %}
```

Context via Python:
File: `apps/<app>/<app>/www/<page_name>.py`

```python
import frappe

def get_context(context):
    context.expenses = frappe.db.get_all("Expense",
        filters={"owner": frappe.session.user},
        fields=["title", "amount"])
```

## Portal settings

In `hooks.py`:
```python
website_route_rules = [
    {"from_route": "/expenses", "to_route": "Expense"},
]

has_website_permission = {
    "Expense": "myapp.permissions.has_website_permission"
}
```

