Wie mache ich statische Inhalte in Rails?

73

Verschiedene Optionen betrachten:

Eine besteht darin, nur die statischen Seiten in den Ordner public / zu legen, aber ich möchte, dass der Header von Layout / Anwendung konsistent ist.

Ich habe es versucht, aber ich habe eine Fehlermeldung erhalten:

# in routes.rb:
map.connect '*path', :controller => 'content', :action => 'show'

# in content_controller.rb:
def show
  render :action => params[:path].join('/')
end

Alles, was ich möchte, ist eine einfache Möglichkeit, Dinge wie meine FAQ, Kontakt, tos, Datenschutz und andere Seiten, die keine Anwendung sind, an einem einfachen Ort zusammenzustellen, indem Sie einfach eine .rhtml erstellen. Wer hat das getan?

Timothy T.
quelle

Antworten:

178

Für Rails6 , Rails5 und Rails4 können Sie Folgendes tun:

Setzen Sie die Zeile unten am Ende Ihrer Routen

  get ':action' => 'static#:action'

Bei Anfragen an root / welcome wird die Datei /app/views/static/welcome.html.erb gerendert .

Vergessen Sie nicht, einen "statischen" Controller zu erstellen, auch wenn Sie dort nichts einfügen müssen.

Einschränkung: Wenn jemand versucht, auf eine nicht vorhandene Seite zuzugreifen, wird ein Anwendungsfehler ausgegeben. Siehe diese Lösung unten, die 404s verarbeiten kann

Für Rails3 müssen Sie 'match' anstelle von 'get' verwenden.

  match ':action' => 'static#:action'
Roland Studer
quelle
4
+1 Super, genau das, was ich brauchte. Dies sollte mehr Stimmen bekommen, da es sich um die neuesten Rails handelt.
Schwamm
14
Wenn sich jemand wundert, ist die ": Aktion" hier Magie; es wird nicht funktionieren, wenn Sie es ": id" oder ": title" oder was auch immer nennen.
Mahemoff
1
In Rails4 erhalte ich im Entwicklungsmodus eine Warnung, dass "match" durch "get" ersetzt werden soll.
Joseph
1
@ RolandStuder Entschuldigung, ich war nicht klar - alles was Sie tun müssen, ist "match" durch "get" zu ersetzen und es funktioniert perfekt. :)
Joseph
2
Wie vermeide ich Ausnahmen, da dies ein Allheilmittel ist? Idealerweise möchten Sie einen 404 geben, keine Ausnahme auslösen. Ich habe versucht herauszufinden, wie dies dokumentiert ist. Es löst keine fehlende Methode aus, sondern sucht nur nach der Ansicht auf der Festplatte.
Amala
22

hängt von der URL-Struktur ab, wenn Sie möchten, dass die Pfade von / (zB / about_us) abweichen, dann:

map.connect ':action', :controller => "static"

Dies sollte ganz am Ende Ihrer Routendatei erfolgen. Werfen Sie Ihre .html.erb-Dateien in app / views / static und Sie sind fertig.

Beispiel: about_us.html.erbWenn Sie einwerfen, erhalten Sie eine Seite unter / about_us.

Das Element, das Sie in Ihrer Frage haben, eignet sich hervorragend für eine Catch-All-Route, auf der Sie das Array analysieren können, unter dem Sie sich befinden params[:path]. Weitere Informationen hierzu finden Sie unter http://railscasts.com/episodes/46-catch-all-route

Omar Qureshi
quelle
13

Das Rendern einer Aktion macht keinen Sinn. Sie möchten eine Vorlage (oder eine Datei) mit einem Layout rendern.

# Path relative to app/views with controller's layout
render :template => params[:path]

# ... OR

# Absolute path. You need to be explicit about rendering with a layout
render :file => params[:path], :layout => true

Sie können eine Vielzahl verschiedener Vorlagen aus einer einzigen Aktion mit Seiten-Caching bereitstellen.

# app/controllers/static_controller.rb
class StaticController < ApplicationController
  layout 'static'

  caches_page :show

  def show
    valid = %w(static1 static2 static3)
    if valid.include?(params[:path])
      render :template => File.join('static', params[:path])
    else
      render :file   => File.join(Rails.root, 'public', '404.html'), 
             :status => 404
    end
  end
