Extensions as Cardtypes

Idea

 

In Wagn 2.0, we want to move most of the extensions into the cards instead of having all the extensions defined at the ActiveRecord level.  Conceptually, the record that was represented by an ActiveRecord type model will now need to be represented by a Cardtype.  See Card Contents in *structure Rules for a related idea.

 

Keep these ideas distinct:

 

  1. The Cardtype extension.  Each card will not necessarily have cardtype card directly associated with it because we can use patterns without referencing cardtype as an attribute or plus card to each card.  Patterns can be used to implement cardtype as an extension, and we will for continuity.
    As I see it, this one would probably come last.  -efm
    I'm fine with you ordering your priorities as you see fit.  It just looks to me like this extension doesn't do that much except map the cardtype to codename/supporting classes.  You might just move the codename into the card record.  Either way the important part is to keep the idea distinct from the rest.
    Oh, getting rid of the cardtype extension should be easy-- you're right -- and I think it should happen very soon.  But you're talking about representing types via patterns -- that's a lot harder.
    Sorry, I should be more clear.  If you made the extension go away, would you make it <card>+*type, or what?  You might turn it into a pointer card or just leave it in the card record and just pretend like it is a pointer card attached.  Initially, all cards have to have one, but that would be relaxed as patterns can specify the type.  Is that more or less how you are thinking?
  2. Card classes.  We need to find an underlying class from name and type args, or similar, but there is no need for a 1-1 cardtype to card-class relationship.  Many cardtypes can share a class, or subclass and extend the same basic card class, and as in 1. the card may not have a cardtype, but it has to be mapped to a card class or fall back to a default class (Basic).
    These are just "patterns", right? 
    Right, this mapping would be defined by pattern based hooks.
    Are you using "card classes" to be something beyond just patterns?  Are these patterns that have associated code?
    Initially this might really just be one ruby class with overloads based on the initial cardtype set (i.e. current Wagn cardtypes plus a few new ones like patterns), but in principle I want to be able to have different card types have that are dependent on a loaded class module.  Patterns would be used to access card class based on the inputs, name, type, etc. (what is handled in with_class_from_args now).
  3. Rendering, validation and view options can be modified by extending these card classes with pattern declarations that just customize the base and extended card classes internally.  In other words, modules can add new syntax/semantics to the DSLs referenced in pattern card definitions.  This sort of syntax can provide standard ways to declare new options for these phases of card processing.
    What do you mean by pattern card definitions?
    This is the out of band card stuff that defines the WADL relationships.  What I'm trying to say is that if you had a new card content handler, loading that module might add methods that extend the WADL definition DSLs thus adding whole new features or classes of content with very different view/render options (for example, multi-media content that you can "play, rewind, play from <time>" or other presentation actions).
  4. Content-type.  A cardtype module can support any content coding it wants.  If the cardtype supports standard linking and transcusions, it needs to do that through the card api, and it needs to render in the client context for trascluded card.  The module needs to parse out the link and transclusion coding (i.e. what's inside the double [] and {} coding) and process them in standard way, but how it parses it out and the rendering actions, etc. are all defined in the module or the base it derives from.  That way you could code a relative trasclusion in XML contend like this: <org> ... <transclude>+search card|item:closed</transclude>, or put it in attributes, or similarly as Json.

 

 

 

I don't get it.  The name is "Extensions as Cardtypes", but I think from the content you're talking about "cardtypes as extensions".  If it's the former, if it's in a card, how is it an extension?  If the latter, then I would expect we'll get rid of extensions long before we get rid of cardtypes.  There's much more code commitment to every-card-has-a-type (and we've got a long way to go before we commit to getting rid of types).

 

I don't know how to press this upon you, Gerry, but I'm hearing lots and lots of proposals for major architectural overhauls without any depth of explanation of the benefit.  When I started trying to sell Lew and John on pattern cards, I went into lots and lots of use cases to explain why we'd make a major time investment like that.  It seems like you're casually throwing out ideas that could entail hundreds of hours of work without letting us know what we'd all gain from it all.


Part of this is trying to get my head around what is possible from this refactoring. The more we understand the longer term parts of the roadmap, the better we can be at getting all the parts in the optimum places.

 

I'm not as much trying to say: do all this stuff for 2.0, as to say: if you take this into account in the design phase we can get a better result. I know it isn't always completely clear from my examples what I have in mind and why I think it is critical, and I am working on that. So please keep pushing back until either it makes sense to you, or I realize I don't have a coherent proposal.

 

Let me try to explain what I mean better because this is more of a conceptual thing than anything else. What I noticed is that you have a parallel facility where you can put custom stuff in a card extension which is logically appended to the card contents and managed by the extension class, or you can add stuff to the card as contents and plus cards. Now, when you have a hard +*tform, the actual card contents is unused, so when we have patterns I expect to be able to access that data space (card.content) under the control of templates. The basics of this can be implemented in the current version by just adding a way to reference the base content from a hard template. The more general handling of this would give access to parts of the content though other languages (e.g. xslt, xpath for XML content), but the point is that none of this goes in the core, I just want the hooks to be there so anyone can add it if it scratches an itch rather than waiting for something to make it onto your roadmap.

  --Gerry Gleason.....Tue Oct 27 12:07:05 -0700 2009


I really think this was better as an early blueprint that may get changed a lot. The four points are really more about an implementation than as proposals at the level of user/wagneer visible structures. I think you are right that this is more "Cardtypes as Extensions", but I think I went the other way because I think in principle it should be possible to eventually get rid of extensions as they now exist and move all of that to pattern based mapping to cardtype handlers.

 

The idea of this is to be incremental, so you can move some functions (permissions for example) from extensions to card/pattern based stuff, and have partial cases as well as some parts are moved to cards while other stuff remains in extensions for a number of reasons. In principle it could all move, and on the model level I think we should move as much as we can possibly move, and have as few exceptions as possible to "everything is a card". In the implementation you can cross those lines for implementation reasons, e.g. performance, but I'm pushing to have a clean and generative model that enable powerful modular extension and the possibility of rich development communities.

 

On the "Cardtypes going away", that isn't really a proposal for what should be done, but a prediction based on what I'm seeing. From an efficiency standpoint, the "Cardtype" extension may never go away, like you said it is all over the code now as well. What I'm suggesting is that new possibilities for determining a card's type will be much greater, and it isn't clear that you always have a card.cardtype which is another specific card. The cardtype may now be constituted by a whole lot of pattern based features, and we will have new concepts and cardtypes involved in these processes.

 

One final note on the "content-type" parts. Again, I'm not saying you need to implement all sorts of new stuff on this, Wagn as is really has variations on one core wiki-like data type, and it probably should stay that way. I just want the hooks to be there to put in any crazy thing I might want.

 

Keeping the distinctions I list will be the key to this. I don't think any of this adds much code to what you need to create for the Wagn 2.0 roadmap, but it does require thinking about some of these issues and discussing them until we all agree we have a good solution.

  --Gerry Gleason.....Tue Oct 27 12:27:58 -0700 2009


Extensionlessness:

Yes, we need somewhere to store data currently stored in extensions. One key element, the codename, I would lean towards storing separately in the database (as a field in the cards table) because of the high need for fast access by code and the low need of end user interface.

 

That change would, in itself eliminate the need for Cardtype extensions, which are really only there for the codename (classname). (You said "the "Cardtype" extension may never go away, like you said". No, I definitely think it will go away!!!)

 

Similarly, Role extensions really only handle codenames, too. However, their ids are also used in the roles_users table, which is where user roles are tracked. We could just use card_ids and be done with the role extension, too. that may be a suitable first step, but ultimately I'd rather track the role assignment in cards as well. For now I'll leave that out of the extensionlessness conversation.

 

The only other true extension (I don't include HardTemplate or SoftTemplate, as both are obviated by our intended pattern card handling of formatting) is users (accounts), which are easily the trickiest extension. name, crypted password, salt, blocked, status, and invite sender all need to be handled as plus cards. "login" has essentially been co-opted to function as a "codename".

 

I like doing this as plus cards, as that mirrors how we do other things and keeps everything accessible to wql. I don't really like using the base content, because that eliminates the possibiliy of softforming cardtypes.

  --Ethan McCutchen.....Wed Oct 28 20:01:14 -0700 2009


I think I'm coming around to your content-type idea. It's a code-level distinction, not a user distinction (we used to make users make that choice -- uggggly).

  --Ethan McCutchen.....Wed Oct 28 20:02:07 -0700 2009


You said "What I'm suggesting is that new possibilities for determining a card's type will be much greater, and it isn't clear that you always have a card.cardtype which is another specific card. The cardtype may now be constituted by a whole lot of pattern based features, and we will have new concepts and cardtypes involved in these processes."

 

I don't get what you're going for there. Examples?

  --Ethan McCutchen.....Wed Oct 28 20:03:46 -0700 2009


New possibilities for cardtype. Keeping in mind that this is just an example and we probably wouldn't do this specifically, but something like it, or maybe we would I thought of a better example:

  • The way tags are used with +*rform to set the type with a soft form, but instead you want to enforce that +typed_tag is always a specific type. You could move that value to  <card>+*cardtype, but you could also just get the type from the patterns. Now  <card>+type_tag has a type from the patterns for "typed_tag", and the plus card, <card>+typed_tag wouldn't have one, or it would be "virtual". I'm also imagining that because patterns give us a lot of flexibility in doing other things like +*rform, this would not be unique.
  • Say we want to put DSL sfuff all in standard places so it doesn't pollute the top level namespace, and all System+cardtype+<name> cards are to be "Cardtype" cards, or maybe more of a "Cardclass" that may contain several cardtype depending on other pattern based settings.  Even if you wouldn't want this for your own reasons, this might be a power you want to give to the designer to choose in building Wagn like apps.

The important thing to get your head around is that stuff that had to be bound to a card before, might be bound to the pattern cards it matches instead.  Implementation-wise you can cache any of this data on the card if you want, but logically it would not be there.  Cardtype per card would be an implementation only thing or if present it may be virtual internally.

  --Gerry Gleason.....Thu Oct 29 03:34:55 -0700 2009


I think I agree on the "codename" comments, but I will know only when I understand it better. If the purpose is to locate the class to be used for cards of that subtype, then I'm with you completely. Not user visible, but maybe DSL visible in configuring the WADL environment. Every codename has to have a content-type, but many codenames might have the same content-type.

 

This part is very speculative, but we may want to have some idea of classes and sub-classes, but I'm not sure if it attaches to one or more of these concepts. I think we want this very simplified and the implementation level, just what is needed to find the right modules to process a given pattern hook. The complexity can all go into the pattern system. That is any class hierarchy and how the specific class and type are chosen is all coded at the WADL (accessible to advanced wagneering). You may need to provide some specific hooks at the card module level to support the features, but no changes in the core models.

  --Gerry Gleason.....Thu Oct 29 03:51:13 -0700 2009


On the Extensionlessness concept, I'm imagining that the support for different codenames is part of the "card module interface" design. That is, moving the handling of codename to the "card module layer". You would have some core modules for the extension types that have been moved into cards, and those modules could use extension tables too, but the core doesn't need to know about it.

 

You would probably have the "Card::Basic" type behind several "extension card types" that subclass basic the same way current codename based classes do. We have already well discussed the ins and outs of packaging this core cardtype module, so I won't add anything here about that.

  --Gerry Gleason.....Thu Oct 29 03:58:29 -0700 2009


I would like to see more discussion on how you plan on doing Roles and permissions. It seems to me that the pattern idea is an opportunity to totally change the semantics of this part. In other words, we don't have a lot of features in this area yet, so nothing is defined yet.

 

I'm thinking that an Apache like allow/deny semantics and an ordering paradigm for the related pattern cards that provide places where permissions setting might be. What are the "places" you have already identified for this?

 

Is this stuff already designed? If so, where is it? If not, where should it go?

  --Gerry Gleason.....Thu Oct 29 04:24:31 -0700 2009


I definitely get the concept that code is to be associated with patterns, not cards (or, specifically, cardtypes). That's a big part of the point. I also see potential benefits to changing to representing type in a card, but not huge, immediate ones that would justify that kind of overhaul.  Caching notwithstanding, you're adding a lot of database calls and a lot of complexity, at least so long as this is all built on a relational database.  Given the fact that all the code that was once type driven is now going to be pattern driven, the door will be left open to make that kind of a change at any time.

 

I keep pushing back against calling System+cardtype+X a namespace. It's not a separate namespace. It's part of the same one. That X is tied to the simple "X" card. It really pollutes the semantics to call this a namespace. If you want it to function as a namespace, you have to handle plus cards in a very different way. If that's what you have in mind, can we move that somewhere else?

 

So long as the codename determines which card represents a type, you can give it any name you want, plus card or whatever.  I don't see why you would need to change the type representation to have this capacity.  already, the type field in the cards table refers to the classname (ie codenam), not the cardtype.  You can change the "User" card to be "Person" or "System+yomama+Person" and it will all work the same.

 

HOWEVER, there is one major disadvantage to making these cards plus cards: it means you can no longer use them as tags.  I can have Grass Commons+Person, but I can't have Grass Commons+ ( System+yomama+Person ).   If I just do those four cards (no parentheses), then the tag is just "Person".  As pattern cards grow to govern more and more, perhaps even that rule set will be configurable.  But until that day, System+cardtype+X is a pretty lame use case that would need more proof.  "Somebody might for some unknown reason want to do something like that" is not a user story that I'm going to devote a lot of energy to supporting.

 

  --Ethan McCutchen.....Thu Oct 29 12:30:44 -0700 2009


The patterning permissions stuff in on Pattern Cards+permissions.

  --Ethan McCutchen.....Thu Oct 29 12:31:36 -0700 2009


I think I'm mostly with you on the card module interface issue around codenames, though initially they'll be spread a little scattershot in the code, as references to star cards, card types, roles, users, and such are now. I think the implementation of codenames (and getting rid of extensions) will be the first step, and reorganizing the code to pull date from "code cards" in organized ways should be treated as two separate stages. No need to conflate them.

 

In general, I advocate getting the data in order first.

  --Ethan McCutchen.....Thu Oct 29 12:48:28 -0700 2009


Still have no idea what you mean when you use "WADL." Maybe you could write some pseudocode? It sounds to me like you're talking about creating a logical language for Wagneers. Since we're so syntax-averse, it's going to take a lot of convincing and a lot of design to move that concept through. But I think it makes sense to start getting clearer on what kinds of things we might want it to accomplish.

 

You said of codenames: "If the purpose is to locate the class to be used for cards of that subtype, then I'm with you completely". The purpose is more general.

 

Right now the code refers to lots of cardnames directly. Eg. *options, *tform, etc. Others it refers to by codenames stored in extensions (Roles, Cardtypes, and certain built-in) Users. I don't think it should *ever* refer directly to a cardname. You should be able to change any cardname you want.

 

Your interpretation was only about cardtypes. And, with our current representation, yes, it would tell us the ruby subtype. As we move to a pattern representation, that particular meaning won't be necessary, but we will refer to patterns using codenames, not cardnames.

  --Ethan McCutchen.....Thu Oct 29 13:01:55 -0700 2009


I see your point about the plus card semantics. The System+* example probably confused what I was trying to get at.

 

I think I'm finally getting the "codename" concept. That isn't the cardname, but it corresponds to it, right?

 

I think it is related to my thoughts about all this. Internally card.codename gives a classname no matter where or even if there is a "cardtype" card anywhere. This is completely independent of how the actual Cardtype card (the "User" card for example) is used. The sorts of things I would put in the System+something cards would not be like that, more like configuration stuff related to "codename" (cardclass might be a better name for it) that I don't want the user/wagneer to know about or depend on.

 

The use as a tag would reference the card named for that tag, but I'm thinking about other stuff that might be more internal. Configuration stuff that says: don't use clean_html, or use this version of the footype card module for it. A place for "out of band data". Maybe there isn't anything in this category.

 

It any case, I think we can leave this topic be for now. We have a good enough understanding for the near term needs.

  --Gerry Gleason.....Thu Oct 29 14:02:33 -0700 2009


I'm trying to use WADL more like you are now and say DSL when I mean some coding about card relationships that may or may not be in cards. I think I was referring to any new +*xxx or whatever type conventions that are implemented with pattern cards. You said when you add stuff like this you don't want to change it. With permissions in extensions now, you have to define how it becomes card visible and that definition I would call a WADL standard.

 

Does this match your use?

  --Gerry Gleason.....Thu Oct 29 14:06:19 -0700 2009


Agreed on "data order first". The other is more like a direction of migration. We know that is the direction we are going so as the refactoring proceeds the code will migrate in that direction so that by the time it comes to that point it may be just a little cutting and pasting to finish the jobs.

  --Gerry Gleason.....Thu Oct 29 14:09:48 -0700 2009


hmm, not sure you get codenames yet. No two cards could have the same codename. why would we call it cardclass? It *can* be used as a class in the case of cardtypes, but it's got a more general use: connecting the card to code. it's about identifying certain individual cards to code, and in most cases (like *options, say), there's no ruby class involved.

 

I don't see any problem with having out-of-band data in cards. In fact I really like that. But let's say I've got these cards: "Gerry", "*dont_clean_html", and "Gerry+*dont_clean_html". The "Gerry" card probably got created on the fly and doesn't need to be referred to individually on the fly. But *dont_clean_html is something that has meaning to the code. It has to have a codename (now *this* is a separate namespace). so it could be the same name ("dont_clean_html") or different ("no html") or for that matter completely arbitrary ("Asdkfj298fS"). But here's the point: "Gerry+*dont_clean_html" does not need a codename. There is nothing in the code that refers to that card, only to its tag, which already has a codename.

 

Ummmm, this is a crappy example, because it's not how we would do that -- it would be attached to a pattern card like "User+*type cards+*dont clean html" or something.  But perhaps you get the point?

 

  --Ethan McCutchen.....Thu Oct 29 14:21:53 -0700 2009


Ahhh, finally getting how you're using WADL.

 

I had stopped using it. Originally I had only meant the expression (pointer, search, combo, whatever) that defines the cards that are a component of an wagn application. It defines a Hand -- all wagn applications are hands, but not all hands are applications. "My love letters to Erika" might be a hand, for example.

 

I think you're saying that the cards themselves (not just the list of names, as in my case) are part of WADL. Any card that governs structure and or functionality would be a WADL card. OK, I can go with that. :)

  --Ethan McCutchen.....Thu Oct 29 14:26:44 -0700 2009


we will refer to patterns using codenames, not cardnames.

 

I think I need a little clarification on this part. In the current code that are the same, right? Or almost the same. Are you just saying that any use of cardtype information in patterns will use the codename, and not a cardname? That makes complete sense if that is all you mean here.

 

I should have said that in Patterns we will refer to cards using codenames, not cardnames.  They are often the same, yes, but it's vital that they don't have to be, so that you can change the cardname without breaking the code.  But yes, that's basically all I'm saying, except that codenames apply to lots of non-cardtype cards.

 

  --Gerry Gleason.....Thu Oct 29 14:27:37 -0700 2009


Re your "migration" comment, I complete agree. Even though I got confused at first since migration implies data migration to me. But yes, you're arguing for a general course for our refactorings. I think I'm on board.

  --Ethan McCutchen.....Thu Oct 29 14:28:38 -0700 2009


(see boldfaced inline comment above. sigh. this is a job for wave.)

  --Ethan McCutchen.....Thu Oct 29 14:35:38 -0700 2009


On WADL, I was thinking more of the linking pats of the cardname structure. When you include Topic+*tform and Topic is a cardtype card, that relationship is part of the WADL spec. Card names and contents are code here. Some of it is just content with the code, but there are implied structural relationships.

 

We are going to where these bindings could be largely in cards too, so I would want to make a clear distinction about cards that might impact semantics. It could change WADL coding relationships. Just changing *rform to *TagTemplate would change WADL, but this is a relatively simple change. Other modifications would take us to Non Standard Wagn spaces. We might want to define these cards as "WADL definition cards" to keep this distinction clear. Probably you want a stronger permission than Admin, maybe Root or System.

  --Gerry Gleason.....Thu Oct 29 14:43:19 -0700 2009


You should probably get back to your real work. Thanks for all this, I think we are converging.

  --Gerry Gleason.....Thu Oct 29 14:46:40 -0700 2009


So that's why it sometime increments the codename. If it has a cardtype that doesn't have a card, that codename is already "taken". If I try to create the Cardtype card for an existing codename, it gives it a new codename so it doesn't collide. This makes it pretty hard to add types. I think it should connect the cardtype and the cardclass codename when you create the cardtype.

  --Gerry Gleason.....Thu Oct 29 14:49:56 -0700 2009


in general, we have almost never had code laying waiting for a cardtype to be created and connected to it. Ruby and Script cards are the exception, and that's why you ran into the issue. It's going to be much more common with modules, and I think the keys are going to be: (a) codenames in db's, and (b) db names in code.

 

To me, it makes sense to have the codename appear once in the db and the db once in the code. That way if there is a name conflict, they both need only be changed in one spot each. Currently, cardtype class_name is used in every row of the cards table, which I don't personally like very much, though it does make some things faster.

  --Ethan McCutchen.....Fri Nov 06 10:45:13 -0800 2009


I ran into it because I was adding cardtypes, and didn't understand the process. I have to add the cardtype to the db before I add the new cardtype classes or it create this same situation. Cards like XML and css are not there already, so I have to remove the new code, start the server and add some cardtypes, then add the code back ...

  --Gerry Gleason.....Fri Nov 06 12:02:34 -0800 2009


Interesting to look back on this discussion after 1.5.2 is done with all the slot refactoring and with 'codename' waiting in the wings where much of this is beginning to be addressed. The work we are now doing to use Sets with views and actions/controller rules is also clearly related. I think maybe we need to move this, though. Clearly this was all critical to getting on track with such deep refactoring.

  --Gerry Gleason.....Wed Feb 02 05:42:59 -0800 2011


I'm going to close this, not because every idea here was necessarily fully addressed, but because we've evolved a LONG way since here and knocked out a ton of these. obviously still mine-able, but any vital ideas should be resurrected in a new Idea card.

  --Ethan McCutchen.....2013-02-25 05:27:55 +0000

+relevant user stories