Agent Skills by ALSEL
OpenAIソフトウェア開発⭐ リポ 7品質スコア 64/100

gastro

Gastroフレームワークを使用してページとコンポーネントを構築します。.gastroファイル、ページ、コンポーネント、ルーティング、SSEハンドラーの作成・編集・デバッグ、またはgastro devサーバーの操作時に使用します。

description の原文を見る

Build pages and components with the Gastro framework. Use when creating, editing, or debugging .gastro files, pages, components, routing, SSE handlers, or working with the gastro dev server.

SKILL.md 本文

コンテキスト

Gastro は Go 用のファイルベースコンポーネントフレームワークです。.gastro ファイルは Go フロントマターと html/template マークアップを組み合わせ、自動ファイルベースルーティングを備えた型安全な Go コードにコンパイルされます。Astro の開発体験、Go の型安全性、PHP のファイルベースルーティングを兼ね備えています。

生成されたコードは .gastro/ ディレクトリに置かれます(gitignore 対象で、手動編集厳禁)。ランタイムライブラリ pkg/gastro/ は生成コードの唯一の依存関係です。

プロジェクト構造

すべての Gastro プロジェクトは以下のレイアウトに従います:

myapp/
  pages/           # HTTP ルートになる .gastro ファイル(コンポーネントのみのプロジェクトではオプション)
  components/      # 再利用可能な .gastro コンポーネント
  static/          # /static/ で提供される CSS、画像、アセット
  .gastro/         # 生成された Go コード(gitignore 対象、編集禁止)
  main.go          # アプリケーションのエントリーポイント
  go.mod

pages/ はオプションです。components/ のみを含むプロジェクトは pages/ なしでコンパイルと実行ができます。これは gastro が大きなモジュール内に組み込まれ、コンポーネントレンダリングのためだけに使用される場合に便利です。

ファイル形式

.gastro ファイルには --- デリミタで区切られた 2 つのセクションがあります:

---
Go フロントマター(サーバーで実行)
---
HTML テンプレート本体(html/template でレンダリング)
  • フロントマター:Go コード。package 宣言はありません(ジェネレーターが処理します)。gastro パッケージは暗黙的に利用可能です。
  • テンプレート本体:標準の Go html/template 構文です。

ページ

ページは pages/ ディレクトリ内の .gastro ファイルです。各ページが HTTP ルートになります。

ページの作成

フロントマターで gastro.Context() を呼び出すと、ファイルがページとしてマークされ、HTTP リクエストにアクセスできます:

---
ctx := gastro.Context()

Title := "Hello"
Name := ctx.Query("name")
---
<h1>{{ .Title }}</h1>
<p>Hello, {{ .Name }}</p>

静的ページ

リクエストアクセスが不要なページは gastro.Context() を省略できます:

---
import Layout "components/layout.gastro"

Title := "About"
---
{{ wrap Layout (dict "Title" .Title) }}
    <h1>About</h1>
{{ end }}

変数の可視性

Go のエクスポート規約に準じます:

  • 大文字で始まる変数(TitlePosts)はテンプレートに {{ .Title }}{{ .Posts }} としてエクスポートされます
  • 小文字で始まる変数(errslug)はフロントマター内のプライベート変数です
---
ctx := gastro.Context()
posts, err := db.ListPublished()    // 小文字 -> プライベート
if err != nil {
    ctx.Error(500, "Failed to load posts")
    return
}

Posts := posts                       // 大文字 -> {{ .Posts }}
Title := "Blog"                      // 大文字 -> {{ .Title }}
---
<h1>{{ .Title }}</h1>
{{ range .Posts }}
<p>{{ .Title }}</p>
{{ end }}

ファイルベースルーティング

ファイルルート
pages/index.gastroGET /
pages/about/index.gastroGET /about
pages/blog/index.gastroGET /blog
pages/blog/[slug].gastroGET /blog/{slug}
pages/[category]/[id].gastroGET /{category}/{id}
  • index.gastro はディレクトリルートにマップされます
  • [param] は Go 1.22+ のルーターパターンで {param} になります
  • GET ルートのみが生成されます。その他のメソッドは main.go で登録してください。

Context API

gastro.Context() は以下のメソッドを持つ *Context を返します:

メソッド説明
Request() *http.Request基礎となる HTTP リクエスト
Param(name string) string[param] セグメントからの URL パスパラメータ
Query(name string) stringクエリ文字列パラメータ(ない場合は空文字列)
Redirect(url string, code int)リダイレクトを送信。その後 return を呼び出す必須。
Error(code int, msg string)エラーレスポンスを送信。その後 return を呼び出す必須。
Header(key, val string)レスポンスヘッダーを設定(テンプレートレンダリング前)

