Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: v0 web package with routing/rendering/utility functions #866

Closed
wants to merge 1 commit into from

Conversation

proggR
Copy link

@proggR proggR commented Jun 2, 2023

Description

I noticed routing for the moment in realms is handled mostly with ad-hoc if statements and had a bit more complex needs for the commune hacking now tracked on the commune-realms branch, so I've rolled a simple web package aiming to simplify handling gnoweb requests. Includes a Templater renderer that supports per-key sub Renderers, allowing for things like globally defined custom renderers for keys like username or postURL, etc.

Contributors Checklist

  • Tests with a ThingsRouter are present in web_test. Could use more coverage after feature scope creep.
  • README.md captures the package's constructs and includes example snippets

Example usage copy pasted from README:

_r := web.NewRouter()
_r.SetFallback(NotFound)
_r.AddRoute("",Home)
_r.AddRoute("{communeID}/proposals/{proposalID}",ProposalProfile)
_r.AddRoute("{communeID}",CommuneProfile)

[...]

// inside realm's Render(path) function 
_req, _action := _r.Resolve(path_)
return _action(_req).Render()

[...]

const viewCommune string = 
`# {communeID}
  
Admin: {admin}

Link: {link}

List: 
  {list}


Link List: 

  {linkList}`

[...]

func CommuneProfile(req_ *web.Request) *web.Response {
	_communeStr := req_.Value("communeID")
	_communeID := identity.IDString(_communeStr)
	_exists := daoRegistry.Exists(_communeID)
	if !_exists {
		_res := ufmt.Sprintf("You are on commune: %s. Does not exist.",_communeStr)
		return req_.Respond(_res, web.Stringer)
	}

	_kv := web.NewKV()	
	_d := daoRegistry.DAO(_communeID)
	
	_list := []string{"one","three","two","apple"}
	_link := web.NewLink("google","https://google.com")
	_links := []*web.Link{_link,_link,_link}


	// return req_.Respond(_d, web.Selfer)
	_kv.Add("communeID", _communeID)
	_kv.Add("admin",string(_d.Identity.Account()))
	_kv.Add("link",web.Linker(_link))
	_kv.Add("list",web.Lister(_list))
	_kv.Add("linkList",web.LinkLister(_links))
	_template := web.NewTemplate(viewCommune, _kv.Keys(), _kv.Values(), avl.Tree{})	

	return req_.Respond(_template, web.Templater)
}

// Alternative to above example

_renderers := avl.Tree{}
_renderers.Set("link",web.Linker)
_renderers.Set("list",web.Lister)
_renderers.Set("linkList",web.LinkLister)

[...]

_kv.Add("link",_link)
_kv.Add("list",_list)
_kv.Add("linkList",_links)

_template := web.NewTemplate(viewCommune, _kv.Keys(), _kv.Values(), _renderers)	
return req_.Respond(_template, web.Templater)

@proggR proggR requested a review from a team as a code owner June 2, 2023 16:49
@github-actions github-actions bot added the 🧾 package/realm Tag used for new Realms or Packages. label Jun 2, 2023
@proggR
Copy link
Author

proggR commented Jun 5, 2023

Self-reviewing after a couple days either afk or delving into umpteen other half-baked starts on packages: this needs better/any encapsulation in the core structs. Part of the reasoning for public everything was admittedly just laziness/wanting to see things work, while part was an active choice wanting to enable devs to steal whatever pieces of this they want to use without having to adopt it all, abusing all fields as they see fit... but also... that could be bad if not leveraged properly, and IMO the interface is likely close-enough to being able to service all above-board needs that I feel like I've been too open with the core-struct fields and should likely tighten that up before this is accepted into main.

The example having public renderers (ie: the CommuneProfile example, that should probably be communeProfile) are largely implementation specific things I'll update with a subsequent commit, but the more I stare at it all, the more I see less of the "enable all hacks" angle, and more the "support only the API you want to support" angle, and would love some feedback in either direction as I tighten it up :)

See: #869 for a question I have re: Render and its relationship to leveraging the project as a self-referential API provider.

@proggR proggR mentioned this pull request Jun 5, 2023
@moul moul mentioned this pull request Jun 8, 2023
9 tasks
@moul moul marked this pull request as draft June 8, 2023 14:46
@moul
Copy link
Member

moul commented Jun 8, 2023

I'm currently working on the router feature in PR #882, as it was on my to-do list.

Regarding the framework, you have the flexibility to choose between a monolithic approach or reusing generic parts. Just keep in mind that the "web" keyword is valuable, and we may need to find a more unique name if necessary, at least while we share the demo/ namespace.

Right now, I suggest continuing with your preferred approach. When you believe there's enough material for a feedback round, let me know (remove the draft status). Feel free to provide review instructions at that time.

@proggR
Copy link
Author

proggR commented Jun 9, 2023

Finally had a chance to comb through #882. Interesting timing/interesting seeing the similarities/differences between your PR and the Router in this :)

Re: the name, I'll noodle on a name change. The importance of web as a name isn't lost on me so I'd be happy to re-assess if there might be any other candidate for a web package that makes more sense :). I considered mvc when I started, since that was kind of the angle I was chasing with this, but there's no real model construct so that felt inaccurate.

FWIW, while this PR/package I'll likely keep using for personal realm dev projects and will aim to polish up/resubmit while I do, I'm finding I run into more situations where a FSM (like #856) would be handy (have a MQ thing in the works, along with an "upkeep" construct, neither of which care yet about web, but both which would benefit from a FSM). Are there any FSM todos/packages I might have missed already being used/worked on?

@thehowl
Copy link
Member

thehowl commented Oct 28, 2024

Closing as draft for 1yr+. You're welcome to re-open to continue it.

@thehowl thehowl closed this Oct 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🧾 package/realm Tag used for new Realms or Packages.
Projects
Status: Done
Status: 🌟 Wanted for Launch
Development

Successfully merging this pull request may close these issues.

4 participants