Как мне высушить это представление с заботой или помощником или чем-то еще?

У меня есть Post с вложенными файлами через Carrierwave.

На мой взгляд, в зависимости от типа вложения я хочу, чтобы отображался другой значок.

Итак, вот что я придумал, что теперь работает нормально, но довольно неприлично и не СУХО.

Как упростить это и сделать более похожим на Rails?

<% if post.file? %>
    <% if post.file.file.extension.downcase =~ /mp3|wav/ %>
        <i class="fa fa-file-audio-o"></i>
    <% elsif post.file.file.extension.downcase =~ /pdf/ %>
        <i class="fa fa-file-pdf-o"></i>
    <% elsif post.file.file.extension.downcase =~ /txt/ %>
        <i class="fa fa-file-text-o"></i>
    <% elsif post.file.file.extension.downcase =~ /doc|docx/ %>
        <i class="fa fa-file-word-o"></i>
    <% elsif post.file.file.extension.downcase =~ /xls|xlsx/ %>
        <i class="fa fa-file-excel-o"></i>
    <% elsif post.file.file.extension.downcase =~ /ppt|pptx/ %>
        <i class="fa fa-file-powerpoint-o"></i>
    <% elsif post.file.file.extension.downcase =~ /mp4|m4v|mov|avi|mkv/ %>
        <i class="fa fa-file-video-o"></i>
    <% end %>
<% end %>

Изменить 1

Я также хотел бы иметь возможность легко определять тип файла с расширением, а затем выполнять с ним какое-то действие. Эта версия значка - всего лишь одно приложение.

Другой пример — мои кнопки «Поделиться». В зависимости от типа прикрепленного файла я хочу добавить имя файла, включенного в заголовок общего ресурса. Так, например:

Моя иконка «Поделиться в Твиттере» без этой логики выглядела бы примерно так:

  <a class="btn btn-twitter" href='http://twitter.com/home?status=<%=u "#{post.title} - Read more at #{post_url(post)}" %>' title="Share on Twitter" target="_blank">
    <i class="fa fa-twitter"></i>
  </a>

С логикой:

<% if post.file? %> 
  <a class="btn btn-twitter" href='http://twitter.com/home?status=<%=u "#{post.title} (#{post.file.file.extension.upcase} Included) - Read more at #{post_url(post)}" %>' title="Share on Twitter" target="_blank">
    <i class="fa fa-twitter"></i>
  </a>
<% end %>

Есть ли более элегантный, Railsy способ подойти к этому?

Изменить 2

С прекрасным элегантным решением @blelump, которое мне нравится, я пытаюсь сделать следующее:

<i class='fa attached-<%= post.file.file.extension.downcase %>'></i>

Где в моем post.css.scss у меня такие правила:

.attached-mp3, .attached-wav {
    @extend .fa-file-audio-o;
}

.attached-pdf {
  @extend .fa-file-pdf-o;
}

.attached-txt {
    @extend .fa-file-text-o;
}

Проблема в том, что HTML-код, создаваемый этим, таков:

<i class="fa attached-txt"></i>

Кажется, он не вызывает @extend .fa-file-text-o.

Как я могу это исправить?

Изменить 3

Вот как мой post.css.scss выглядит после предложений @blelump:

.field_report{
  width: 100%;
}

.field_report #report_box{
  width: 100%;
  height: 250px;
}

.attached-mp3, .attached-wav {
    @extend .fa-file-audio-o;
}

.attached-pdf {
  @extend .fa-file-pdf-o;
}

.attached-txt {
    @extend .fa-file-text-o;
}

.attached-doc, .attached-docx {
    @extend .fa-file-word-o;
}

.attached-xls, .attached-xlsx {
    @extend .fa-file-excel-o;
}

.attached-ppt, .attached-pptx {
    @extend .fa-file-powerpoint-o;
}

