Level-2 / Transphporm

Transformation Style Sheets - Revolutionising PHP templating
276 stars 27 forks source link

TSS Behavior Catalog #4

Closed smolinari closed 8 years ago

smolinari commented 9 years ago

This is a list of all the web application behaviors. which should/ could be or are covered by CDSs.

This list is not even close to finished. As we get documentation for each type of behavior, I'll link to them. I am not a designer, so any suggestions or additions to improve this list are very much welcome! As they come in, I'll add them.

Scott

TRPB commented 9 years ago

A quick question, what does the template system have to do with event firing/listening? Can you give an example of where this would be useful and a quick and dirty example of the API? (E.g. what kind of thing you'd expect to see in the .cds)

smolinari commented 9 years ago

Like I said, I am no designer, but I'll give this a try.

Say there is a standard JS function that determines if all required fields in a form are filled out properly. The designer only knows the function is called validate. He also knows, the form elements, the fields, would need to trigger the function and can do this through the CDS. Maybe it could look like this?

 .first-name {input: text; placeholder: i18n(first_name); trigger: validate; required}
 .last-name {input: text; placeholder: i18n(last_name); trigger: validate; required}
 .date-of-birth {input: date; placeholder: i18n(date_of_birth); trigger: validate; required}
 .telephone {input: phone; placeholder: i18n(telephone); trigger: validate;}
 .remarks {input: textarea; cols: 40; rows: 10;}` 

This does quite a bit.

And the designer also wants the submit button to be disabled, until the fields are properly validated.

  .submit-button {form: button; validate: enabled}; 

Does that make any sense or is feasible at all?

Scott

.

TRPB commented 9 years ago

I'll have to admit I still don't fully understand the purpose of this. Since the template engine takes XML, Data and CDS and spits out some rendered HTML, it might be useful to show the 3 components (template, CDS as you have above, some sample data) and then the expected rendered HTML.

edit: I totally get localisation, but isn't that essentially just a data() lookup?

TRPB commented 9 years ago

However you did just make me think of something cool. Consider the simple task of re-populating form components based on $_POST...

$template = '<template>
            <form action="" method="post">
                <input type="hidden" name="user[id]" />
                <input type="text" name="user[name]" />
                <input type="text" name="user[email]" />
                <textarea name="user[address]"></textarea>
            </form>
        </template>';

$cds = 'form [name]:attr[value] {content: data(attr(name)); }

$data = $_POST;

Syntax could be improved but it might be a nice way of doing it :)

form [name] like CSS will select any element inside form that has a name attribute.

:attr[value] would select the value attribute (not element) on each matched element and content would set the attribute's value.

attr(name) would read the name attribute and data(user[name]) would function identically to how data(user.name) does at the moment. :)

smolinari commented 9 years ago

The system would also need to somehow have registered JS functionality in it too, so the designer can add any view behavior into the CDS too. I am even thinking the CDS system should also spit out React JSX or something along those lines. The rendered HTML would automatically entail the needed binding for the JSX. Without a JS integration like this, a CDS would only be a data binding system and nothing else. If that is all it should be, then forget my contemplation. :smile:

But then, the designer is back to the problem of having to hack in JS throughout the HTML/XML herself. Ok. A lot of designers understand and can program in JS too. Maybe the idea of having view behavior be controlled in the CDS isn't necessary or too much. I don't know. It just seems like a cool way to get more people into working with the web and splitting the responsibilities of design, UI behavior and data integration. If the JS functions are pre-built and in the back-ground (where they should be), then all a designer has to know is HTML, CSS and CDSs (and the available JS functions and return values (the API)). It is all declarative and relatively easier to learn. Much easier than learning JS.

Scott

smolinari commented 9 years ago

Oh, and you also need some form of JS anyway, for the client side CDS data binding and querying behavior to get data from the server. Might as well build CDSs out to be extensible to any type of JS behavior.

Scott

TRPB commented 9 years ago

I'm happy to have the system integrate with JS, I'm just failing to see the use-case at the moment.

In your example you have this:

.first-name {input: text; placeholder: i18n(first_name); trigger: validate; required}

What exactly would specifying input: text do? Presumably it would just add some validation to the input? Would it add an automatic blur event, for example?

Wouldn't this be better off being described in a single, reusable cds file?

[data-validate="text"]:attr[onblur] {content: "validateText(this);" }

Then in our template we put:

<input data-validate="text" />

And we can use the same cds file with each template? Possibly via @import

One of the problems this is instantly going to cause is a lack of portability between clientside and serverside. In my mind, you should be able to take a data structure, some XML and a .cds file and have it rendered identically via JS or PHP (or any other language that cares to implement it)

edit: and if you wanted to get clever, add the data-validate attribute inside the cds itself:

.first-name:attr[data-validate] {content: "text";}

edit2: If you don't like event attributes such as 'onblur=""' then we could even add:

input:event[blur] { content: "validateText(this);"; }

When the template is rendered on the server, it creates the "onblur=" attribute, when done using javascript it assigns it using addEventListener.

TRPB commented 9 years ago

How about just making the entire system extensible?

$cds = 'input[name="firstname"] {input: text}';

$template = new \CDS\Builder($template, $cds, $data);
$template->registerProperty('input', function($element, $value) {
    //$element is the matched element, this will be called once for each element
    //$value is the value supplied in the cds so in this example "text"
});

Then when it comes to javascript

A) It doesn't lock people into a specific validation library B) Anyone can add any property they want and do the same thing:


cds = 'input[name="email"] {input: email;}';

var template = new CDS_Builder(template, cds, data);
template.registerProperty('input', function(element, value) {
    $(element).blur(function() {
    if (value == 'email') {
        if (!element.value.match('///regex-for-email//')) {
            alert('Invalid email address');
        }
    }
});
});
smolinari commented 9 years ago

The input: text is only to determine the type of input field it should be, along with the necessary JS required. For instance, you don't have telephone or date (well, not in IE) input field types.

cds (let's go with ids)

   #first-name {input: text; placeholder: i18n(first_name); trigger: validate; required}

XML

 <dl>
     <dt> 
          <dd>      
              <label></label>
          </dd>     
          <dd>
              <input id="first-name">
          </dd>
     </dt>
  </dl>

And let's say the designer wants to have a hint popup in the field and asks the JS programmer to make him the hint. (or she can plug in a hint module),

cds

 #first-name-hint {hint: i18n(add_valid_first_name);} 

XML

 <dl>
     <dt> 
          <dd>      
              <label></label>
          </dd>     
          <dd>
              <input id="first-name">
              <span id="first-name-hint"></span>
          </dd>
     </dt>
  </dl>

So that is all the designer would need to do.

The output would be.

 <dl>
     <dt> 
          <dd>      
              <label>First Name</label>
          </dd>     
          <dd>
              <input type="text" id="first-name" value="Scott Molinari" name="first_name">
              <span id="first-name-hint" class="hint">Please add a valid first name!</span>
          </dd>
     </dt>
  </dl>

Scott

smolinari commented 9 years ago

How about just making the entire system extensible?

Absolutely! :+1:

Scott

TRPB commented 9 years ago

I've added a registerProperty method to enable this. Take a look at Builder.php

TRPB commented 9 years ago

I think that's the way forward. Provide some basic data manipulation tools (repeat, content, etc) and allow anything more than that to be either added on a per-application basis or as a separate project that extends the basic functionality of this one.

smolinari commented 9 years ago

Great. Anything to support extensibility is the way to go. CDSs must be completely self-definable. There should be only a basic set of rules and standard behaviors. Everything else is an extension.

One thing still open in my mind though....how can the sheets, or rather the declarations in them, cascade?

Scott

TRPB commented 9 years ago

The same way as CSS :) iteration() is available in all rules for child elements. On 3 Sep 2015 19:36, "Scott" notifications@github.com wrote:

Great. Anything to support extensibility is the way to go. CDSs must be completely self-definable. There should be only a basic set of rules and standard behaviors. Everything else is an extension.

One thing still open in my mind though....how can the sheets, or rather the declarations in them, cascade?

Scott

— Reply to this email directly or view it on GitHub.

smolinari commented 9 years ago

Can you give me a quick example please? Cause, I think this might be a point on where our perspectives are diverging or rather I am misunderstanding the purpose. Because, I am thinking of the ability to define the actual sources of data in CDSs, to be able to bind that data to the structure. So, if I would define a cds declaration to use a user object's fields, how could I use that same declaration for anything else?

Scott

TRPB commented 9 years ago

Take a look at testRepeatObjectChildNodes

The CDS is this:

 'ul li {repeat: data(list);}
        ul li h2 {content: iteration(id)}
        ul li span {content: iteration(name); }';

The applied iteration cascades down child elements, although not quite as cascading as css, I think it still fits.... I guess the name could be changed if it doesn't really fit :)

smolinari commented 9 years ago

How about Behavioral Data Sheets? :sweat_smile:

Scott

TRPB commented 9 years ago

For the project, I was thinking keeping in the theme of Vision and my other projects: Maphper, Aphplication a nice crossover might per Percephption although it's a bit of a mouthful :p I think you're right that we need a specific name for the file format, though.

edit: or how about Transphporm, might be a better description of what is actually happening.

smolinari commented 9 years ago

Yeah, that sounds good. I like the play on PHP.

Though, the template system needs a name. Transphporm is just the interpreter/ compiler of BDSs for the template system. :wink:

Scott

TRPB commented 9 years ago

The big question, really, is which properties should be inbuilt in the .bds format and which should be added via extensions? I think at minimum the ones I've already done (content, repeat and display) but possibly some others might be needed as well.

Javascript version: Tranjsform ;)

smolinari commented 9 years ago

Enough to get people to understand the possibilities and enough to allow people to use .bds files successfully. I think the data binding is the first challenge, since behavior can always still be done over JS (as usual). More behavioral aspects could be the "add-ons". Kind of like building a view framework, but with the template system and .bds files as part of it all.

I wanted to go into this a few posts ago, but I deleted it all for a shorter more pertinent answer. I'll say it now. CSS was made to separate content from design. A great concept. The thing is though, content isn't just content. CSS covers the design.

So, what is the content?

I'd say, content is structure, data(state) and behavior. Structure comes from the meta languages. Data/state is what PHP or any other back-end delivers. And behavior is what JS delivers. With .bds, we are separating data from the structure (and why it is so cool), also with (hopefully) the secondary ability to also split behavior from structure, when it deals with data/state. That is my birds-eye view of Transphporm.

Scott

TRPB commented 9 years ago

Data binding is pretty much done. I need to add a way of writing content to attributes and I've pretty much settled on

input.name:attr[value] {content: "whatever";}

Rather than

input.name: {attribute: value "whatever" }

As it's difficult to do concatenation with the latter, e.g.

input.name:attr[value] {content: "string1", data(something);}

although I'm open to suggestions.

smolinari commented 9 years ago

I am also uncertain. Can't it stay with key: value pairs through and through? That way the format is standard. So, like this?

input.name {attribute: value; content: "what ever";}

or

input.name {attribute: placeholder; content: "what ever";}

And how would Transphporm know where input.name is? Does the designer have to add the name attribute, for it to find it? And what if "name" is something coming from the data source? Or am I misunderstanding something again? I mean to me, it can't be properly dynamic, if any attribute in any tag, except for class or id attributes, are entered into the meta language.

That is why I had ended up with this.

#first-name {input: text; placeholder: i18n(first_name); trigger: validate; required}

ok. to stick with key value pairs, it would need to be this.

#first-name {input: text; placeholder: i18n(first_name); trigger: validate; required: true;}

LOL!

Scott

TRPB commented 9 years ago

Noooo input.name is just a CSS selector that matches an input element with the class "name" in order to set its attribute "value" to "whatever"

So from

After applying the BDS becomes

Sorry for formatting, I'm on my phone.

smolinari commented 9 years ago

Ah, Ok.

input.name {attribute: value; content: "Scott";}

Edit: Wait. Couldn't this work?

input.name {value; "Scott"}

Scott

smolinari commented 9 years ago

And this?

input.name {
       value: "Scott";
       readonly: true;
       disabled: false;
       maxlength: 25;
 }

Scott

TRPB commented 9 years ago

Only if we're not allowing custom attributes such as data-whatever. Otherwise, we'll have name clashes with other properties.

smolinari commented 9 years ago

Hmm.... I'm going to start from scratch and go with a full use case of what I am imagining. Let's say we want to have this table and the behavior.

https://jsfiddle.net/0u4yes58/15/

I know it is possible to do the alternating colors with CSS. It's just an example of behavior.

The BDS for this kind of table template might look like this.

#table.[name_list] {id: [name_list]; body.onload: alternate([name_list]); style: 100%;}
#table.[name_list] tr {repeat: [name_list.row_count];}
#table.[name_list] th {repeat: i18n([name_list.th])}
#table.[name_list] td {repeat: [name_list.td]}

Note: maybe we could also come up with a way to reduce the repeated "#table.[name_list]" selectors? It has to know the "th" and "td" selectors are also nested in the "tr"s.

and the template would look list this.

<!-- name_list table @client -->
<table>
  <tr>
    <th>Some Example Text</th>
    <th>Some Example Text</th>
  </tr>
  <tr>
    <td>Some Example Text</td>
    <td>Some Example Text</td>
  </tr>
</table>
<!-- /name_list table -->

So, what is happening in my mind with this?

  1. The first line is busy. It is saying, this declaration is for a table with the id "name_list. It is also saying the id should be inserted into the table tag with id: [name_list];.
  2. So, we have to build an array (or object) with the name and id of "name_list" from whatever object is being requested from the template at the time. In other words, the call might be for blogs or authors, but the list is reusable for both. (Note: The brackets "[]" are just delimiters for the array variables, as I didn't know what else to use.)
  3. We have a JS function called "alternate" and it is given the value of the id and it is triggered by "onLoad" through the body tag.
  4. We also have a function for internationalization (i.e. for translation) for the "th" text.
  5. In the object or array, we have properties or subarrays of "th" values for the table header and "td" values for the cell values.
  6. JS and Data functions available to DEFT ( I took the liberty of using the name I came up with earlier) are configured and known both to the system, the developers and designers, so DEFT and the devs and designers know how DEFT will compile all this.
  7. (Suggestion) The HTML comments in the template are for the designer and for compiling and decompiling templates from a single page design. The @client is just another idea and is intended to tell DEFT that the templating functionality should happen on the client side. We could have a @server too.
  8. It doesn't matter what the designer added to the template, this will be re-rendered properly through DEFT.

Is this too much or too wild? Does it make sense? I think it does. Imagine the ugly conditional code the template would need to have to make this happen, not to mention the complexity for resuability of the JS behavior. Such conditional template syntax makes the template mofugly and hard to read..... for everyone!

This concept makes the designers job so much more simpler and the possibilities are so cool. It also takes and puts the data and behavior outside of the structure and simplifies both. I think. And the idea is, all that extra work that is normally needed for designers is reduced down to DEFT and BDSs. It properly splits responsibilities. It's awesome! :+1:

Well, it can be.

Scott

smolinari commented 9 years ago

Man, my head is spinning. What about the issue of colspan and rowspan?

#table.[name_list] td { content: [name_list.sum]; colspan: [name_list.th.count];}

This would be added to the end of the above BDS and would tell DEFT to add the td to the end and span the whole number of available columns. Hmmm...

Scott

TRPB commented 9 years ago

Personally this is going well beyond the original goal, and in the wrong direction.

#table.[name_list] 
  1. . and [ are already CSS selectors. Although other selectors may be useful (although I don't really see why), I'd prefer to stick with pure CSS for element selection. Why reinvent the wheel? People already know CSS, let's use that
  2. You're back to having the author of the template writing display logic:
<!-- name_list table @client -->

They need to know the special syntax here and it's moving back towards having special markup in the template. Not only that, this can't be achieved with DOM manipulation and will rely on ugly/slow regex.

TRPB commented 9 years ago

And for comparison, here's how to do essentially what you want with the current implementation in this repo:

<table>
  <tr>
    <th>Some Example Text</th>
    <th>Some Example Text</th>
  </tr>
  <tr>
    <td>Some Example Text</td>
    <td>Some Example Text</td>
  </tr>
</table>

bds. Let's consider looping through users. We could add classes rather than targeting the element names here

table tr {repeat: data(users); }
table tr th:nth-child(1) {content: "Name";  }
table tr th:nth-child(2) {content: "Email";  }

table tr td:nth-child(1) { data: iteratation(name); }
table tr td:nth-child(2) { data: iteratation(email); }

/* The nth-child selector is implemented but the attribute property is not yet */
table tr td:nth-child(odd) {attribute: class odd}
table tr td:nth-child(even) {attribute: class even}
smolinari commented 9 years ago

About the template author worrying about display logic, isn't that is often the case? However, I was also contemplating whether or not the @server or @client declarations might be better off in the bds itself.

Scott

TRPB commented 9 years ago

I'll go back to saying: The same .bds, xml and data structure should be able to run and produce and identical result whether it's in PHP or javascript. @server and @client seem entirely redundant here.

TRPB commented 9 years ago

Going back to:

About the template author worrying about display logic, isn't that is often the case?

What I'm trying to avoid is mixing markup and processing instructions. Your comment there is entirely processing instructions.

smolinari commented 9 years ago

Yes, I am envisioning the use of processing instructions (behavior) being "coordinated" in the bds. The logic or the instructions themselves are in JS or Node or PHP or Java or .net. etc. Basically, what I am wanting is not only data binding, but also behavior binding. Without the behavior, we are back to CDSs. or DBSs. Data Binding Sheets. :smile:

On @server or @client being redundant, I thought about that some more and I understand what you mean. The decision for where BDSs need to be compiled or rather how, is a global one.

table tr {repeat: data(users); }
table tr th:nth-child(1) {content: "Name";  }
table tr th:nth-child(2) {content: "Email";  }

table tr td:nth-child(1) { data: iteratation(name); }
table tr td:nth-child(2) { data: iteratation(email); }

/* The nth-child selector is implemented but the attribute property is not yet */
table tr td:nth-child(odd) {attribute: class odd}
table tr td:nth-child(even) {attribute: class even}

This bds example is very specific and can only be used for a specific user list template with email and name fields. Couldn't it be possible to abstract the bds to be more common in someway? For instance, a list of data that should fit into a table with a varying number of fields and varying column titles, and varying values, etc. That was my intention with the [name_list] array or object.

I am coming from the idea that in the end, these values can be determined completely in userland and inserted by the application during runtime (compilation), meaning the BDS system would require and insert the variables needed to gather the data required to compile the template. It is sort of like the concept of Less or Sass for CSS, but for DBSs.

Scott

TRPB commented 9 years ago

The problem is, you'll need some binding logic somewhere that says "field name goes in this html element`

For something like what you suggest, it's very easy:

.users tr {repeat: data(users); }
.users td {content: iteration(attr(data-field));}

Then in my template I have:

<table class="users">
    <tr>
        <td data-field="name">User name</td>
        <td data-field="email">Email</td>
    </tr>

</table>

I can then use the same .bds file with any table of the class .users.

smolinari commented 9 years ago

My BDS could even look more like this.

@name_list = $nameList;

#table.@name_list.id {
        body.onload: alternate(@name_list.id);
        style: 100%;
       .tr {repeat: @name_list.row_count;}
       .th {repeat: i18n(@name_list.th)}
       .td {repeat: @name_list.td}
 }   

