I recently began working on a documentation site using Ruby on Rails and Turbo (repository is here, and the website is here), and I'm having a slight issue with navigation.
When I press the links in the left sidebar, the content on the right side of the screen is correctly replaced. Here's some relevant code -
articles.html.erb
<div class='docs-split'>
<div class='sidebar'>
<div>
...
<div class='links padding-top'>
<%= link_to render(:partial => 'shared/primary_navigation_link', locals: { title: "Getting Started", path: "getting-started" }), 'getting-started' %>
<%= link_to render(:partial => 'shared/primary_navigation_link', locals: { title: "Types of Charts", path: "types-of-charts" }), 'types-of-charts' %>
</div>
</div>
</div>
<div class='content'>
<%= turbo_frame_tag "article", src: article_path(params[:title] ? params[:title] : "getting-started") do %>
<% end %>
</div>
</div>
articles_controller.rb
require 'github/markup'
class ArticlesController < ApplicationController
def index
end
def open_article
title = Rails.root.to_s + "/app/markdown/" + params[:title] + ".md"
#content = ActionController::Base.render inline: GitHub::Markup.render(title, File.read(title))
end
end
open_article.html.erb
<%= turbo_frame_tag "article" do %>
<%= #content %>
<% end %>
routes.rb
Rails.application.routes.draw do
root :to => redirect('/articles/getting-started')
get 'articles/:title', to: 'articles#index'
# Embedded article GET route
get ':title', to: 'articles#open_article', as: 'article'
end
What I expect to occur is that only the content inside the Turbo tag will change while the rest of the HTMl remains the same and the navigation link styles will transition as specified by my CSS. However, what seems to occur instead is that all of the HTML is reloaded, which means the CSS transitions that are supposed to happen when navigation links are clicked don't happen and the Turbo tag content appears to blink twice.
I'm new to Rails and Hotwire/Turbo, so any help would be appreciated. Thank you!
Related
I have a page with the following code:
<div>
<% if #site.roster_management_enabled? %>
<h3><%= link_to "Go To Page", { :controller => 'roster_player_import', :action => 'rostering_redirect'}, :target => "_blank" %></h3>
<% end %>
</div>
The controller/action mentioned above is as follows:
def rostering_redirect
url = URI.join(#site.boss_organization.admin_app_root_url, 'rostering')
redirect_to url.to_s
end
I want the html code listed above to execute automatically rather than having the user click on the link. To be more specific, is there a way to return the URL from the controller/action and pass that to the HTML code such that I don't have to use the syntax {:controller =>.....} and instead use something like URL=....
You can put the url you redirect to directly in your template:
<div>
<% if #site.roster_management_enabled? %>
<h3><%= link_to 'Go To Page', URI.join(#site.boss_organization.admin_app_root_url, 'rostering').to_s, target: '_blank' %></h3>
<% end %>
</div>
This works if:
#site is available in the template (from your code it is not clear where it is loaded)
You do not need to run additional checks/tracking on the server side
I have little problems with nested layouts. On my site I need to make one separate part of the site only for administrator.
I have this in my application.html.erb file:
<body>
<%= render 'layouts/header' %>
<div class="container">
<%= yield %>
<%= render 'layouts/footer' %>
</div>
</body>
I was wondering how can I now make another template like this to be inserted inside <%= yield %> because for administrator part I again need fixed parts of the site like header and footer in main layout. Instead of header and footer I will have two menus. I want <%= yield %> to be filled with new template which will have menu on top and new <%= yield %> which will be filled with actions from admin controller. So, menu will always stay on top.
I've made a menu partial views/admins/_menu.html.erb:
<div>
<div>
<div class="container">
<ul>
<li><%= link_to "Action1", '#' %></li>
<li><%= link_to "Action2", '#' %></li>
<li><%= link_to "Action3", '#' %></li>
</ul>
</div>
</div>
</div>
My new layout is layouts/sublayouts/admin.html.erb:
<%= render 'admins/menu' %>
<%= yield %>
Currently alternative is to render views/admins/_menu.html.erb in each view on top but that doesn't look as a good solution to me.
Regular site would have this structure:
Header/Menu
|
Container
|Content
Footer
And admin site would have this structure:
Header/Menu
|
Container
|Content
|Admin Menu
|Admin Content
|
Footer
What would be the best way to accomplish this?
Update: Based on the comments I've updated the answer with a better understanding of the question
The best way is to incorporate this into your application.html.erb layout.
The desired behavior is to have the admin menu appear when the user clicks on the Admin Panel link or any links on the admin menu.
The way I recommend doing this is that you have an admin controller which handles routing to all of your admin views, so clicking on the Admin Panel button and all the links in the admin menu will be handled by your admin controller. Add a before_filter to you admin controller like this:
# app/controller/admin_controller.rb
class AdminController < ActionController::Base
before_filter: set_admin_status
private
def set_admin_status
#admin = true
end
end
In your application template do the following:
# application.html.erb
<body>
<%= render 'layouts/header' %>
<div class="container">
<% if #admin %>
<%= render 'admins/menu' %>
<% end %>
<%= yield %>
<%= render 'layouts/footer' %>
</div>
</body>
What this should do is that everytime you navigate to the page that corresponds to the Admin Panel or any of the links in your admin menu it will set the #admin_status flag to be true and your layout will render the admin menu, which I believe is the desired behavior.
Usually I do following to accomplish the same problem, I create the separate layout based on parent class:
application_controller.rb
class ApplicationController < ActionController::Base
protect_from_forgery
layout :layout
private
def layout
if self.class.parent == Admin
'application_admin'
else
'application'
end
end
end
app/views/layouts/application.html.haml
Header/Menu
|
Container
|Content
Footer
app/views/layouts/application_admin.html.haml
Header/Menu
|
Container
|Content
|Admin Menu
|Admin Content
|
Footer
Update 1
config/routes.rb
namespace :admin do
root to: 'home#index'
resources :admins
end
app/controllers/admin/admins_controller.rb
class Admin::AdminsController < ApplicationController
def index
// code
end
end
I am new to rails and still working on fundamentals, so any tips and advice are greatly appreciated!
I've made a functional contact page on a website, and I would like to be able to render the form and functionality of inside a tab on a different page. I have the following code in the static_pages folder in my views folder:
<div id="tabs">
<ul>
<li>About</li>
<li>Contact</li>
</ul>
<div id="tabs-1">
<%= render "shared/about"%>
</div>
<div id="tabs-5">
<%= render "contact/new"%>
</div>
where <%= render "contact/new"%> corresponds to the new.html.erb file in contact in views.
the relevant code inside my routes.rb is
match 'contact' => 'contact#new', :as => 'contact', :via => :get
match 'contact' => 'contact#create', :as => 'contact', :via => :post
and here is my controller:
class ContactController < ApplicationController
def new
#message = Message.new
end
def create
#message = Message.new(params[:message])
if #message.valid?
NotificationsMailer.contact_pr(#message).deliver
redirect_to(root_path, :notice => "Message was successfully sent.")
else
flash.now.alert = "Please fill all fields."
render :new
end
end
end
However, It seems that whatever I try I still am unable to render the form. I apologize if this is a very simple question, and I am mostly interested in getting better at fundamentals in Ruby on Rails so any advice is appreciated! Thanks!
If you want to render this form in other templates (and you do), you should extract it to partial named for example: _form.html.erb.
Then, you should put
<%= render 'contact/form' %>
everywhere you need this partial in view (including new.html.erb template).
When you are done with this, you should leave
render :new
in controller, as it works a little bit different than in view and it renders appropriate action template instead of partial.
Of course, you need to set #message variable everywhere you need this partial. Or, you can put in your partial:
<%= form_for(#message || Message.new) do |f| %>
More info about layouts and rendering here.
I found the gem bootstrap-addons-rails and wanted to use it for Image Galleries in my Rails Application.
I have built a model Gallery and connected it through a has-many-relationship to a model Image. To storage the images I used Paperclip. Now I wanted to build the view (show-action in the galleries-controller) and tried to follow the documentation for the Bootstrap Image Gallery, which says:
<div id="gallery" data-toggle="modal-gallery" data-target="#modal-gallery">
Banana
Apple
Orange
</div>
I began with the following for my view:
<div id="gallery" data-toggle="modal-gallery" data-target="#modal-gallery">
<% #gallery.images.each do |image| %>
<%= image_tag(image.url.url(:original)) %>
<% end %>
</div>
But I have no idea how I can transfer the HTML-Snippet to a nice working Rails-Code. Especially the href="apple.jpg" is my problem. I don`t know how I can put there something like:
image_tag(image.url.url(:original))
I would be thankful for any answer.
If you want to link to the image, use this code:
<%= link_to image.url.url(:original), "Image", :data => {:gallery => 'gallery'}, :title => "Apple" %>
If you want the actual image to have the data-type attribute, use this code:
<%= image_tag(image.url.url(:original), :data => {:gallery => "gallery"}, :title => "Apple") %>
Hope it helps!
Getting a little bit confused as to why these whitespaces are being taken literally.
If you take a look at the image below you'll see a bunch of rectangles. The top rectangle on the left should actualy align with the bar on the right but it doesn't because of a line break.
The rails code for this layout looks like this...
In the layout:
<div id = "left_bar"><%=yield(:left_bar)%></div>
<div id = "main_content"><%=yield%></div>
And in the actual template:
<div class = "set_area images current" id = "set_area_<%= #image_set.id %>">
<%= render('images/images', :images => #image_set.images) %>
<div class = "clear"></div>
</div>
<% content_for :left_bar do %>
<% for set in #image_sets %>
<%= render("set_tab", :set => set, :is_current_tab => set.eql?(#image_set))%>
<% end %>
<% end %>
EDIT: Above code has slightly been simplified for brevity.
UPDATE: When I replaced the line to render the partial:
<%= render("set_tab", :set => set, :is_current_tab => set.eql?(#image_set))%>
with
<p>Hello</p>
The white-spaces didn't show up.
I tracked down the issue to the "set_tab" partial. I started removing and re-adding in lines again.
I believe this went wrong because there were some mixed encodings. I mostly work on linux machine but I did some editing on a windows machine earlier in the day.
If anybody else find their view acting up like this throw out your indentation and redo it.