.attached-mp4, .attached-m4v, .attached-mov, .attached-mkv, .attached-avi {
    @extend .fa-file-video-o;
}

person marcamillion    schedule 04.11.2014    source источник


Ответы (2)


Вы, вероятно, используете LESS или SASS, поэтому CSS вас спасет. Для SASS, например.

.whatever-pdf {
  @extend .fa-file-pdf-o;
}

Поскольку вы используете значки FontAwesome, убедитесь, что эти классы объявлены в .scss, который включает вызов @import FontAwesome. В вашем случае это bootstrap_and_overrides.css.scss.

Затем, в вашем представлении, он превращается в:

<i class="fa whatever-#{post.file.file.extension.downcase}"></i>

и это все.

Редактировать 1:

Пример для EN локалей:

# config/locales/en.yml:
en:
  posts: 
    file_has_been_included: "(your %{file} has been included)"
  extensions:
    pptx: powerpoint presentation
    # ...

#view:
  <a class="btn btn-twitter" href='http://twitter.com/home?status=<%=u "#{post.title} #{t("posts.file_has_been_included", file: t("extensions.#{post.file.file.extension.downcase}"))} - Read more at #{post_url(post)}" %>' title="Share on Twitter" target="_blank"></a>
person blelump    schedule 04.11.2014
comment
То есть я просто создал бы эти правила для всех расширений в моем файле .scss? Не возражаете ли вы просто отредактировать это для всех моих правил, чтобы я мог точно знать, как будет выглядеть мой файл SASS? Спасибо! - person marcamillion; 04.11.2014
comment
Да, конечно, есть и другие решения, включая добавление логики в ваш помощник, но здесь это не обязательно. Это точно самый быстрый. - person blelump; 04.11.2014
comment
Это красивое элегантное решение. Проблема, с которой я сталкиваюсь, заключается в том, что я хочу сделать более сложные вещи. Я только что обновил свой вопрос. Можете ли вы изменить свой ответ, чтобы включить подход к этому, пожалуйста? Спасибо! - person marcamillion; 04.11.2014
comment
Таким образом, в конечном итоге #{post.title} (#{post.file.file.extension.upcase} Included) - ... расширяется в blah blah (PPTX included). Ну, вы можете использовать свои локали здесь, это было бы более элегантно. С I18n было бы #{post.title} (#{t("something.something.pptx") } Included) - ..., которые дают blah blah (your powerpoint presentation has been included) - ... Лучше, не так ли? - person blelump; 04.11.2014
comment
Это звучит неплохо. Не могли бы вы показать это более подробно в ответе, пожалуйста. Спасибо! Изменить: включая такие вещи, как то, что я помещал в какой I18n файл и т. д. - person marcamillion; 04.11.2014
comment
Отлично спасибо! У вас случайно нет опыта работы с simple_form и country_select? stackoverflow.com/questions/26736875/ - person marcamillion; 04.11.2014
comment
Привет @blelump, у меня проблема с первой частью этого ответа. Я только что обновил вопрос. - person marcamillion; 04.11.2014
comment
Правильно ли он компилируется? Загляните в свой скомпилированный файл post.css и проверьте. .attached-pdf { } пусто? - person blelump; 04.11.2014
comment
Я даже не вижу .attached-pdf или каких-либо других правил в скомпилированном post.css в разработке. Должен ли я включить что-то в моем development.rb для его компиляции? В моем post.css.scss есть 2 других обычных правила CSS, которые я вижу в своем post.css. Не уверен, что это имеет значение, но до сих пор я никогда не использовал scss функциональные возможности моих sass файлов, кроме импорта Bootstrap. - person marcamillion; 05.11.2014
comment
Я также отредактировал свой вопрос, чтобы включить мой post.css.scss в его текущее состояние после вашего предложения. - person marcamillion; 05.11.2014
comment
Поскольку вы хотите загружать его только в своих действиях с публикацией, это не сработает. Для директивы SASS @extend ваши классы .fa-file-... не видны, поэтому ваш css пуст. Вы можете включить соответствующий css, содержащий определения этих классов, в post.css.scss, но это приведет к тому, что эти классы будут загружены для действий публикации дважды (первый, вероятно, в вашем app.css.scss, а второй в post.css.scss). - person blelump; 05.11.2014
comment
У вас есть два варианта. Либо поместите эти определения .attached-xls, .attached-xlsx и т. д. в область видимости (например, app.css.scss — да, тогда они будут загружены везде), содержащую fa- классов (чтобы они были видны для директивы SASS @extend), либо вам нужно вернуться к своей первой идее с огромным if else/case when решение. - person blelump; 05.11.2014
comment
если я перемещу его в свой app.css.scss, он будет компилироваться при КАЖДОМ запросе или просто компилируется один раз при развертывании приложения в Heroku? Если он скомпилирован только один раз, и это просто вопрос загрузки стилей в моем application.css, я не возражаю. Но если он будет компилироваться при каждом отдельном запросе (в чем я сомневаюсь, но я просто дважды проверяю), то это, очевидно, нет-нет. - person marcamillion; 05.11.2014
comment
Кстати, я только что попробовал, и он все еще не работает. Я получаю эту ошибку в своем server.log: WARNING on line 64 of /app/assets/stylesheets/application.css.scss: ".attached-mp3" failed to @extend ".fa-file-audio-o". The selector ".fa-file-audio-o" was not found. This will be an error in future releases of Sass. Use "@extend .fa-file-audio-o !optional" if the extend should be able to fail. Может ли быть так, что .fa-file-audio-o — это значок с потрясающим шрифтом. FontAwesome загружается в bootstrap_and_overrides.css.scss после загрузки application.css. Может ли это влиять? - person marcamillion; 05.11.2014
comment
Кстати... теперь, когда я смотрю на свой server.log, когда я помещаю его в свой post.css.scss, я также вижу эту ошибку. Так что это касается не только application.css.scss. - person marcamillion; 05.11.2014
comment
Компиляция CSS SASS — очень деликатный процесс. Вы должны создать некоторые file.css.scss. Затем в этом файле @import right_name_for_fonts_awesome и ниже ваши расширения css. Вы поняли идею? Вы можете сделать это в пределах bootstrap_and_overrides.css.scss, если это текущее место @import right_name_for_fonts_awesome. - person blelump; 05.11.2014
comment
Чтобы ответить на ваш первый вопрос, для производства они компилируются только один раз, во время assets:precompile задачи. - person blelump; 05.11.2014
comment
Ага, хорошо. В этом есть смысл. Я просто включил эти стили в свой bootstrap_and_overrides.css.scss, куда был импортирован fontawesome. Теперь это работает. Большой! Теперь, чтобы проверить вторую часть ответа! - person marcamillion; 05.11.2014

Вы написали post.file.file.extension.downcase несколько раз. Вы можете объявить его в новой переменной

filename = post.file.file.extension.downcase

вместо операторов if else вам нужно использовать операторы case when

<% if post.file? %>
<% case filename %>
<% when filename =~ /mp3|wav/ %>
    <i class="fa fa-file-audio-o"></i>
<% when filename =~ /pdf/ %>
    <i class="fa fa-file-pdf-o"></i>
<% when filename =~ /txt/ %>
    <i class="fa fa-file-text-o"></i>
<% when filename =~ /doc|docx/ %>
    <i class="fa fa-file-word-o"></i>
<% when filename =~ /xls|xlsx/ %>
    <i class="fa fa-file-excel-o"></i>
<% when filename =~ /ppt|pptx/ %>
    <i class="fa fa-file-powerpoint-o"></i>
<% when filename =~ /mp4|m4v|mov|avi|mkv/ %>
    <i class="fa fa-file-video-o"></i>
<% end %>
person Darkmouse    schedule 04.11.2014