Prerequisite: The alternate and i18n functions must be registered with the BDS system, otherwise it errors during compilation of this BDS. Also the $nameList variable must be available at compilation time. I know this is a lot more than what you intended BDSs to be, but can't you see the power?

Scott

TRPB commented 9 years ago

I'd prefer to stick as closely to CSS syntax as possible as people are already familiar with it.

smolinari commented 9 years ago

Ok. It is a start. :+1:

Scott

smolinari commented 9 years ago

The problem is, you'll need some binding logic somewhere that says "field name goes in this html element`

I don't understand this though. Why can't the BDS system just compile a proper td for the field data it is given, in the order it is given? With the field name definition in the template, that puts the data order in the hands of the designer, which is not always wanted.

Scott

TRPB commented 9 years ago

The thinking behind data() and iteration() is that it works like url() and references an external resource. Adding real variables and annotations adds a lot of complexity to the format.

I don't understand this though. Why can't the BDS system just compile a proper td for the field data it is given, in the order it is given? That puts the data order in the hands of the designer, which is not always wanted.

What exactly is the designer doing here then? Defining a template that looks like this?

<table class="users">
<tr>
<td></td>
</tr>
</table>
TRPB commented 9 years ago

What I'm struggling to see with your suggestion is that most of the time, we're not dealing with just flat tabular data. How would I do this user list:

