slim-template / slim

Slim is a template language whose goal is to reduce the syntax to the essential parts without becoming cryptic.
https://slim-template.github.io
MIT License
5.34k stars 501 forks source link

Deal with 'spaces around tags' problem #375

Closed sheerun closed 12 years ago

sheerun commented 12 years ago

This issue is nicely visible in this stackoverflow question.

You have to put two spaces at the beginning of ' tag that appear after html tag to separate them with space. This is really annoying when adding many links to SLIM template, and sincerely one of the reasons why my team don't want to switch from HAML.

Please deal with it one way or another.

I think a good solution is to redefine ' tag to add spaces before and after added text UNLESS it is first or last in group. So following:

EDIT: I don't think this solution is good anymore. Please look at new one in this comment

p
  ' Please look
  a href="" here
  ' and 
  a comment 
  ' if you want

would render to:

<p>Please look <a>here</a> and <a>comment</a> if you want</p>

Following:

p
  'Please look
  a href="" here
  'and 
  a comment 
  'if you want

would render to:

<p>Please look <a>here</a>and <a>comment</a>if you want </p>

And following:

p
  |  Please look
  a href="" here
  |  and 
  a comment 
  |  if you want

would render to:

<p> Please look<a>here</a> and<a>comment</a> if you want</p>

I hope it is not too late. Please consider this issue seriously.

porada commented 12 years ago

Good idea.

Moreover, I’d happily replace ' with a different character (or characters). Compared to |, it’s invisible.

sheerun commented 12 years ago

If you really don't want to break backward compatibility, maybe using double quotes is a good idea.

Especially because strings can be interpolated by default in slim. I think it looks cute and is more visible.

p
  " Please look
  a href="" here
  " and 
  a comment 
  " if you want
minad commented 12 years ago

At first - why is this an issue? You shouldn't write such code after all. Slim and Haml are for structure, not for text.

Solutions:

sheerun commented 12 years ago

Then how you recommend writing paragraphs with many = link_to inside?

minad commented 12 years ago
  1. with double spaces
  2. with markdown helper and text interpolation
  3. with smart text mode
sheerun commented 12 years ago

These solutions are ridiculous for me. I hope you'll change your mind at some point.

minad commented 12 years ago

Ok, then don't use it.

stonean commented 12 years ago

@sheerun could always write your own template language to do what you want it to. That's what I did with Slim.

minad commented 12 years ago

I would really like to know why @sheerun finds the solutions ridiculous. I don't find the following that bad.

 | Text #{link_to ...} blablba
   foo bar #{link_to ...} asdasd

 markdown:
   Text #{link_to ...} blablba
   foo bar #{link_to ...} asdasd

And the spaces problem will be tackled especially by the smart text mode plugin. Why do you refuse to try it?

porada commented 12 years ago

select with nested options is a more problematic example than link_to. Is there a way to put it inline without using ' and double spaces?

minad commented 12 years ago

@porada Why is select with options problematic?

porada commented 12 years ago

Problematic as in, unlike link_to, can’t be solved using 3 different methods — there’s only one way to put it inline with a piece of text:

label
  ' Notify me
  select
    option daily
    option weekly
  |  about the changes.

IMHO, it’s just inelegant.

raxoft commented 12 years ago

What's the problem with smart mode's

label
  > Notify me
  select
    option daily
    option weekly
  > about the changes.

then?

raxoft commented 12 years ago

BTW, one of the reasons why the smart text mode was created in the first place was that I was tired of having to carefully choose between ' and | and single/double/trailing spaces to get the spaces around tags right, too. Now with the smart text mode available, I don't see much to complain about... And you even get the implicit text as an added bonus, so in many cases you don't even have to bother typing | or > at all.

porada commented 12 years ago

Didn’t know about using > before. Thanks.

Does it work in the current stable version of Slim?

raxoft commented 12 years ago

Unfortunately not, it's yet to be merged into the main trunk, see #351. You can try it from the slim branch, though, if you know how to use github branches with bundler or directly.

In either case, discussions like this one might help convince @minad that I am not the only one who likes the smart text mode, so it might eventually get merged earlier... :) That's why he was explicitly asking for feedback above, after all...

minad commented 12 years ago

@raxoft It is planned for 2.0.

raxoft commented 12 years ago

Great, thanks.

AdrienGiboire commented 12 years ago

I'm not sure the smart mode would handle such exemple:

p
  ' In addition to programming, we have expertise in
  strong Artificial Intelligence,
  strong Computer Science,
  strong Digital Business,
  strong Economics,
  strong Philosophy,
  strong Physics,
  strong Software Engineering,
  strong Mechanical Engineering,
  strong Finance,
  strong Political Science,
  strong Statistics
  ' and
  strong Data Mining
  ' which allows us to provide any client with perfectly tailored software and consulting services.

Which renders:

In addition to programming, we have expertise in Artificial Intelligence,Computer Science,Digital Business,Economics,Philosophy,Physics,Software Engineering,Mechanical Engineering,Finance,Political Science,Statistics and Data Mining which allows us to provide any client with perfectly tailored software and consulting services.

Trailing spaces in code ain't a solution. But I didn't find other way to add trailing spaces to each strong tag in the generated HTML.

Is it me doing it wrong?

sheerun commented 12 years ago

Use :markdown

simonc commented 12 years ago

I consider it an issue with forms. For instance I think the following is ugly :/

form.form-inline action="..." method="post"
  input type="text" name="user[name]" placeholder="Name"
  '
  input type="text" name="user[phone]" placeholder="Phone number"
  '
  button type="submit" Ok

I really love slim and I'd really love to be able to write it in a prettier way. I'm not fond of haml but I have to say, dealing with spaces is much more easier :(

What about something like this ?

form.form-inline action="..." method="post"
  input> type="text" name="user[name]" placeholder="Name"
  input> type="text" name="user[phone]" placeholder="Phone number"
  button type="submit" Ok

That wouldn't break the existing code using slim but it would add a nice workaround :)

sheerun commented 12 years ago

IMHO if any phrasing context element is next to other, they should be by default separated by space. Isn't that obvious? Just tell me just one case when you don't want that (remember, accessibility rule says, the content should be readable without CSS). I think that this should be the "smart mode", not ridiculous case matching...

One one hand you say SLIM is not form markup, but on the other you decide to implement smart mode. And current implementation just doesn't solve problems people are noticing here.

Side note: "Ok, then don't use it."? "write your own template language to do what you want it to"? You just embarrass me, and arguably open source community.

EDIT: see followup comment

simonc commented 12 years ago

The only case I see is when you want two elements to stick together but don't want to write it on the same line (would be ugly in slim :/).

I would :+1: @sheerun on this. I guess it would deserve a new major version because it could break existing code but it's (totally) worth it :)

sheerun commented 12 years ago

@simonc Probably white-space: nowrap; is better in your usecase.

simonc commented 12 years ago

@sheerun I don't think so, the line-break would be represented as a single space, right ? When I said "stick together", I meant without any space in-between.

sheerun commented 12 years ago

@simonc I see what you mean. Maybe in such cases the solution is to just use inline HTML (SLIM allows that).

Generally though, you don't want inline elements to not be separated by spaces because it breaks accessibility.

simonc commented 12 years ago

Haml has an elegant way to deal with this issue by adding a < or a > sign after the tag name. If spaces were kept by Slim, this solution to deal with the rare cases where you need to remove unwanted spaces seems pretty reasonable to me :)

raxoft commented 12 years ago

@AdrienGiboire: It would help if you have mentioned what output you would like. I mean, if you really wanted the strong tag include the commas (bad typography, BTW) separated by spaces, you could write

p
  In addition...
  strong Artificial Intelligence, Computer Science, ..., Statistics
  > and
  strong Data Mining
  > which allows us...

OTOH, if you wanted to format it properly, without strong tag around spaces, you could use

p
  In addition...
  strong Artificial Intelligence
  ,
  strong Computer Science
  ,
  ...
  ,
  strong Statistics
  > and
  strong Data Mining
  > which allows us...