end

Zuletzt müssen wir eine Route definieren.

# config/routes.rb
map.connect 'static/:path', :controller => 'static', :action => 'show'

Versuchen Sie, auf diese statischen Seiten zuzugreifen. Wenn der Pfad keine gültige Vorlage enthält, wird die 404-Datei gerendert und ein 404-Status zurückgegeben.

  • http://localhost:3000/static/static1
  • http://localhost:3000/static/static3
  • http://localhost:3000/static/static2

Wenn Sie in app / public nachsehen, werden Sie ein static / -Verzeichnis mit static1.html, static2.html und static3.html bemerken. Nach dem ersten Zugriff auf die Seite sind alle nachfolgenden Anforderungen dank des Seiten-Caching vollständig statisch.

Tate Johnson
quelle
2

Überlegen Sie, ob Sie 1 Home Controller mit paar Methoden wie show, aboutus, privacy haben:

class HomesController < ApplicationController
  def show
  end
  def privacy
  end
  def aboutus
  end
end

Und ordnen Sie die show-Methode Ihrem Stamm zu, und ordnen Sie die andere einigen benannten Routen wie z

map.root      :controller => "homes", :action => "show"
map.aboutus "/aboutus", :controller => "homes", :action => "aboutus"
map.privacy "/privacy", :controller => "homes", :action => "privacy"

Und mit Blick auf jeden

app/views/homes/aboutus.html.erb --> you get http://localhost:3000/aboutus
app/views/homes/show.html.erb --> you get http://localhost:3000 (root)
app/views/homes/privacy.html.erb --> you get http://localhost:3000/privacy

Alle verwenden dasselbe Layout unter app / views / layout / application.html.erb

gkrdvl
quelle
2

Die Lindsaar- Lösung ist eine der besten, die ich je gesehen habe. Er erstellt statische Caching-Seiten, die abgelaufen sind, als sich die Git-Revision geändert hat.

<%= cache "site-page-#{@page_name}-#{App.git_revision}" do %>
  <%= render :partial => @page_name %>
<% end %>
ecleel
quelle
1

Erstellen Sie einen PagesController für Ihre statischen Seiten (z. B. Kontakt) und fügen Sie ihn ein

def contact_page
end

in config / route.rb einfügen

get 'contact' => 'pages#contact_page'

Dadurch wird der Inhalt von views / pages / contact_page.html.erb angezeigt

GoodViber
quelle
Warum das Downvote? Ich weiß zu schätzen, dass sich meine Antwort auf Rails 4 bezieht, werde aber trotzdem eine Frage beantworten.
GoodViber
1

Ich habe die Idee eines verallgemeinerten Controllers aus den gegebenen Antworten verwendet, aber ich wollte 404s fangen, also habe ich eine Aktion eingefügt, um beide Fälle zu behandeln:

# app/controllers/static_controller.rb
class StaticController < ApplicationController
    def static_or_404
        render params[:static]
    rescue ActionView::MissingTemplate
        render :not_found
    end
end

und dann ganz unten in meinem Routing:

# config/routes.rb
get '*static', to: 'static#static_or_404'

Es dient der Ansicht app/views/staticmit demselben Namen wie der Pfad, und wenn es keine solche Ansicht gibt, dient es app/views/static/not_found.html.erb. Man könnte auch ersetzen render :not_foundmit redirect_to root_pathoder irgendetwas anderes wollte passieren lassen.

eriese
quelle
Großartiges Zeug! Ich bin gerade auf meine Antwort zurückgekommen und wollte aufschreiben, wie man mit 404s umgeht. Dann habe ich gesehen, dass Sie das bereits getan haben, und jetzt verlinke ich stattdessen auf Ihre Lösung. In gewisser Weise wäre es immer noch gut, meine Antwort auf Sichtbarkeit zu aktualisieren. Oder vielleicht möchten Sie meine Antwort bearbeiten, damit Sie eine Zuschreibung erhalten. Viel verdiente Gegenstimme. Ich hoffe, dass die beste Antwort nicht zu lange bei den wenigsten Stimmen bleibt.
Roland Studer