<table class="users">
    <tr>
        <td class="name">Name</td>
        <td class="email"><a href="mailto:email">email</a></td>
        <td class="edit"><a href="user/edit/id">Edit</a></td>
        <td class="delete"><a href="user/delete/id" onclick="return confirm('Delete this user?');">Delete</a></td>
    </tr>
</table>

Using the format I'm proposing it's easy to do this:

.users tr {repeat: data(users);}
.users .name {content: iteration(name);}
.users .email a {content: iteration(email);}

/* Still not 100% sure on this way of writing to attributes but lets run with it for this example */
.users .email a:attr[href] {content: "mailto:", iteraton(email);}

.users .delete a:attr[href] { content: "user/delete/", iteration(id)};
.users .edit a:attr[href] { content: "user/edit/", iteration(id)};
smolinari commented 9 years ago

Adding real variables and annotations adds a lot of complexity to the format.

I understand. But, why did Less and Sass get invented? To solve a problem, right? And I'll bet money BDSs will have that problem at some point too. The data will need to be "abstracted" to include userland variables and formatting.

What exactly is the designer doing here then? Defining a template that looks like this?

His job? :) His fun is no longer putting behavior and data in the structure, and design in CSS, but rather putting data and behavior in BDSs.

The table template would actually be more like what it should look like for the design, but with no functionality or real data.

