Haml: contrôler les espaces autour du texte

97

Dans mon modèle Rails, j'aimerais réaliser le HTML final à cet effet en utilisant HAML:

I will first <a href="http://example.com">link somewhere</a>, then render this half of the sentence if a condition is met

Le modèle qui se rapproche:

I will first
= link_to 'link somewhere', 'http://example.com'
- if @condition
  , then render this half of the sentence if a condition is met

Vous pouvez cependant noter que cela produit un espace entre le lien et la virgule. Existe-t-il un moyen pratique d'éviter ces espaces? Je sais qu'il existe une syntaxe pour supprimer les espaces autour des balises, mais cette même syntaxe peut-elle être appliquée uniquement au texte? Je n'aime vraiment pas la solution de balisage supplémentaire pour accomplir cela.

Matchu
la source

Réponses:

211

Une meilleure façon de le faire a été introduite via les assistants de Haml:

entourer

= surround '(', ')' do
  %a{:href => "food"} chicken
Produit:
(<a href='food'>chicken</a>)

réussir :

click
= succeed '.' do
  %a{:href=>"thing"} here
Produit:
click
<a href='thing'>here</a>.

précéder :

= precede '*' do
  %span.small Not really
Produit:
*<span class='small'>Not really</span>

Pour répondre à la question initiale:

I will first
= succeed ',' do
  = link_to 'link somewhere', 'http://example.com'
- if @condition
  then render this half of the sentence if a condition is met
Produit:
I will first
<a href="http://example.com">link somewhere</a>,
then render this half of the sentence if a condition is met
Ryan Crispin Heneise
la source
1
Bon timing, je viens de découvrir ces derniers en lisant la source de Haml. Apparemment, ils existent depuis un moment. Bizarre qu'ils ne les documentent pas dans la page de référence principale ...
Groxx
1
Pouvez-vous élargir votre réponse et montrer pour exprimer l'exemple du PO en utilisant ces aides (vraisemblablement succeedspécifiquement)? Pour moi, cela semble toujours non évident et un peu moche: gist.github.com/1665374
John
16
J'ai l'impression qu'il me manque quelque chose (en regardant le nombre de votes positifs), mais la variante de réussite n'est pas équivalente à celle d'origine, car la virgule de fin sera rendue même si @condition == false, ce qui est plus laid que l'espace avant cette virgule.
Nash Bridges
2
J'ai réussi à obtenir le résultat correct en utilisant precede, plutôt que de réussir. À votre santé!
Cam
40

Vous pouvez également le faire en utilisant le modificateur "Trim whitespace" de Haml. L'insertion >après une déclaration Haml empêchera l'ajout d'espaces blancs autour d'elle:

I will first
%a{:href => 'http://example.com'}> link somewhere
- if @condition
  , then render this half of the sentence if a condition is met

produit:

I will first<a href='http://example.com'>link somewhere</a>, then render this half of the sentence if a condition is met

Cependant, comme vous pouvez le voir, le >modificateur supprime également l'espace blanc devant le lien, supprimant l'espace souhaité entre les mots et le lien. Je n'ai pas encore trouvé de moyen de contourner ce problème, sauf pour ajouter &nbsp;à la fin de "Je vais d'abord", comme ceci:

I will first&nbsp;
%a{:href => 'http://example.com'}> link somewhere
- if @condition
  , then render this half of the sentence if a condition is met

Ce qui produit finalement la sortie souhaitée sans beaucoup d'interpolation difficile à lire:

I will first&nbsp;<span><a href="http://example.com">link somewhere</a></span>, then render this half of the sentence if a condition is met
Ryan Crispin Heneise
la source
1
J'ai oublié de mentionner que j'ai obtenu ceci de la feuille de triche Haml, ce qui est très utile: cheat.errtheblog.com/s/haml
Ryan Crispin Heneise
3
Cela fonctionne avec des balises mais pas des expressions; dans votre exemple, vous avez changé son expression en tag. J'ai le même problème et malheureusement ce n'est pas une solution.
Teflon Ted
1
Je ferais remarquer que cela &nbsp;a une signification particulière, ce n'est pas un espace blanc ordinaire - c'est un espace blanc insécable, ce qui signifie que pendant le retour à la ligne, le navigateur ferait tout pour garder les mots liés &nbsp;ensemble et ce n'est pas toujours ce que vous voulez.
Andrew
1
En plus du commentaire d'Andrew, utilisez &#032;plutôt que &nbsp;pour un simple espace blanc.
Daniel AR Werner
12

D'accord, voici la solution sur laquelle je m'installe:

Assistant

def one_line(&block)
  haml_concat capture_haml(&block).gsub("\n", '').gsub('\\n', "\n")
end

Vue

I will first
- one_line do
  = link_to 'link somewhere', 'http://example.com'
  - if @condition
    , then render this half of the sentence
    \\n
    if a condition is met

