mirror of
https://github.com/roots/wp-packages
synced 2026-07-22 02:10:54 +08:00
Replace Go's html/template with CloudyKit/jet/v6 for server-rendered templates. Jet provides first-class parameterized blocks, template inheritance via extends/yield, and C-like expressions — eliminating the dict helper workarounds that html/template required for reusable components. Add components.html with four reusable Jet blocks: - shell(command, variant, class) — copyable command boxes (replaces ~16 duplicated instances across 6 templates) - notice(variant, class) with yield content — alert boxes with variant-based styling and content slots - input(icon, name, ...) — form inputs with icon and keyboard hint - pagination(pager, class) — pagination controls driven by pre-computed buildPagination() data Key changes: - templates.go: embed.FS loader for Jet, function registration via AddGlobal, buildPagination() helper, render() using VarMap - handlers.go: simplified render calls (no more template combinations) - router.go: *jet.Set replaces *templateSet - All 13 templates converted to Jet syntax (extends/block/yield) - Tailwind scanning unaffected (templates remain .html files) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
103 lines
No EOL
7.2 KiB
HTML
103 lines
No EOL
7.2 KiB
HTML
{{extends "layout.html"}}
|
|
{{import "components.html"}}
|
|
{{block title()}}WP Packages — WordPress Packages for Composer | WPackagist Alternative{{end}}
|
|
{{block meta_seo()}}
|
|
<meta name="description" content="Composer repository for WordPress plugins and themes. A 17x faster, open-source WPackagist alternative with 5-minute update cycles.">
|
|
{{if AppURL}}<link rel="canonical" href="{{AppURL}}/">{{end}}
|
|
{{if Page && Page > 1}}<meta name="robots" content="noindex, follow">{{end}}
|
|
{{end}}
|
|
{{block json_ld()}}{{jsonLD(JSONLD)|raw}}{{end}}
|
|
{{block og_meta()}}
|
|
<meta property="og:title" content="WP Packages — WordPress Packages for Composer | WPackagist Alternative">
|
|
<meta property="og:description" content="Composer repository for WordPress plugins and themes.">
|
|
{{if OGImage}}<meta property="og:image" content="{{OGImage}}">{{end}}
|
|
{{if AppURL}}<meta property="og:url" content="{{AppURL}}">{{end}}
|
|
<meta property="og:type" content="website">
|
|
<meta name="twitter:card" content="summary_large_image">
|
|
<meta name="twitter:title" content="WP Packages — WordPress Packages for Composer | WPackagist Alternative">
|
|
<meta name="twitter:description" content="Composer repository for WordPress plugins and themes.">
|
|
{{if OGImage}}<meta name="twitter:image" content="{{OGImage}}">{{end}}
|
|
{{end}}
|
|
{{block body()}}
|
|
<section class="relative overflow-hidden border-b border-gray-200/50">
|
|
<div class="absolute inset-0 bg-gradient-to-b from-brand-lightest/40 to-transparent"></div>
|
|
<div class="relative mx-auto max-w-6xl px-4 sm:px-6 lg:px-8 pt-16 pb-12 sm:pt-24 sm:pb-16 text-center">
|
|
<h1 class="text-4xl sm:text-5xl lg:text-6xl font-bold tracking-tight text-gray-900 mb-6 text-balance">WordPress Packages<br><span class="text-brand-primary">for Composer</span></h1>
|
|
<h2 class="text-xl sm:text-2xl text-gray-500 max-w-xl mx-auto mb-4 text-balance">Composer repository for WordPress plugins and themes</h2>
|
|
<h3 class="text-base text-gray-500 max-w-xl mx-auto mb-6 text-balance">A 17x faster, fully open-source alternative to WPackagist that updates every 5 minutes</h3>
|
|
<p class="mb-10"><a href="/wp-packages-vs-wpackagist" class="text-sm font-medium text-brand-primary hover:underline">See how WP Packages compares to WPackagist →</a></p>
|
|
<a href="/docs" class="inline-flex items-center rounded-lg bg-brand-primary px-5 py-2.5 text-sm font-medium text-white hover:bg-brand-primary/85 transition-colors">Get Started</a>
|
|
</div>
|
|
<div class="relative border-t border-gray-200/50">
|
|
<div class="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8">
|
|
<div class="grid grid-cols-1 sm:grid-cols-3 divide-y sm:divide-y-0 sm:divide-x divide-gray-200/50">
|
|
<div class="py-6 text-center">
|
|
<div class="text-2xl sm:text-3xl font-bold text-brand-primary tabular-nums">{{formatNumber(Stats.PluginInstalls)}}</div>
|
|
<div class="text-sm text-gray-500 mt-0.5">Plugin Installs</div>
|
|
</div>
|
|
<div class="py-6 text-center">
|
|
<div class="text-2xl sm:text-3xl font-bold text-brand-primary tabular-nums">{{formatNumber(Stats.ThemeInstalls)}}</div>
|
|
<div class="text-sm text-gray-500 mt-0.5">Theme Installs</div>
|
|
</div>
|
|
<div class="py-6 text-center">
|
|
<div class="text-2xl sm:text-3xl font-bold text-brand-primary tabular-nums">{{formatNumber(Stats.RootsDownloads)}}</div>
|
|
<div class="text-sm text-gray-500 mt-0.5"><a href="/wordpress-core" class="hover:text-gray-900 transition-colors"><code class="text-xs font-mono bg-gray-100 px-1.5 py-0.5 rounded-md border border-gray-200/40">roots/wordpress</code> Installs</a></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
<section class="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8 py-10">
|
|
<div class="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 mb-2">
|
|
<form id="filter-form" method="GET" action="/" hx-get="/packages-partial" hx-target="#package-results" hx-trigger="submit, change from:select, input from:[name=search] delay:300ms changed" hx-push-url="false" hx-swap="innerHTML" class="flex flex-col sm:flex-row items-start sm:items-center gap-2 flex-1 scroll-mt-16">
|
|
<div class="relative w-full sm:max-w-md">
|
|
{{yield input(icon="search", type="search", name="search", value=Filters.Search, placeholder="Search packages...", showShortcut=true)}}
|
|
</div>
|
|
<div class="flex items-center gap-2">
|
|
<label for="filter-type" class="sr-only">Package type</label>
|
|
<div class="relative">
|
|
<svg class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 pointer-events-none" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 0 1-.659 1.591l-5.432 5.432a2.25 2.25 0 0 0-.659 1.591v2.927a2.25 2.25 0 0 1-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 0 0-.659-1.591L3.659 7.409A2.25 2.25 0 0 1 3 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0 1 12 3Z"/></svg>
|
|
<select id="filter-type" name="type" class="h-10 pl-9 pr-8 text-sm border border-gray-200 rounded-lg bg-white select-chevron focus:outline-none focus:ring-2 focus:ring-brand-primary/20 focus:border-brand-primary">
|
|
<option value="">All types</option>
|
|
<option value="plugin"{{if Filters.Type == "plugin"}} selected{{end}}>Plugins</option>
|
|
<option value="theme"{{if Filters.Type == "theme"}} selected{{end}}>Themes</option>
|
|
</select>
|
|
</div>
|
|
<label for="filter-sort" class="sr-only">Sort by</label>
|
|
<div class="relative">
|
|
<svg class="absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 text-gray-400 pointer-events-none" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M3 7.5 7.5 3m0 0L12 7.5M7.5 3v13.5m13.5 0L16.5 21m0 0L12 16.5m4.5 4.5V7.5"/></svg>
|
|
<select id="filter-sort" name="sort" class="h-10 pl-9 pr-8 text-sm border border-gray-200 rounded-lg bg-white select-chevron focus:outline-none focus:ring-2 focus:ring-brand-primary/20 focus:border-brand-primary">
|
|
<option value="composer_installs"{{if Filters.Sort == "composer_installs"}} selected{{end}}>Composer installs</option>
|
|
<option value="active_installs"{{if Filters.Sort == "active_installs"}} selected{{end}}>Active installs</option>
|
|
<option value="name"{{if Filters.Sort == "name"}} selected{{end}}>Name</option>
|
|
<option value="updated"{{if Filters.Sort == "updated"}} selected{{end}}>Recently updated</option>
|
|
</select>
|
|
</div>
|
|
<button type="submit" class="sr-only">Search</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div id="package-results">
|
|
{{include "package_results.html"}}
|
|
</div>
|
|
|
|
<div class="flex justify-center mt-8">
|
|
{{yield notice() content}}
|
|
Some WordPress plugins have a latest version on WordPress.org that isn't tagged in SVN. These can be installed via <code class="text-xs font-mono bg-amber-100 px-1 py-0.5 rounded whitespace-nowrap">dev-trunk</code>. <a href="/untagged" class="font-medium underline underline-offset-2 hover:no-underline">Learn more on our Untagged Plugins page</a>.
|
|
{{end}}
|
|
</div>
|
|
|
|
</section>
|
|
{{if BlogPosts}}
|
|
<section class="border-t border-gray-200/50 py-14">
|
|
<div class="mx-auto max-w-6xl px-4 sm:px-6 lg:px-8 text-center">
|
|
<h2 class="text-2xl sm:text-3xl font-bold text-gray-900 mb-6">Latest updates</h2>
|
|
<ul class="space-y-2 max-w-xl mx-auto">
|
|
{{range _, post := BlogPosts}}
|
|
<li><a href="{{post.Link}}" class="text-sm font-medium text-brand-primary hover:underline">{{post.Title}}</a></li>
|
|
{{end}}
|
|
</ul>
|
|
</div>
|
|
</section>
|
|
{{end}}
|
|
{{end}} |