<table class="list">
  <tr>
    <th>Name</th>
    <th>Email</th>
    <th>Functions</th>
  </tr>
  <tr>
    <td><a href="">Test Name</a></td>
    <td><a href="">some@test-email.com</a></td>
    <td><a href="">Edit</a></td>
    <td><a href="">Delete</a></td>
  </tr>
</table>

The BDS could be:

@list = $list;

.@list.name {
       .tr {repeat: @list.row_count;}
       .th {repeat: @list.th; colspan: @list.functions.count;}
       .td {repeat: @list.td.data; repeat: @list.functions;}
 } 

Scott

smolinari commented 9 years ago

Actually, no. That won't work.

@list = $list;

.@list.name {
        tr {repeat: @list.row_count;}
        th {repeat: @list.th;}
        th .functions {content: @list.function.name; colspan: @list.functions.count;}
        td {repeat: @list.td.data; repeat: @list.functions;}
 } 

That's better. :smile:

Scott

TRPB commented 9 years ago

how would you write the email address to the content of the <a> tag (and set its href)?

TRPB commented 9 years ago

As for repeating columns using a data set, how about this:

$data = ['users' => []];
$data['users'][] = ['name' => 'User 1', 'email' => 'user1@example.com'];
$data['users'][] = ['name' => 'User 2', 'email' => 'user2@example.com'];