De cette façon, les espaces sont exclus par défaut, mais je peux toujours les inclure explicitement avec une ligne "\ n". (Il a besoin de la double barre oblique inverse, car sinon HAML l'interprète comme une nouvelle ligne réelle.) Faites-moi savoir s'il existe une meilleure option!

Matchu
la source
Note au monde: j'ai finalement compris et transféré ces derniers aux assistants: P
Matchu
Une autre note au monde: ces jours-ci, j'utilise la solution de Groxx :)
Matchu
Ceci est très utile quand il s'agit de haml qui génère un fichier texte! Dans mon cas, j'avais une ligne dont une partie était décidée par un "si", ce que je n'ai pas pu corriger avec la solution de mysamillidea car elle ne supprime pas les nouvelles lignes, elle déplace juste la virgule avant la nouvelle ligne. (Bien que je convienne que pour la réponse à la question originale, mysmallidea est la meilleure.)
cesoid
6

Vous pouvez utiliser la 'syntaxe d'aligator' de HAML

Suppression des espaces blancs:> et <

et <vous donne plus de contrôle sur l'espace blanc près d'une balise. > supprimera tous les espaces autour d'une balise, tandis que <supprimera immédiatement tous les espaces dans une balise. Vous pouvez les considérer comme des alligators mangeant l'espace blanc:> fait face à l'extérieur de l'étiquette et mange l'espace blanc à l'extérieur, et <fait face à l'étiquette et mange l'espace blanc à l'intérieur. Ils sont placés à la fin d'une définition de balise, après les déclarations de classe, d'id et d'attribut mais avant / ou =.

http://haml.info/docs/yardoc/file.REFERENCE.html#whitespace_removal__and_

Yo Ludke
la source
5

Une fois l'approche que j'ai adoptée pour ce genre de chose est d'utiliser l'interpolation de chaîne:

I will first #{link_to 'Link somewhere'}#{', then render this half of the sentence if a condition is met' if condition}

Je n'aime pas l'apparence de la chaîne littérale dans l'interpolation, mais je l'ai déjà utilisée avec des chaînes précédemment déclarées ou des chaînes générées dynamiquement.

Mandrin
la source
Mhm. C'est mon approche générale des choses comme ça, mais je n'avais jamais pensé à utiliser le conditionnel là-dedans. C'est dommage que le modèle que j'utilisais se soit avéré un peu plus complexe qu'une seconde moitié de phrase ... mais cela vaut vraiment la peine de s'en souvenir - merci!
Matchu
5

Vous pouvez le faire pour conserver l'espace principal:

%a{:href => 'http://example.com'}>= ' link somewhere'

L'espace est entre guillemets.

thethinman
la source
3

Bien que cela ne soit pas bien documenté, cela est réalisé proprement en utilisant la préservation des espaces blancs HAML (>) combinée à un espace ASCII (& # 32;), et non avec des helpers:

%a{:href=>'/home'}> Home link
,&#32; 
%a{:href=>'/page'} Next link

Cela produira ce que vous voulez:

<a href='/home'>Anchor text</a>,&#32;
<a href='/page'>More text</a>

Mais je suis d'accord, HAML doit trouver une meilleure façon de faire cela, car il ajoute des caractères ASCII inutiles à la page (mais c'est toujours plus efficace que d'utiliser des helpers).

ojak
la source
1

Il y a la syntaxe "grignotage d'espaces" entre crochets angulaires, sinon écrivez une méthode d'aide pour cela.

Andrew Vit
la source
Comment exactement une aide pour cela fonctionnerait-elle? Meh, je vais voir ce que je peux trouver ...
Matchu
En ce qui concerne le grignotage d'espaces, je ne peux pas trouver comment faire fonctionner cette syntaxe si ce n'est pas sur une sorte de définition de balise. Est-ce que je fais juste une erreur ou cette syntaxe ne fonctionne-t-elle pas sans balise?
Matchu
1

Je suis tombé sur un problème similaire et j'ai trouvé cela, alors j'ai pensé publier une autre solution qui ne nécessite pas de méthode d'aide. Utilisez l'interpolation Ruby # {} pour envelopper le lien et les instructions if:

I will first 
#{link_to 'link somewhere', 'http://example.com'}#{if true : ", then render this half of the sentence if a condition is met" end}

Cela fonctionne dans la version 3.0.18, cela peut également fonctionner dans les versions antérieures.

des biscuits
la source
Certes, Haml n'est pas conçu pour le contenu. Ce n'est pas du contenu dont nous parlons ici, cependant. C'est un modèle. L'auteur de cet article de blog fait référence à des choses comme l'écriture d'une page Web statique complète dans Haml, ce qui n'est pas ce que je fais. L'extrait de code que j'ai fourni est à peu près le .hamlfichier complet - le fait qu'il inclue un lien et une virgule n'indique vraiment rien de toute façon.
Matchu
1
Ah, je vois. J'ai édité ma réponse, laissant la solution autonome.
biscuits
Bien que cela puisse fonctionner, je pense que cela rend le balisage difficile à lire. À la place, utilisez simplement les modificateurs d'espaces blancs HAML <et> comme d'autres personnes l'ont mentionné, ce qui maintient votre HAML propre et lisible.
ToddH
1

Encore une autre option que j'ai utilisée dans le passé:

- if @condition
  %span> , then some more text after the link.
Colllin
la source
0

Vous pouvez également toujours faire:

= link_to url_path do 
  = ["part_1", "part_2"].join(", ")
bcackerman
la source
0

La solution que j'ai obtenue est:

I will first
= link_to 'link somewhere', 'http://example.com'
- if @condition
  = ", then render this half of the sentence if a condition is met"

Vous pouvez utiliser =, bien qu'il =soit utilisé pour afficher le résultat du code Rails, mais ici, il servira le but.

Arslan Ali
la source