エラーハンドリング

2 つのレイヤーがあります:

  1. 明示的:制御されたエラーレスポンスのための ctx.Error(code, msg) + return
  2. パニック回復:すべてのハンドラーは defer gastro.Recover(w, r) でラップされ、パニックをキャッチして 500 を返します

コンポーネント

コンポーネントは components/ ディレクトリ内の再利用可能な .gastro ファイルです。型付きプロップを受け取り、子要素をレンダリングできます。

コンポーネントの定義

gastro.Props() を使用してプロップを宣言します。同じフロントマターで Props 構造体を定義します:

---
type Props struct {
    Title  string
    Author string
}

p := gastro.Props()
Title := p.Title
Author := p.Author
---
<article>
    <h2>{{ .Title }}</h2>
    <p>By {{ .Author }}</p>
</article>

計算値

複数のプロップから派生値が必要な場合は、まず構造体全体を割り当てます:

---
import "fmt"

type Props struct {
    Label string
    X     int
}

p := gastro.Props()
Label := p.Label
CX := fmt.Sprintf("%d", p.X + 135)
---
<text x="{{ .CX }}">{{ .Label }}</text>

コンポーネントのインポートと使用

.gastro ファイル拡張子付きでインポートすると、Go インポートと区別されます:

---
import (
    "myblog/db"

    Layout "components/layout.gastro"
    PostCard "components/post-card.gastro"
)

ctx := gastro.Context()
posts, _ := db.ListPublished()
Posts := posts
---
{{ wrap Layout (dict "Title" "Home") }}
    {{ range .Posts }}
    {{ PostCard (dict "Title" .Title "Slug" .Slug) }}
    {{ end }}
{{ end }}

リーフコンポーネント vs ラッパーコンポーネント

リーフコンポーネント(子なし)は直接関数呼び出しを使用します:

{{ PostCard (dict "Title" .Title "Slug" .Slug) }}

ラッパーコンポーネント(子を受け取る)は wrap ... {{ end }} を使用します:

{{ wrap Layout (dict "Title" .Title) }}
    <h1>Hello</h1>
    <p>This becomes the children content.</p>
{{ end }}

子要素

{{ .Children }} を子要素がレンダリングされるべき場所に配置します。コンポーネント内に {{ .Children }} は 1 つだけです:

---
type Props struct {
    Title string
}

Title := gastro.Props().Title
---
<html>
<head><title>{{ .Title }}</title></head>
<body>
    <nav>...</nav>
    <main>{{ .Children }}</main>
    <footer>...</footer>
</body>
</html>

子要素は親のデータコンテキストでレンダリングされるため、親のテンプレート変数を参照できます。

プロップ構文

プロップは dict 構文で渡されます:

構文意味
.Expr親コンテキストからのテンプレート式"Title" .Title
"literal"文字列リテラル"Title" "About"
(.Val | func "arg")パイプ式"Date" (.CreatedAt | timeFormat "Jan 2, 2006")

型の強制変換

Gastro は構造体フィールドの型に一致するようプロップ値を強制変換します:

対象型受け入れられる値
string任意の値(fmt.Sprintf 経由)
boolboolstring"true""false"
intintint64float64float32string(解析済み)
float64float64float32intstring(解析済み)

テンプレート関数

登録なしですべてのテンプレートで利用可能な 18 個の組み込み関数があります:

文字列upperlowertitletrimjoinsplitcontainsreplace

セーフティ(html/template エスケープをバイパス --信頼できるコンテンツのみで使用):safeHTMLsafeAttrsafeURLsafeCSSsafeJS

ユーティリティdefaulttimeFormatjsondictlist

パイプ値を受け取る関数は、それを最後のパラメータとして取ります(Go テンプレート規約)。

カスタムヘルパー

main.go で登録します:

routes := gastro.Routes(
    gastro.WithFuncs(template.FuncMap{
        "formatEUR": func(cents int) string {
            return fmt.Sprintf("%.2f EUR", float64(cents)/100)
        },
    }),
)

SSE とリアルタイム

SSE エンドポイントは、Gastro ルートの横に登録される通常の Go HTTP ハンドラーです。

汎用 SSE

func handleUpdates(w http.ResponseWriter, r *http.Request) {
    sse := gastro.NewSSE(w, r)

    for {
        select {
        case <-sse.Context().Done():
            return
        case msg := <-updates:
            sse.Send("update", msg)
        }
    }
}