Add extra > at appropriate places if you like it more that way. (BTW, I think that your example in fact misses couple of commas, but that's not the point).

So it is quite possible in Slim, but like others I would recommend using the builtin markdown or textile or autodoc markup for the bulk text instead.

@simonc: Personally, I have no issue with separating the input elements with '. I think that it makes it stand out nicely. It goes consistently well along with other separators one might use, like ' | or ' &middot;. Besides, you always have the option of not using spaces at all and separate the elements properly with CSS alone.

@sheerun: Of course that you don't want tags to be always surrounded by spaces. You don't want space before dot or comma following an </a>, for example, or inside parens. Also, it would be a nightmare for CSS styling if slim inserted extra spaces around spans or input elements at will. I am really glad that it doesn't insert space unless told to, and I think it is quite consistent and easily explainable policy, too. Much better than what Haml does.

You also mention that smart mode doesn't solve something... Could you be more specific? From what I can see, your example with " which you consider cute and which you have been asking for would be written exactly like that with smart mode enabled (except with >)... Did you really bother at all to try to use the smart mode or are you just hypothesizing here?

@simonc: No offense, but the < and > in Haml are just plain stupid. There is little need for having two ways of removing the space between outer and inner tags (which wouldn't be necessary at all if Haml didn't insert the extra space on its own will in the first place). What is needed (and lacking in Haml) is the way of removing the space before and/or after the tag. Without that, how do you write something like <em>this</em>? That's why I think Slim's approach of not inserting extra spaces is better - you don't need ridiculous ways of getting rid of them afterwards...

simonc commented 12 years ago

@raxoft for one I guess the ' or ' | thing is a matter of test, I think it's ugly.

Concerning the space addition I expect

input type="text" name="user[name]" placeholder="Name"
input type="text" name="user[phone]" placeholder="Phone number"

to behave like

<input type="text" name="user[name]" placeholder="Name" />
<input type="text" name="user[phone]" placeholder="Phone number" />

where the space are significant even if they are collapsed into one. And like @sheerun said, it should be CSS rôle to do that.

For Haml and its lack of space removal options, I guess I could give the same answer than earlier, use markdown:

:markdown
  something like _this_?

What would make me happy is an option on Slim that let you choose how you want to handle spaces. I never ever use text nodes in slim. It's always the result of a call to a method or something else. So the absent spaces is especially painful when I create forms or series of links, etc. But like I said it's a matter of taste.

sheerun commented 12 years ago

@raxoft I don't think " solution is good anymore. You've made really good point about </a> and parens, but in these cases we should rather use markdown:, as @minad noticed earlier. But markdown can't be easily used for form elements, breadcrumbs (I mean, when we need to use iteration of some kind), or dynamic elements (when we use lots of - if and logic in general). So please note that we don't use SLIM only, but intermix it with Ruby code.

We encounter whitespaces problem pretty much everywhere inline tags are input, label, button, a (but not as part of static paragraph, that can be expressed as markdown:). And pretty much everywhere I want to put spaces around and I'm not happy about current SLIM behaviour as you are.

Unfortunately current "smart text mode" addresses "static" cases of paragraphs, that can be expressed using :markdown not the "dynamic" ones, which actually cause the problem. As Rails dev, I never create forms using SLIM only.

raxoft commented 12 years ago

@simonc Regarding spaces, I would just restate what I said. Many people are completely ignorant about spurious whitespace in HTML and the effect it has on rendering, and sometimes they are not even aware that what they get is not only because of the CSS but also because of the extra space and CSS combined. The 'no automatic spaces policy' is the best and safest choice here IMO.

Regarding the :markdown answer, it only applies to bulk text, not other text snippets. Do you build forms with markdown? I doubt that. Therefore being able to use markdown in Haml is no excuse for the inability of writing the example I gave in Haml itself (other than verbatim HTML, of course).

raxoft commented 12 years ago

@sheerun Well, if you don't consider the " solution good anymore, perhaps we can continue the discussion as soon as you have another solution which you will like. Until then, complaining about the current behavior is not getting anyone anywhere.

AdrienGiboire commented 12 years ago

Thanks guys :)

sheerun commented 12 years ago

@raxoft I presented new solution in comment above

simonc commented 12 years ago

@raxoft I'm not sure this kind of people is using Slim and the option I propose, allowing to choose the kind of space behavior you want would solve this.

No I don't write forms in markdown, that's why I'd like to be able to have spaces between my inputs without having to use what I consider a ugly hack to do so.

raxoft commented 12 years ago

@sheerun Well, perhaps you did, but I meant a solution which actually works.

@simonc I think that you don't need any global option which would modify space treatment. I guess you would soon learn that it breaks the other cases you weren't even thinking about anyway. You should be perfectly happy with something like what you mentioned above - adding > after the tag name inserts space after the closing tag, adding < after the tag name inserts space before the opening tag (and of course any combination thereof). Try suggesting that to @minad and see what he has to say about that.

sheerun commented 12 years ago

@raxoft Why you think it won't work? Btw. you've provided only examples of paragraphs that can be expressed using markdown:, no ruby code, no form elements, no loops. And why on earth I would begin form paragraph with sentence beginning with capital letter? Again, smart code addresses wrong class of issues.

