This is my sidebar content
More to come
https://github.com/adhocteam/pushup Skip to content Toggle navigation Sign up * Product + Actions Automate any workflow + Packages Host and manage packages + Security Find and fix vulnerabilities + Codespaces Instant dev environments + Copilot Write better code with AI + Code review Manage code changes + Issues Plan and track work + Discussions Collaborate outside of code + Explore + All features + Documentation + GitHub Skills + Blog * Solutions + For + Enterprise + Teams + Startups + Education + By Solution + CI/CD & Automation + DevOps + DevSecOps + Case Studies + Customer Stories + Resources * Open Source + GitHub Sponsors Fund open source developers + The ReadME Project GitHub community articles + Repositories + Topics + Trending + Collections * Pricing [ ] * # In this repository All GitHub | Jump to | * No suggested jump to results * # In this repository All GitHub | Jump to | * # In this organization All GitHub | Jump to | * # In this repository All GitHub | Jump to | Sign in Sign up {{ message }} adhocteam / pushup Public * Notifications * Fork 1 * Star 197 Pushup is for making modern, page-oriented web apps in Go pushup.adhoc.dev License MIT license 197 stars 1 fork Star Notifications * Code * Issues 31 * Pull requests 1 * Discussions * Actions * Projects 0 * Security * Insights More * Code * Issues * Pull requests * Discussions * Actions * Projects * Security * Insights adhocteam/pushup This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository. main Switch branches/tags [ ] Branches Tags Could not load branches Nothing to show {{ refName }} default View all branches Could not load tags Nothing to show {{ refName }} default View all tags Name already in use A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch? Cancel Create 10 branches 1 tag Code * Local * Codespaces * Clone HTTPS GitHub CLI [https://github.com/a] Use Git or checkout with SVN using the web URL. [gh repo clone adhoct] Work fast with our official CLI. Learn more. * Open with GitHub Desktop * Download ZIP Sign In Required Please sign in to use Codespaces. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching GitHub Desktop If nothing happens, download GitHub Desktop and try again. Launching Xcode If nothing happens, download Xcode and try again. Launching Visual Studio Code Your codespace will open once ready. There was a problem preparing your codespace, please try again. Latest commit @paulsmith paulsmith Update README.md ... 1b4b316 Jan 4, 2023 Update README.md 1b4b316 Git stats * 261 commits Files Permalink Failed to load latest commit information. Type Name Latest commit message Commit time .github/workflows github: pushup needs go > 1.18 Oct 20, 2022 _runtime docs: self-host the main Pushup website Oct 20, 2022 docs docs: embed YouTube Jan 4, 2023 example project: rename GitHub org Oct 6, 2022 scaffold docs: fix up URL to main site Dec 22, 2022 testdata language: Rename ^else and add ^else ^if Oct 1, 2022 tools tools: add program to fetch named character references Sep 19, 2022 vim-pushup Create README.md Oct 10, 2022 .gitignore docs: add YT embed to the README Jan 4, 2023 ABOUT.md Update ABOUT.md Sep 28, 2022 CODE_OF_CONDUCT.md meta: Add code of conduct Dec 22, 2022 CONTRIBUTING.md meta: quick fix to contributor guidelines Dec 22, 2022 LICENSE project: add MIT license Oct 10, 2022 Makefile meta: add a startup banner Jan 3, 2023 README.md Update README.md Jan 4, 2023 banner.txt meta: add a startup banner Jan 3, 2023 entities.go parser: improve open tag tokenizer against various inputs Sep 14, 2022 example-syntax-highlighting.png syntax: minor tweak screenshot Sep 13, 2022 flake.lock Nix stuff Jun 2, 2022 flake.nix dev-reloader: cut down on spurious reloads from editor temporaries Oct 6, 2022 go.mod project: rename GitHub org Oct 6, 2022 go.sum Move example demo app into its own directory Aug 10, 2022 main.go cmd: check that Go is installed Jan 3, 2023 main_test.go codegen: Escape leading dollar signs in .go names Dec 22, 2022 proc_attr_linux.go let pushup build on mac Aug 11, 2022 proc_attr_notlinux.go let pushup build on mac Aug 11, 2022 shell.nix dev: clean up shell.nix file Oct 20, 2022 version.go Add version to generated files Aug 25, 2022 View code [ ] Pushup - a page-oriented web framework for Go Project status What is Pushup? Pages in Pushup Getting started Installing Pushup Prerequisites Install an official release Install via git Install via go install Creating a new Pushup project Example demo app Go modules and Pushup projects Project directory structure Pages Layouts Static media File-based routing Dynamic routes Enhanced hypertext Inline partials Basic web framework functionality Escaping Pushup syntax How it works Directives ^import ^layout ^layout ! - no layout Go code blocks ^{ ^handler Control flow statements ^if ^for Expressions Simple expressions Explicit expressions Layout and templates ^section ^partial Vim syntax file README.md Pushup - a page-oriented web framework for Go workflow status Contributor Covenant Project status Pushup is an experiment. In terms of the development life cycle, it should be considered preview pre-release software: it is largely functional, likely has significant bugs (including potential for data loss) and/or subpar performance, but is suitable for demos and testing. It has a decent unit test suite, including fuzzing test cases for the parser. Don't count on it for anything serious yet, and expect significant breaking changes. screenshot of syntax highlighting of an example Pushup page * Pushup - a page-oriented web framework for Go + What is Pushup? o Pages in Pushup + Getting started o Installing Pushup # Prerequisites # Install an official release # Install via git # Install via go install o Creating a new Pushup project + Example demo app + Go modules and Pushup projects + Project directory structure + Pages + Layouts + Static media + File-based routing o Dynamic routes + Enhanced hypertext o Inline partials + Basic web framework functionality o Escaping + Pushup syntax o How it works o Directives # ^import # ^layout @ ^layout ! - no layout o Go code blocks # ^{ # ^handler o Control flow statements # ^if # ^for o Expressions # Simple expressions # Explicit expressions o Layout and templates # ^section # ^partial + Vim syntax file Pushup is an experimental new project that is exploring the viability of a new approach to web frameworks in Go. Pushup seeks to make building page-oriented, server-side web apps using Go easy. It embraces the server, while acknowledging the reality of modern web apps and their improvements to UI interactivity over previous generations. What is Pushup? Pushup is a program that compiles projects developed with the Pushup markup language into standalone web app servers. There are three main aspects to Pushup: 1. An opinionated project/app directory structure that enables file-based routing, 2. A lightweight markup alternative to traditional web framework templates that combines Go code for control flow and imperative, view-controller-like code with HTML markup, and 3. A compiler that parses that markup and generates pure Go code, building standalone web apps on top of the Go stdlib net/http package. Pages in Pushup The core object in Pushup is the "page": a file with the .up extension that is a mix of HTML, Go code, and a lightweight markup language that glues them together. Pushup pages participate in URL routing by virtue of their path in the filesystem. Pushup pages are compiled into pure Go which is then built along with a thin runtime into a standalone web app server (which is all net/http under the hood). The main proposition motivating Pushup is that the page is the right level of abstraction for most kinds of server-side web apps. The syntax of the Pushup markup language looks like this: ^import "time" ^{ title := "Hello, from Pushup!" }
The time is now ^time.Now().String().
^if time.Now().Weekday() == time.Friday {It's Friday! Enjoy the start to your weekend.
} ^else {Have a great day, we're glad you're here.
} You would then place this code in a file somewhere in your app/pages directory, like hello.up. The .up extension is important and tells the compiler that it is a Pushup page. Once you build and run your Pushup app, that page is automatically mapped to the URL path /hello. Getting started To make a new Pushup app, first install the main Pushup executable. Installing Pushup Prerequisites * go 1.18 or later Make sure the directory where the go tool installs executables is in your $PATH. It is $(go env GOPATH)/bin. You can check if this is the case with: echo $PATH | grep $(go env GOPATH)/bin > /dev/null && echo yes || echo no Install an official release Download Pushup for your platform from the releases page. Install via git git clone git@github.com:AdHocRandD/pushup.git cd pushup make Install via go install Make sure you have Go installed (at least version 1.18), and type: go install github.com/adhocteam/pushup@latest Creating a new Pushup project To create a new Pushup project, use the pushup new command. pushup new Without any additional arguments, it will attempt to create a scaffolded new project in the current directory. However, the directory must be completely empty, or the command will abort. To simulataneously make a new directory and generate a scaffolded project, pass a relative path as argument: pushup new myproject The scaffolded new project directory consists of a directory structure for .up files and auxiliary project Go code, and a go.mod file. Change to the new project directory if necessary, then do a pushup run, which compiles the Pushup project to Go code, builds the app, and starts up the server. pushup run If all goes well, you should see a message on the terminal that the Pushup app is running and listening on a port: || Pushup ready and listening on 0.0.0.0:8080 || By default it listens on port 8080, but with the -port or -unix-socket flags you can pick your own listener. Open http://localhost:8080/ in your browser to see the default layout and a welcome index page. Example demo app See the example directory for a demo Pushup app that demonstrates many of the concepts in Pushup and implements a few small common patterns like some HTMX examples and a simple CRUD app. Click on "view source" at the bottom of any page in the example app to see the source of the .up page for that route, including the source of the "view source" .up page itself. This is a good way to see how to write Pushup syntax. Go modules and Pushup projects Pushup treats projects as their own self-contained Go module. The build process assumes this is the case by default. But it is possible to include a Pushup project as part of a parent Go module. See the the -module option to pushup new, and the -build-pkg option to the pushup run command. Project directory structure Pushup projects have a particular directory structure that the compiler expects before building. The most minimal Pushup project would look like: app +-- layouts +-- pages | +-- index.up +-- pkg +-- static go.mod Pages Pushup pages are the main units in Pushup. They are a combination of logic and content. It may be helpful to think of them as both the controller and the view in a MVC-like system, but colocated together in the same file. They are also the basis of file-based routing: the name of the Pushup file, minus the .up extension, is mapped to the portion of the URL path for routing. Layouts Layouts are HTML templates that used in common across multiple pages. They are just HTML, with Pushup syntax as necessary. Each page renders its contents, and then the layout inserts the page contents into the template with the ^outputSection("contents") Pushup expression. Static media Static media files like CSS, JS, and images, can be added to the app/ static project directory. These will be embedded directly in the project executable when it is built, and are accessed via a straightforward mapping under the "/static/" URL path. File-based routing Pushup maps file locations to URL route paths. So about.up becomes / about, and foo/bar/baz.up becomes /foo/bar/baz. More TK ... Dynamic routes If the filename of a Pushup page starts with a $ dollar sign, the portion of the URL path that matches will be available to the page via the getParam() Pushup API method. For example, let's say there is a Pushup page at app/pages/people/ $id.up. If a browser visits the URL /people/1234, the page can access it like a named parameter with the API method getParam(), for example:ID: ^getParam(req, "id")
would output:ID: 1234
The name of the parameter is the word following the $ dollar sign, up to a dot or a slash. Conceptually, the URL route is /people/:id, where :id is the named parameter that is substituted for the actual value in the request URL. Directories can be dynamic, too. app/pages/products/$pid/details.up maps to /products/:pid/details. Multiple named parameters are allowed, for example, app/pages/users/ $uid/projects/$pid.up maps to /users/:uid/projects/:pid. Enhanced hypertext Inline partials Inline partials allow pages to denote subsections of themselves, and allow for these subsections (the inline partials) to be rendered and returned to the client independently, without having to render the entire enclosing page. Typically, partials in templating languages are stored in their own files, which are then transcluded into other templates. Inline partials, however, are partials declared and defined in-line a parent or including template. Inline partials are useful when combined with enhanced hypertext solutions (eg., htmx). The reason is that these sites make AJAX requests for partial HTML responses to update portions of an already-loaded document. Partial responses should not have enclosing markup such as base templates applied by the templating engine, since that would break the of the document they are being inserted into. Inline partials in Pushup automatically disable layouts so that partial responses have just the content they define. The ability to quickly define partials, and not have to deal with complexities like toggling off layouts, makes it easier to build enhanced hypertext sites. Basic web framework functionality All modern web frameworks should implement a standard set of functionality, spanning from safety to convenience. As of this writing, Pushup does not yet implement them all, but aspires to prior to any public release. Escaping By default, all content is HTML-escaped, so in general it is safe to directly place user-supplied data into Pushup pages. (Note that the framework does not (yet) do this in your Go code, data from form submissions and URL queries should be validated and treated as unsafe.) For example, if you wanted to display on the page the query a user searched for, this is safe: ^{ query := req.FormValue("query") }You search for: ^query
Pushup syntax How it works Pushup is a mix of a new syntax consisting of Pushup directives and keywords, Go code, and HTML markup. Parsing a .up file always starts out in HTML mode, so you can just put plain HTML in a file and that's a valid Pushup page. When the parser encounters a '^' character (caret, ASCII 0x5e) while in HTML mode, it switches to parsing Pushup syntax, which consists of simple directives, control flow statements, block delimiters, and Go expressions. It then switches to the Go code parser. Once it detects the end of the directive, statement, or expression, it switches back to HTML mode, and parsing continues in a similar fashion. Pushup uses the tokenizers from the go/scanner and golang.org/x/net/ html packages, so it should be able to handle any valid syntax from either language. Directives ^import Use ^import to import a Go package into the current Pushup page. The syntax for ^import is the same as a regular Go import declaration Example: ^import "strings" ^import "strconv" ^import . "strings" ^layout Layouts are HTML templates that enclose the contents of a Pushup page. The ^layout directive instructs Pushup what layout to apply the contents of the current page. The name of the layout following the directive is the filename in the layouts directory minus the .up extension. For example, ^layout main would try to apply the layout located at app/layouts/main.up. ^layout is optional - if it is not specified, pages automatically get the "default" layout (app/layouts/default.up). Example: ^layout homepage ^layout ! - no layout A page may choose to have no layout applied - that is, the contents of the page itself are sent directly to the client with no enclosing template. In this case, use the ! name: ^layout ! Go code blocks ^{ To include statements of Go in a Pushup page, type ^{ followed by your Go code, terminating with a closing }. The scope of a ^{ ... } in the compiled Go code is equal to its surrounding markup, so you can define a variable and immediately use it: ^{ name := "world" }Query: ^query
} ^for ^for takes a Go "for" statement condition, clause, or range, and a block, and repeatedly executes the block. Example: ^for i := 0; i < 10; i++ {Number ^i
} Expressions Simple expressions Simple Go expressions can be written with just ^ followed by the expression. "Simple" means: * variable names (eg., ^x) * dotted field name access of structs (eg., ^account.name) * function and method calls (eg., ^strings.Repeat("x", 3)) * index expressions (eg., a[x]) Example: ^{ name := "Paul" }Hello, ^name!
Outputs:Hello, Paul!
Notice that the parser stops on the "!" because it knows it is not part of a Go variable name. Example:The URL path: ^req.URL.Path
Outputs:The URL path: /foo/bar
Example: ^import "strings"^strings.Repeat("Hello", 3)
Outputs:HelloHelloHello
Explicit expressions Explicit expressions are written with ^ and followed by any valid Go expression grouped by parentheses. Example: ^{ numPeople := 4 }With ^numPeople people there are ^(numPeople * 2) hands
Outputs:With 4 people there are 8 hands
Layout and templates ^section Pushup layouts can have sections within the HTML document that Pushup pages can define with their own content to be rendered into those locations. For example, a layout could have a sidebar section, and each page can set its own sidebar content. In a Pushup page, sections are defined with the keyword like so: ^section sidebar {More to come
Elements
^partial list {Leagues
^partial teams {Teams
^partial players {Players
} } } ... To request a nested partial, make sure the URL path is preceded by each containing partial's name and a forward slash, for example, / sports/leagues/teams/players. Vim syntax file There is a vim plugin in the vim-pushup directory. You should be able to symlink it into your plugin manager's path. Alternatively, to install it manually: * Locate or create a syntax directory in your vim config directory (Usually ~/.vim/syntax for vim or ~/.config/nvim/syntax for neovim) * Copy syntax/pushup.vim into that directory * Locate or create a ftdetect directory in your vim config directory (Usually ~/.vim/syntax for vim or ~/.config/nvim/syntax for neovim) * Copy ftdetect/pushup.vim into that directory About Pushup is for making modern, page-oriented web apps in Go pushup.adhoc.dev Topics go http www Resources Readme License MIT license Code of conduct Code of conduct Stars 197 stars Watchers 12 watching Forks 1 fork Releases 1 tags Packages 0 No packages published Contributors 4 * @paulsmith paulsmith Paul Smith * @llimllib llimllib Bill Mill * @dvogel dvogel Drew Vogel * @eli-oat eli-oat Eli Mellen Languages * Go 95.9% * Vim Script 2.4% * CSS 1.4% * Other 0.3% Footer (c) 2023 GitHub, Inc. Footer navigation * Terms * Privacy * Security * Status * Docs * Contact GitHub * Pricing * API * Training * Blog * About You can't perform that action at this time. You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.