Datastar 統合

import "github.com/andrioid/gastro/pkg/gastro/datastar"

func handleIncrement(w http.ResponseWriter, r *http.Request) {
    html, err := gastro.Render.Counter(gastro.CounterProps{Count: 42})
    if err != nil {
        http.Error(w, err.Error(), 500)
        return
    }

    sse := datastar.NewSSE(w, r)
    sse.PatchElements(html)
}

型安全な Render API

コンパイラは各コンポーネント用に Render メソッドを生成します:

html, err := gastro.Render.Counter(gastro.CounterProps{Count: 42})
html, err := gastro.Render.Layout(gastro.LayoutProps{Title: "Home"}, children...)

main.go での配線

mux := http.NewServeMux()
mux.HandleFunc("GET /api/increment", handleIncrement)
mux.Handle("/", gastro.Routes())
http.ListenAndServe(":4242", mux)

Datastar ページ属性

---
Title := "Counter"
---
<div id="count">0</div>
<button data-on:click="@get('/api/increment')">+1</button>

Raw ブロック

{{ raw }}...{{ endraw }} を使用して、リテラルテンプレート構文と HTML をテキストとして表示します。コンパイラは、テンプレートデリミタ({{/}})と HTML 特殊文字(<>&)の両方をエスケープするため、コンテンツはブラウザでプレーンテキストとしてレンダリングされます。

<pre><code>
{{ raw }}
<h1>{{ .Greeting }}</h1>
<p>Hello {{ .Name }}, nice to see you.</p>
{{ endraw }}
</code></pre>

作成者は {{ raw }}...{{ endraw }} 内にプレーンコードを書くと、そのまま表示されます。コンパイラがすべてのエスケープを処理します:

  • {{{{ "{{" }}(テンプレートデリミタエスケープ)
  • }}{{ "}}" }}(テンプレートデリミタエスケープ)
  • <&lt;(HTML エンティティエスケープ)
  • >&gt;(HTML エンティティエスケープ)
  • &&amp;(HTML エンティティエスケープ)

{{ raw }}{{ endraw }} マーカーの周囲の空白は常にトリミングされるため、raw ブロックは <pre><code> に余分な空行なしでクリーンに統合されます。

短いインラインの記述には、インライン形式を使用します:<code>{{ raw }}{{ .Children }}{{ endraw }}</code>

Raw ブロックはネストできません。最初の {{ endraw }} が常にブロックを閉じます。

Markdown

.gastro テンプレートに markdown ファイルのレンダリングされた HTML をインラインするには {{ markdown "path/to/file.md" }} を使用します。このディレクティブは gastro generate によってコンパイル時に展開されます:ファイルが読み込まれ、goldmark(GFM + 脚注)で解析され、chroma で構文強調表示され、生成されたテンプレートに焼き込まれます。実行時の markdown 解析はなく、新しいランタイム依存関係もありません。

パスルール

  • ./foo.md または ../shared/foo.md.gastro ファイルのディレクトリを基準に解決されます。パスはプロジェクトルート外に到達できます(例:共有 docs/ ディレクトリ)。
  • content/foo.mdpages/docs/foo.md — その他のパスはプロジェクトルートを基準に解決されます。
  • 絶対パスは拒否されます。
  • ファイルは .md 拡張子を持つ必要があります。

使用方法

---
import DocsLayout "components/docs-layout.gastro"

Title := "Getting Started"
---
{{ wrap DocsLayout (dict "Title" .Title) }}
    {{ markdown "./getting-started.md" }}
{{ end }}

引数は文字列リテラルでなければなりません — コンパイル時に評価され、実行時ではありません。動的パス({{ markdown .Slug }})はサポートされていません。

制約

  • Markdown ファイルは純粋なコンテンツです:フロントマター、テンプレート補間、コンポーネント埋め込みはありません。動的データが必要な場合は、markdown 呼び出しの周囲の .gastro シェルに置きます。
  • コードフェンス(およびインライン `code`)は自動的に保護されます—その内部の {{/}} はエスケープされるため、html/template は再解析しません。markdown 内で {{ raw }} は必要ありません。
  • 構文強調表示は chroma の github テーマを使用してクラス出力を行います。ユーザーは一致する CSS を含める必要があります(gastro new プロジェクトには static/chroma.css が付属しています)。

開発ループ

開発ウォッチャーはプロジェクト内のどこでも .md ファイルを追跡します(隠しディレクトリ、node_modulesvendortmp をスキップ)。変更は .gastro ファイルへのテンプレート編集と同じように、再生成 + リロードをトリガーします。