I agree people need to understand that static paragraphs like this should be written using markdown:. I wouldn't recommend smart code for form elements though, and without it we're forced to use lot of whitespace-preserving markup. And that could be solved with different conventions, I described earlier (just separate inline elements with spaces by default).

simonc commented 12 years ago

@raxoft Yes, I would be happy enough with the > solution. I don't know if it deserves it's own issue though.

raxoft commented 12 years ago

@sheerun I have already pointed out why it doesn't work. And the first example I posted were form elements. Maybe you have mistaken 'me' and 'you'? Now if you excuse me I am out until this discussion starts to make sense again.

@simonc Well, you never know until you try :)

sheerun commented 12 years ago

@raxoft You're probably talking about following snippet you've posted earlier:

label
  > Notify me
  select
    option daily
    option weekly
  > about the changes.

This is not good example though, because there is only one form element, select is nested in label, and as I said there is no reason such paragraph should begin with sentence beginning with captal letter. Please tell how should the syntax be if select is after the label, not inside it. I can only come up with following:

label Foo
'
input name="bar"
'
label Bar
'
select
  option daily
  option weekly

I understand, that you've spent very much time implementing smart mode, but I beg you, don't be biased about it. If anyone has reasonable arguments against my solution I'm more than eager to throw it away (actually, my first solution in this topic can be an example, it certainly wasn't good one. We should not add new semantics, but rather change the conventions).

raxoft commented 12 years ago

@sheerun Honestly, I don't get what I am supposed to make out of your last post. It doesn't seem to make much sense to me. What's all that about the capital letter? And what syntax are you asking for?

The only thing which seems obvious is that rendering of your forms depends on the presence of whitespace between the form elements. In that case I would suggest that you start looking for a better CSS library which takes proper care of form rendering and don't waste your time on adding ad hoc spaces here and there to get what you want.

sheerun commented 12 years ago

I'm sorry about capital case confusion, for some reason I thought smart text has something to do with beginning sentence with capital letter, and it apparently only introduces new tag (<). Anyway, issues I've described stay the same. And there's no need to introduce new tag, if problem can be solved with different conventions.

That said, I think whitespaces between inline elements should be a rule, not exception.

The questoin is should text be separated by spaces (using >) or inline elements (including text, by convention).

Anyway, I'm done with this argument. I said what I had to say.

raxoft commented 12 years ago

@sheerun Well, it seems to me that your posts above consist of curious mixture of true, wrong, misleading as well as irrelevant facts. I am afraid that until you come up with a clear statement like 'I would like Slim input X render as Y because that would solve issue Z', it's not anymore obvious what exactly you want and what your problem is.

minad commented 12 years ago

What do you think about tag modifiers as suggested in #397

Patrik Rak notifications@github.com schrieb:

@sheerun Well, it seems to me that your posts above consist of curious mixture of true, wrong, misleading as well as irrelevant facts. I am afraid that until you come up with a clear statement like 'I would like Slim input X render as Y because that would solve issue Z', it's not obvious what exactly you want and what your problem is.


Reply to this email directly or view it on GitHub: https://github.com/slim-template/slim/issues/375#issuecomment-17479133

minad commented 12 years ago

I implemented a patch which allows the following syntax for trailing-ws. / and ' are tag modifiers for closed and trailing-ws respectively. They can be after or before attributes.

   input type="text" '
   input' type="text"
   input type="text" /
   input/ type="text"
   input type="text" '/
   input'/ type="text"
   a href="url" ' text
   a' href="url" text

https://github.com/slim-template/slim/tree/trailing-ws

porada commented 12 years ago

This is great. Thank you.

sheerun commented 12 years ago

Thank you, :cherries:

raxoft commented 12 years ago

Hmm, few comments about this:

sheerun commented 12 years ago

Perhaps following would be nicer:

  input' type="text"     # space after input
  'input type="text"     # space before input
  'a' href="url" text    # space around anchor
  'a' href="url" 'text'  # space around anchor and inner text
  a' href="url" text'    # space after anchor and inner text

I mean, the modifier should be only near the tag it modifies. It is also easy to reason about multiline blocks:

  'p'
    strong' Hello
    span world
  # Put space around p tag, with "Hello world" separated by space in it.
minad commented 12 years ago

I don't think we need more syntax for the special cases.