Managable Patterned Contextual Lists
Idea
+issues
We need to make it easy to create lists of patterned cards. Say you want to attach a list of files to a ticket. Or create a blog where each post includes a gallery with a bunch of photos.
It's sorta-kinda possible now with Pointers, but it requires either (a) spending a bunch of time on names or (b) using autoname rules. Consider attaching files to a ticket. One thing you could do now is to create a +files card (Pointer), type in the name of each file you want to upload, click on the name, upload the file... Painful! Another route would be to create autonamed files, each of which has a subcard (eg +ticket) auto-relating the file back to the Ticket.
+solution
The core thing we need to figure out is how we want the data to look.
Regardless of what data approach we take, we probably want a super simple interface with something like "Add another File" (for the file-on-a-ticket example) that ends up creating file cards in place. Same goes for photos in a gallery, contextual transactions, whatever.
Sol I. One solution would be to add extra interface around the autonaming solution to make it really easy to add these cards in place. If we go this route, the data for the files-on-a-ticket example would end up like this:
- MyTicket (ticket)
- File-001 (File)
- File-001+ticket (Pointer) -> My Ticket
.. and so forth.
Sol II. Another solution would be to add extra handling around the pointer approach that makes it so that each of the items gets autonamed. If we were to keep our traditional autonaming, it might looks something like this:
- MyTicket (ticket)
- File-001 (File)
- MyTicket+myfiles -> File-001
We could, of course, consider different autonaming patterns here, for example:
- MyTicket+myfiles+1
- MyTicket+myfiles+File-1
- MyTicket+MyFiles-001
It would be possible to choose a naming pattern that obviates the need for the pointer, but that has, imo, some serious costs:
- you can't remove items from the list (or reorder them) without renaming cards
- a given item can't be on two different lists
- you have to be careful to avoid accidentally adding items to the list by using an applicable name.
~~~~~~~~
There may be other approaches, but to me it seems like the pointer (Sol II) is so far the clearest data approach here.
+example
(Gerry wants) to create cards like +buy, or +give, or +pay, so that (could be two records, the form and context will link a Company and Customer (Purchaser), and TheCompany+*orders and TheCustomer+*purchases each get a form of the PurchaseOrder entered.
Finally thinking about alternative currencies again, and what I need to do them in wagn (decko). I think some form of wagneerable event customizations will be the best way, and am wondering what your thoughts are on the matter.
I guess we've crossed the "code in cards" line already with machine cards (JS and CSS), and if JS cards are compromised the system is pretty much open to hacks already. Maybe this is just a matter of generally limiting it to Admin, and more of a concern for accidental damage or disabling of the site. Fail-safes should be all we need for the most part.
Can you articulate the concrete example that got you here?
The best way to describe this is analogous to the way collection URLs work. I tried to explain myself in the examples. I want to be able to click on something I can put in a page or on a menu choice, that when I click on it, it is much like a new card page (or in a slot). When I click submit, normally it would save the contents and the name used to trigger the new form becomes "real", so the next user could not use it to create another new item in the collection.
Potentially, a more advanced autoname could do the job. My ultimate use cases the form would gather the details of a currency transaction, the other party (the Left of the virtual card would be one party (i.e. PartyA+buy on a +buy rule)), the currency, the amount, what it is for would all be +cards of a form. A simpler use would be the typical gallery use case. Say I want users to be able to have a photo gallery, so Gerry+photos would show all the photos. If I put {{+new_photo}} in the page (say the User type template), and I click on that to upload an image to Gerry+photos+ , and photos+*right+*structure just displays all it's children.
I could see +photos being a Pointer card and having the feature be about adding new items to the Pointer card that is simplified. That still leaves the issue of an improved autoname because we sometimes don't want to name each item of a collection.
ok, I think I get what you're going for. I want something like this, too. We should rename this (has nothing to do with forms, and wagn will never have custom actions), and restate the issue (which is an exploration of one possible solution, though I think we can do better), and delete the current example (all rabbit holes).
But the gallery example is a good one.
I wrote some stuff up. Please see if what is there in the issue section gets to the heart of what you really want to achieve. If so, please change the name to something like "support easy-to-manage patterned contextual lists"
Also please look at the solution section and weigh in on the data ideas.
I think maybe this data approach will be a good practice. Afaic, all the talk of rules and virtual cards and events was pretty useless. But I'm curious to hear more about +pay, +buy, +give, etc. If you can say (without mentioning rules or mods or DSL or anything) what kinds of cards you want to get created and what you want users to experience, then we can bat different solutions back and forth.
Please have a look at the commenting overhaul blueprint. I tried to make it much clearer, and I think you'll see how it relates.
A statement like "we will never have custom actions" needs some clarification. Are you saying it is inconceivable that we might want wagneerable events? We already do similar stuff in standard modules, what is the distinction you are making that constitutes "custom actions" It is on you to articulate the design principles that are involved and what we want the rules to be.
My frustration is that you respond to these inquiries with more or less "why would you want to do that" or even "you should never want to do that". Help me clarify my examples, don't tell me they are wrong and there is no reason to want such a feature.
I don't want to always have to fit a feature into existing wagn interactions, if this is really a platform, then a lot more UX experiences should be available. I don't want to have to explain to users that I can't give you what you want because it is hard/impossible to do with wagn.
Last comment was cross-posted with your additional comments. I'll see if that addresses my concerns. Feel free to clone this ticket into the one you want, but your suggested rename isn't the use case I'm really interested in (it's one, and having it might give another path to do what I want). I'll try not to use implementation concepts too early, but these are developer/wagneer use cases, so the problem appears in terms of trying to do something with existing features and figuring out what kind of feature will give the most power without making a mess of the design.
Don't you think we should give Wagneers both options? (solution I and II)
Given some user created types with *structure rules and replace File with those types, and you have most of my requirements. So, say we are doing +buy. Create a type Order and define it's interactions with cards and maybe mods too, and +buy could just do 'add order' to one of the parties, and the other side might be best handled by an event on the creation of the Order that processes it.
The need in that case would not be so much for custom actions(events) as for post processing to implement work flow and other processes. The currency model would be posting events/transactions and rules engines that are watching that flow of events and maintaining state, etc. This could event be external processes listening to the events (card history: acts, actions, changes) and maintaining a "game state". Using this history event flow would be great here, since we could then re-create the state by re-running the event streams from earlier or even initial states. The other thing I'll need to do is implement signature chains for a sequence of transactions to bind them logically into a whole. That will probably need some mod code, but conventional mods to implement some calculations over all the data for signatures and the like.
actions = create, read, update, delete. I just meant that we won't be adding any more; that's MVC, this is MoFoS. Of course we have custom events, but events are not actions. Sorry, I though that vocabulary was pretty well established. In general, a bit more precision with vocabulary would be a big help. In some of the copy I moved off, you said "rules are always simple cards, right". Simple cards are cards without plusses. Rules are never simple cards. It feels like that kind of thing is all over the place, and it makes these ideas difficult to decode.
But the bigger problem with these kinds of proposals is that we're throwing out dozens of half-baked ideas at once, and it's hard to get a foothold. Don't get me wrong, I love me some half-baked ideas. But let's pick one or two and bake them!!
Generally speaking, I think the progression goes like this:
1. data patterns. Does what you want to do fit an existing data pattern (that you can demonstrate with names, types, etc)? If no, let's figure that out first (that's where we are here). If yet, then maybe give a quick example and we're ready to talk about:
2. data transactions (events). Do we have a model for the events needed to happen here? This can include any rules that effect events (eg permissions or new ones), and can involve wagneering or not. If have the events we need, then we can talk:
3. views / ui / user experience.
I know that lot of ideas will start as UX, and we should definitely track these needs better than we do. But the point is that this one idea was driven by a new UX idea, but the solutions explored wandered all over the map without ever getting even a little bit clear on what we wanted the data to look like.
Re Wagneering, it's important to remember here that we're not just trying to create shortcuts for coders; we're trying to make this stuff accessible to folks who don't actually code. I have always been and will continue to be very picky about what gets included as standard wagneering practice, and one of my top priorities for Decko 1.0 is making wagneering more discoverable. Any code that involves adding lots of new wagneering configuration options without a conception of how to make them discoverable is just not going to get merged in any time soon.
That said, we do already have wagneerable events (*on create, *on update, *on delete). It's possible that we will have more, though it would require finding a way to keep them very simple. The things I imagine using those events for are things like emailing (the only thing now supported), tweeting, and other external integrations. That's easy to understand. Doing things like altering events midstream is not something that I would expect to be on wagneers' minds. In general, I don't want Wagneers to have to dig too deeply into the concept of events, so I think we need to think of ways to empower them without burdening them.
Fwiw, I doubt you can honestly find many instances of where I ever actually said anything close to "you should never want to do that", but if I have, I apologize. On the other hand, I have DEFINITELY asked "why would you want to do that" and will ask that again and again. I'd be a shitty product manager if I didn't try to understand user stories, *especially* when it involves Wagneering.
If you re-read your own comments, do they make any sense to you?
Given some user created types with *structure rules and replace File with those types, and you have most of my requirements. So, say we are doing +buy. Create a type Order and define it's interactions with cards and maybe mods too, and +buy could just do 'add order' to one of the parties, and the other side might be best handled by an event on the creation of the Order that processes it.
I really can't piece that apart, but it looks like it's about events, and I don't think we're ready for that yet. I'm hoping we can put all that aside a bit until we get some more clarity on data issues.
Don't you think we should give Wagneers both options? (solution I and II)
OK, let's work on this framing a bit. Decko's main strategy for linking cards of two different types is the Pointer-Search solution. Something like this:
- A+B (Pointer)->C (POINTER SIDE), therefore
- C+D (Search)->(WQL) finds A. (SEARCH SIDE)
To use a better example, let's say we've got a simple system where:
- Renzo+employer=>CSU (pointer), and
- CSU+employees-> [ Renzo ] (search)
Wagneers (or "Cardists") do have both options, of course, in terms of data representation. What we are looking at here is whether it should be easy to add a list of things from both the perspective of Renzo (the pointer side) and CSU (the search side).
Before we get into the "manageability" (autonaming) aspect of things, let's take stock of where we are. In general, it's quite possible to add and edit items in place on the pointer side. It wouldn't be hard for Renzo to add a new employer without leaving the page (assuming you know your way around wagn). On the Search side, we could use a bunch of tricks (like special links), and even then we can't really edit an item in place. We couldn't really make it so that we add a new employee to CSU without linking to a new page, and even then we'd really need to make sure that Renzo included the +employer card in its structure for the whole thing to work.
Over the years there's been a chunk of discussion about "bidirectionality", the basic idea of which is to make it so that interacting with Searches and Pointers has smaller seams. In this case, you might be able to interact with CSU+employees and have an experience that feels a lot like interacting with a Pointer. How would that work? I'll try to dig a bit further into that question on the support bidirectionality ticket. The key point, though, is that there is no extra data representation required there, it's all about events and interface.
ALL of this context is just to say that supporting sol 1 and sol 2 is really about extending bidirectionality ideas to the manageability/autonaming realm. This ticket (in its current form) is really about autonaming list items (might be a simpler name, now that I think about it), and for bidirectionality to apply here, then yes, we need to support both solutions.
That said, the Pointer functionality is much closer to what we already want, so it's probably the easier starting place.
Another related ticket: quick upload interface for multiple files or images
(I moved out lots of the old content. A lot of it is about 6 years old and refers to rforms and such!)
You got me on 'rules', I meant 'Setting' cards, rule is Set+Setting and always a non-simple. I'll be better about action vs. event. My solution was to be able to do some "redirecting" of data before the store actually happens. All the current *on X are after the create/save takes place. What you might want to do here could be a bit wonky, hence the idea of a DSL.
A agree with the ideas about discoverability, but this is at the level of link syntax, WQL, stylesheet, etc., already well beyond most wagneers. We both want more UI wrapped around all of those features and this is no different (if we find something we want/need to do here).
Cool. Well, let's start breaking more of this out. It seems like for the high level case of currencies, we need a blueprint. There are just so many new ideas involved.
The DSL is a separate idea (if not a blueprint itself). one that has the feeling of something that I'm going to resist for a long time but will eventually make its way in and be awesome. The awesomeness will owe some debt of gratitude to the doubters who pushed for better and better design, but a much stronger debt of gratitude to those that insisted upon it :)
support bidirectionality is already an idea; I tried to make some progress on it.
And I think there are some other ideas involving structures and such that I don't get yet. I think the +*new thing connects to a bunch of stuff I've wanted, but it was only kind of mentioned in passing.
Still, I really do think we should bang on the +solution section above, especially on the autonaming aspects. Autonaming kind of sucks right now, and it feels to me like the first step in so many of these ideas (file uploads, galleries, comments, transactions, etc) is making autonaming better. I mean, really, we still have to do File-00001 because File-2 would come after File-10 alphabetically. So we randomly pick X digits? That's kind of pathetic, no?
And what of comments. In that case, relative naming would kind of seem to make sense, because a comment typically only makes sense in context. Whereas a photo in a gallery will often make sense in many other contexts.
If we got to awesomeness in autonaming and bidirectionality, I think we'd be moving a lot of higher-level blueprints into range.
All I was trying to say in that quoted paragraph is that a lot of what I want is solved by the "add a new one to the list" pattern as in a gallery. Just replace File in your example with MyType and if MyType has a *structure rule, click 'add', get a form, submit to create.
So, lets say for +buy, what I'm really saying and maybe I don't care about +buy, but 'add to +orders', or whatever the collection name is. Buy could be the label on the link. The action is new(+collection) and isn't 'new' at all in the CRUD action sense, we would build it on those actions.
So, one more stab at explaining my solution of doing something before creation. The action is still Create, but if we change the data, we can generate names to re-route the data, or even clone data so that more cards with different names are generated from the original parameters. I can see the limitations of this idea, so maybe that idea can be left to die.
btw, did you resonate with the "progression" suggestion above?
I like how you split up the main issue in that comment a few above. I'm going to jump over to bidirectionality next. Yes, Pointer is the main way we do linking, but we also can 'contain' objects to link them. The children of a card are linked to it, but by namespace, so the children don't have names independent of the parent.
I don't think the *structure rule is really related, right? We just want the new card interface regardless, no?
Sorry to harp on the vocab, but I don't know what "action" is in the non-CRUD sense; you haven't defined it. And are you using "contain" to mean "have as a child?". Boy, that's confusing new terminology. And we've gone through a lot of effort to define "namespace", but you're using namespace to mean something different from what we defined. And using "link" to mean "relate" is confusing (link is a specific type of content reference, so it's confusing to use it in its general sense). I still think I roughly understand what you're going for, but it feels like for every seconds worth of writing you do it takes 10 seconds worth of decoding time. I'm sure it's frustrating for you, too, but really, I just feel drained after reading this stuff. It's all the worse that I suspect your thoughts are generally good, they're just cloaked in a haze of mistranslations. It's like reading Don Quixote translated by Cheech Marin. (OK, it's not like that. I'm trying too hard.)
I've always assumed that we'll need to get much better at what you're calling "rerouting". That kind of stuff is step #2 in the "progression" as outlined above. I still want to get clearer on the inputs and outputs first, though. Naming (and autonaming especially) seems like it still needs a lot of attention.
In the solution section above I tried to tackle why I thought using naming as another solution (solution 3?) was a bad idea. See "serious costs". Imo, we want the
Not to the general case, but to my use case. It is what gives the form behavior, but you are correct to say it is general. Even with a photo-gallery, if you want to caption them or something, you'll create a user type with a *structure rule to encapsulate the caption and image file, but even if it is a regular type with no template, just a *default (or not). The UX isn't a nice multi-edit form, if there are inclusions saved from the *default, then you have to click-to-add each one. The process of adding one to a collection is the same.
Sorry, bad language usage again. I just meant, it isn't adding anything new to CRUD to do this. It's just that the apparent target of the create is different than the actual target. Still a create action with magic added to the target selection process.
Anyway, I didn't want to get bogged down it that since we probably don't need it (yet).
I have to see again if I follow what you are referring to as the "progression".
Sorry about the imprecision about linking, relating, namespacing. The main point is that these are similar to design decisions faced in any ORM situation. The difference between [[Some other card]] and {{Another card}} vs. [[+a tag]] and {{+another tag}} are subtly related to the design space we are exploring. The + relative inclusion is where the 'containment' is happening, the inclusion mechanism tends towards this (being descriptive here with container, analogous to attributes in the model (i.e. scalars with a value column, not a pointer via keys)), but because cards nest this containment, it is more powerful that in typical ORMs.. Our mode of linking isn't really like associations because we have lists of name pointers, not local and foreign keys
Ok, yes on the progression, and I agree that what I was trying to describe (badly) was at the # 2 level. Part of that is autonaming, and the other part is probably at least potentially external (runs on event listeners to the history API). Looking at the settings for *on create, etc. now I'm not sure what we can put there? Seems like they are 'any card', but I don't remember how that was supposed to work. ... To the docs.
What are you thinking for a new autoname rule? Remind me about how the controller level works, C vs. U is decided there based on whether the name exists or not? Seems like I might want to Create on a name, and whether it exists or not, I use an autoname process to make it unique and therefore new. So, +buy could have an autoname rule that Creates on +orders according to one of the patterns in your solutions.
To clarify the ORM analogy a little more. A Pointer +card is really like belong_to_many, because the base card is pointing to the other card(s). It's always to_many because Pointers can't be restricted to only one (we could add this sort of restriction as an option, but it hasn't been critical). Setting up the opposite search is like the has_many side. In ORMs, this situation is only supportable with a supplemental table, which makes it more symmetric (has_and_belongs_to_many on boths sides via the join table).
right. effectively our references table is that join table :)
Yeah, that's part of it. The real difference is that AR, being DBM based doesn't support an array of anything in one record. In DBM terms, it isn't a normalized relation anymore.
You bring up an interesting representational point. Except for the ordering, we could reconstruct a Pointer card content from the references table.
I've wanted to add an seq there. Not sure yet whether that means we store multiple references when content references the same card twice...
+discussed in support tickets
+relevant user stories