静的アセット

  • static/ にファイルを配置
  • /static/ URL プレフィックスで提供
  • テンプレートで /static/styles.css として参照
  • プロダクション:go:embed 経由でバイナリに組み込まれます
  • 開発モード(GASTRO_DEV=1):ディスクから提供(変更はライブ)

開発ワークフロー

gastro list — コンポーネントとページを検出

gastro list           # Props シグネチャ付きの整列テーブル
gastro list --json    # JSON 配列 — スクリプトとエージェントから使用

エントリごとの JSON 形式:{"kind":"component"|"page", "name":"Card", "path":"components/card.gastro", "props":[{"name":"Title","type":"string"}]}props は常に配列であり、null にはなりません。

gastro dev(主なワークフロー)

gastro dev

開発サーバーは:

  • すべての .gastro ファイルの変更を監視
  • Go コードを自動的に再生成
  • サーバーをリビルドして再起動
  • テンプレート本体の変更:再起動なしでホットリロード
  • フロントマター / Go コードの変更:完全リビルド + 再起動
  • CSS / 静的アセットの変更:ライブ(ディスクから読み込み、再起動不要)
  • デフォルトポート:4242(PORT 環境変数でオーバーライド)

組み込みパッケージプロジェクト

サーバープロセスが gastro プロジェクトルート以外のディレクトリから実行される場合、 gastro が .gastro/templates/static/ を見つけられるように GASTRO_DEV_ROOT を設定します:

GASTRO_DEV=1 GASTRO_DEV_ROOT=/path/to/internal/web go run ./cmd/myapp

これを設定しないと、gastro は cwd にフォールバックし、テンプレート読み込み時に「no such file or directory」エラーでクラッシュします。完全な mise タスク例は docs/dev-mode.md を参照してください。

プロダクションビルド

# ワンステップビルド
gastro build
./app

# または手動で:
gastro generate
GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o dist/myapp .

手動コード生成

開発サーバー外でのみ必要です(CI、デプロイメントスクリプト、クロスコンパイル):

gastro generate
go build -o myapp .

ルール

  1. .gastro/ 内のファイルは編集しないでください — これらは生成されたもので、上書きされます。
  2. 開発中は gastro dev を使用してください — コード生成、リビルド、再起動を自動的に処理します。
  3. ctx.Redirect()ctx.Error() の後は常に return を呼び出してください — そうしないとテンプレートがレンダリングされます。
  4. Props 構造体は gastro.Props() を呼び出すコンポーネントのフロントマターで定義する必須 です。
  5. p := gastro.Props() パターンを使用してください — 変数に割り当ててからフィールドを抽出します。gastro.Props().Field チェーンを避けます。
  6. 大文字 = エクスポート、小文字 = プライベート — これはフロントマター変数と Props 構造体フィールドの両方に適用されます。
  7. コンポーネントインポートは .gastro 拡張子を使用してください — これがコンパイラが Go パッケージインポートから区別する方法です。
  8. コード例のテンプレート式はエスケープされる必須 — リテラルテンプレート構文を出力するには {{ raw }}...{{ endraw }} ブロックを使用します。従来の/シンプルな場合は、{{ "{{ .Var }}" }} も機能します。
  9. -race でテストを実行してください — 常に go test -race ./... または go build -race を使用してデータレースをキャッチします。
  10. ビジネスロジックは Go パッケージに属します.gastro ファイルはコンシューマーであり、プロバイダーではありません。モデル、サービス、データベースコードを通常の .go ファイルに保持します。

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
andrioid
リポジトリ
andrioid/gastro
ライセンス
MIT
最終更新
2026/5/10

Source: https://github.com/andrioid/gastro / ライセンス: MIT

関連スキル

汎用ソフトウェア開発⭐ リポ 39,967

doubt-driven-development

重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。

by addyosmani
汎用ソフトウェア開発⭐ リポ 1,175

apprun-skills

TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。

by yysun
OpenAIソフトウェア開発⭐ リポ 797

desloppify

コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。

by Git-on-my-level
汎用ソフトウェア開発⭐ リポ 39,967

debugging-and-error-recovery

テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。

by addyosmani
汎用ソフトウェア開発⭐ リポ 39,967

test-driven-development

テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。

by addyosmani
汎用ソフトウェア開発⭐ リポ 39,967

incremental-implementation

変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。

by addyosmani
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: andrioid · andrioid/gastro · ライセンス: MIT