Search code examples
ruby-on-railsrubyslim-lang

scoped Iteration variable in slim template ceases to exist when indenting


I have the following .slim template:

.row
  .col-md-12.col-lg3
    .col-md-6.col-lg3
      .panel.panel-default.list-panel
        .panel-heading
          h3.panel-title Some Title
        .panel.body
          ul
            - @host_domains.each do |host, domains|
              li
                h4 for host: #{host} #{domains}
                ul
                  - domains.each do |domain|
                    li
                      = domain

The value of @host_domains is set to a testing value of:

    @host_domains = {
        'some_host' => %w[www.google.com facebook.com screwyou.com],
        'some_other_host' => %w[www.google.com facebook.com screwyou.com]
    }

The issue is that when it starts iterating over domains I get the error undefined local variable or method 'domains'. I know it exists because it does not error on the line before (h4 for host: #{host} #{domains}) where I added domains to see if it would error (it does not).

Why does the scoped iteration variable domains cease to exist when I try to iterate over it?

It's probably something small that I'm just not seeing.

EDIT: removing the ul tag and aligning it fixes the no variable issue. The issue is definitely indention related, changing the ul tag to say div still results in the same error.

EDIT: I'm reasonably certain the problem is slim, it's ignoring indentation.

If I I change the template to look more like this:

            - @host_domains.each do |host, domains|
              li
                h4 For host: #{host}
                - domains.each do |domain|
                  li #{domain}

and then look at the generated html, I can see that instead of bunch of li tags inside of a li tag, it's putting the domain li tags next to the li tag it's supposed to be inside of.

The issue then is that slim just isn't respecting indentation and just moving things around as it pleases which is not what it should be doing.


Solution

  • Slim doesn't respect the indentation structure so you have to force it to do so by wrapping the inner ul/li tags within a div tag.

    Like this:

                - @host_domains.each do |host, domains|
                  li
                    h4 For host: #{host}
                    div
                      ul
                        - domains.each do |domain|
                          li #{domain}