.users tr {repeat: data(users); }
.users td.info {repeat: iteration(); content: iteration();}

.users th.info {repeat: data(users) 1; content: key();}

<table class="users">
    <thead>
        <tr>
            <th class="info">heading</th>
            <th>&nbsp;</th>
            <th>&nbsp;</th>
        </tr>
    </thead>
    <tr>
        <td class="info"> user info</td>
        <td><a href="#">Edit</a></td>
        <td><a href="#">Delete</a></td>
    </tr>
</table>

Where key() is the array key.

smolinari commented 9 years ago

how would you write the email address to the content of the tag (and set its href)?

Because an <a> tag is in the structure, the data given must match and hold the link and proper attributes for the <a> tag. Also, for the email, the data source should have some sort of meta data denoting it as an email, so Transphporm forms the HTML accordingly.

I also forgot something and changing things up a bit with more nesting.

@list = $list;

.user_list {
        tr {repeat: @list.row_count;}
        th {
             repeat: @list.th;
            .functions {content: @list.function.name; colspan: @list.functions.count;
        }
        td {
             repeat: @list.td;
            .functions {repeat: @list.td.functions;} 
            .delete {onclick: confirm("Are you sure?");}
        }
 } 

So this is saying.

  • Find an element with the class name matching object.name_variable. Like "user_list". The designer should know not to give a div this class name, for instance.
  • Create a bunch of nested <tr>s according to the number of rows in the list object.
  • In the first <tr>, insert all `? s with the list if "th" data.
  • as the last activity for <th>s add the "functions" part of the array, add colspan so this only spans the number of functions available.
  • In the rest of the <tr>s, add <td>s with the data in list.td and at the end list off <td>s for the list.td.functions. The delete function must also get the confirm JS function injected.

Piece of cake. :smile: LOL!

Edit: Ok. I see the class or identifier must be matched. It can't be as generic as I'd like it to be.

Scott

TRPB commented 9 years ago

Because an tag is in the structure, the data given must match and hold the link and proper attributes for the tag. Also, for the email, the data source should have some sort of meta data denoting it as an email, so Transphporm forms the HTML accordingly.

This is where I find it falls down. Essentially we are using the BDS to transform a data structure into HTML. If we have to transform a data structure into a HTML-like structure (With knowledge of the tag and attribute names) before passing it to the BDS then we have at best a duplication of effort. You'll have to write a function to format the data in the BDS "sorta html" ready format. Then have the BDS change the "sorta html" into proper html.

If I want to add a single new element with a new link (Another table column) I need to edit the function that is extracting data from the backend to structure the data in a new way that represents the updated HTML. This is backwards, the person writing the function that assigns data to the BDS shouldn't care about the structure of the HTML, only the data it could potentially reference it should be up to the person who is writing the BDS to extract the required data and decided how it is applied to the template, not the person passing the data to the template.

smolinari commented 9 years ago

Hmmm.....the data must have some form of metadata determining the type. This metadata is what Transphporm needs to know to do the proper formatting with the data. It "transphporms" it. :smile: I am liking that name more and more. If it is an email data type, then the appropriate tag is formed. In other words, tag attributes are data, not structure.

Oh, and the designer could also use the BDS to disable any linking.

.email {a: nolink}

Or add a function to the email field, for hiding the email address appropriately.

.email {a: hidelink()}

Which brings me back to what I said about the structure. Instead of the if/then normally needed in the structure with Twig to hide an email link for the non-admin, the designer just puts in the <a> tag in the structure, indicating that links should be added for all instances where the data allows for it, like a name for a user or title for a blog. Then through the BDS, the designer just denotes special behaviors. Like

.email {a: showadmins()}

The functions make the system so flexible, as this is client code or pre-built plug-ins. There is no more if/then/else in a template..

As for repeating columns using a data set, how about this:

At least I got you thinking a bit in the same direction! :+1:

I can't say what I am wishing for is a better solution than the template syntax like Twig has. It seems it could get just as complicated. But still, the idea of splitting out data and behavior from the structure is intriguing. I mean. It solves the same problem that CSS solves with design and content. And that is cool!

Scott

smolinari commented 9 years ago

Ok. To conform more to CSS. How about this?

.email a {link: false;}

or

.email a {link: showadmins();}

Scott