I need to add a few links to certain pages of the application in the ActiveAdmin pages. I can do this using sidebars, but I'll have to repeat the code for each of my resources. Is there anyway of adding custom links to the header ? Or define a sidebar that will appear for all resources ?
I also wouldn't want to overlook setting config.site_title_link in initializers/active_admin.rb.
I'm pretty sure it takes a symbol representing the name of a route from your application, for example:
config.site_title_link = :root
would link the site title to your application's root_path.
Thanks #phoet ! Implemented it by overriding the HeaderRenderer instead:
module ActiveAdmin
module Views
class HeaderRenderer
def to_html
title + global_navigation + application_link + utility_navigation
end
def application_link
link_to('Back to Application', root_url)
end
end
end
end
i think there is no build-in way to do it, but you can override the render-logic in the TabsRenderer (2.2) / TabbedNavigation (3.0):
def render_menu(menu)
content_tag :ul, :id => #options[:id] do
menu.items.collect do |item|
render_item(item)
end.join.<<('your_custom_stuff').html_safe
end
end
Related
In the routes.rb I set lists#index as the root:
root to: "lists#index"
I would like will_paginate to create page hrefs pointing to /?page=# instead of /lists?page=#. To create the paginate links I have the following line in the "lists#index" file:
<%= will_paginate #lists %>
The solution was indeed a custom renderer. Thanks Ayush!
The following helped me to solve it: how-to-customize-the-will-paginate-links-with-images
I created a file: app/helpers/will_paginate_helper.rb with the following content:
module WillPaginateHelper
class RootedLinkRenderer < WillPaginate::ActionView::LinkRenderer
protected
def link(text, target, attributes = {})
if target.is_a? Fixnum
attributes[:rel] = ""
target = "/?page=#{target}"
end
attributes[:href] = target
tag(:a, text, attributes)
end
end
end
Finally, I updated the index file and replaced:
<%= will_paginate #lists %>
with:
<%= will_paginate #lists, renderer: WillPaginateHelper::RootedLinkRenderer %>
So the href is http://localhost:3000/?page=2 and not http://localhost:3000/lists?page=2.
What I understand from your question that you are trying to create a custom renderer, although I have never used it, but for that you need to override the link method of renderer.
here is the link to the original code might be of some help -
https://github.com/voormedia/paginary/blob/master/lib/paginary/helpers/pagination_helper.rb
In this particular case the links are influenced by the order of the routing instructions in the routes.rb file.
If you place the line
root to: "lists#index"
at the top of routes.rb then will_paginate will generate links to /?page=# without the need for a custom renderer.
This can be found in the FAQs for the module in coursera.
How do I edit or override the footer of Active_Admin?
Answer:
In your rails app, create this file: app/admin/footer.rb
The content would be something like:
module ActiveAdmin
module Views
class Footer < Component
def build
super :id => "footer"
super :style => "text-align: right;"
div do
small "Cool footer #{Date.today.year}"
end
end
end
end
end
Don't forget! restart the app/server.
Any ActiveAdmin layout component can be customized like this.
More about it:
Why does it work?
This is Ruby's magic sauce. We are reopening the definition of the Footer class and changing it for our custom content.
Is it totally customizable? I don't know. This is the inheritance path:
ActiveAdmin
class Component < Arbre::Component
class Footer < Component
Arbre
class Component < Arbre::HTML::Div
This means that we can use Arbre's DSL directly.
If all you want to do is change or delete the 'powered by' message, what you can do is change its value in a locale file. Example, edit config/locales/en.yml
And use something like this:
en:
active_admin:
powered_by: "Powered by hamsters"
Why this works:
The default locale for a rails app is english, the en locale file.
Between v1.0.4pre and v.1.0.5pre, the previous method of overriding Footer#build no longer works well, and the new API is
ActiveAdmin.application.footer = proc {
...
}
For v.1.0.0.pre5 I found that the Accepted Answer requires a small additiion, namely adding a variable to build as below:
module ActiveAdmin
module Views
class Footer < Component
def build (namespace)
super :id => "footer"
super :style => "text-align: right;"
div do
small "Cool footer #{Date.today.year}"
end
end
end
end
end
From gist
create file in lib/footer.rb
class Footer < ActiveAdmin::Component
def build
super :id => "footer"
span "My Awesome footer"
end
end
add to initializers/active_admin.rb
ActiveAdmin.setup do |config|
......some config here....
config.view_factory.footer = Footer
......some config here....
end
Newer version of ActiveAdmin provides configurable option to set footer.
ActiveAdmin Footer Customization
config.footer = "MyApp Revision v1.3"
Footer can be configured using proc, where you can even render partial.
ActiveAdmin Footer Customization using proc
config.footer = proc { "Enjoy MyApp Revision 123, #{controller.current_admin_user.try(:email)}!" }
PR which added the ability to customize the footer
I have on the homepage list of articles that are listed with using will_paginate gem.
Everything works well, but there is one thing I would want to improve - on the homepage, the data are loaded into home controller and index action.
So, when I load my website - www.website.com, data are loaded into home/index. When I click on the pagination link for the second page, the link is www.website.com/home/index?page=2. I would like to see there in the best way www.website.com/page/2 (or www.website.com/?page=2).
Basically, the point is to remove from the URL /home/index - is there any way to do this?
Thanks
You may do it this way - add this class to some helper module, for example app/helpers/application_helper.rb:
module ApplicationHelper
class SmartLinkRenderer < WillPaginate::ActionView::LinkRenderer
protected
def link(text, target, attributes = {})
if target.is_a? Fixnum
attributes[:rel] = rel_value(target)
target = url(target)
end
attributes[:href] = target.gsub(/[?&]page=(\d+)/,'/page/\1')
tag(:a, text, attributes)
end
end
end
You may customize it according to your needs, for example do
attributes[:href] = target.gsub(/home\/index/,'')
or whatever. And then you may do this in your views:
<%= will_paginate #items, :renderer => 'ApplicationHelper::SmartLinkRenderer' %>
Try this
root to: 'home#index'
in you config/routes.rb file
EDIT
to be able to route these kind of requests:
www.website.com/page/2
add this to routes.rb:
match "page/:page" => "your_root_controller#index"
this way :page will be in your params hash.
and for example index method to view your Message model can be:
def index
#messages = Messages.paginate(page: params[:page])
end
hope that can help. for more information please refer to RoR routing
I am working with ActiveAdmin and need to make customizations to some views and have come across a couple of scenarios I feel I am doing wrong.
I am adding an additional table to a show view (comments on Posts). This requires me to rewrite the whole attributes table and then add my panel. Is there a way to customize views without losing the default content?
I would also like to add a table of associated items on the show view which doesn't need to be customized is there any way to include the default tale that would normally be on the index view with default actions and paging?
After digging in the source code of Active Admin, I've found a way to patch this
show do
default_main_content
panel "Your Added Stuff" do
# Add stuff here
end
end
Of course this is undocumented and maybe considered a hack, but unless any other solution exists, it works.
Note: To do this in the form action (new and edit):
form do |f|
f.inputs
# Other inputs here
f.actions
end
Instead of using default_main_content, you could also just loop through the columns on the model like so:
ActiveAdmin.register Ad do
show do
attributes_table do
default_attribute_table_rows.each do |field|
row field
end
# Custom bits here
end
end
end
A couple areas of the documentation might help you:
See Customize the Show Page, Customizing the Index Page, Customizing the Form, and Custom Pages. An example of customizing a show screen:
ActiveAdmin.register Ad do
show do |ad|
default_main_content
h3 ad.title
end
end
See Custom Action Items in the Custom Controller Actions section of the documentation. An example:
action_item :only => :show, :if => proc{ current_admin_user.super_admin? } do
"Only display this to super admins on the show screen"
end
NB default_main_content does not exist in the documentation anymore, yet it works fine.
Just figured that out myself:
For the default table index page you can do something like this
index do
h1 "Hello World"
p "get more content"
instance_eval(&default_table)
end
.js.erb's are nice, because you can use them to replace parts of a page without having to leave the current page, which gives a cleaner and unchopped up feel to the site / app.
Is there a way to use them in sinatra? or an equivalent?
Just add .js to the end of the symbol you're passing erb(). A la (to call mypage.js.erb):
erb "mypage.js".to_sym
Dirty, but it works.
Based on your description, I'm guessing that your desire is to have portions of a page editable and replaced via AJAX. If this is wrong, please clarify.
I do this in my Sinatra apps by including (my own) AJAXFetch jQuery library and writing code as shown below. This lets me use the partial both when rendering the page initially as well as when editing via AJAX, for maximum DRYness. The AJAXFetch library handles all AJAX fetch/swap through markup alone, without needing to write custom JS on the pages that use it.
helpers/partials.rb
require 'sinatra/base'
module Sinatra
module PartialPartials
ENV_PATHS = %w[ REQUEST_PATH PATH_INFO REQUEST_URI ]
def spoof_request( uri, headers=nil )
new_env = env.dup
ENV_PATHS.each{ |k| new_env[k] = uri.to_s }
new_env.merge!(headers) if headers
call( new_env ).last.join
end
def partial( page, variables={} )
haml page, {layout:false}, variables
end
end
helpers PartialPartials
end
routes/bug.rb
get '/bug/:bug_id' do
if #bug = Bug[params[:bug_id]]
# ...
haml :bug
end
end
# Generate routes for each known partial
partials = %w[ bugdescription bughistory bugtitle fixer
pain project relatedbugs status tags version votes ]
partials.each do |part|
[ part, "#{part}_edit" ].each do |name|
get "/partial/#{name}/:bug_id" do
id = params[:bug_id]
login_required
halt 404, "(no bug ##{id})" unless #bug = Bug[id]
partial :"_#{name}"
end
end
end
post "/update_bug/:partial" do
id = params[:bug_id]
unless params['cancel']=='cancel'
# (update the bug based on fields)
#bug.save
end
spoof_request "/partial/#{params[:partial]}/#{id}", 'REQUEST_METHOD'=>'GET'
end
views/bug.haml
#main
#bug.section
= partial :_bugtitle
.section-body
= partial :_bugdescription
<!-- many more partials used -->
views/_bugtitle.haml
%h1.ajaxfetch-andswap.editable(href="/partial/bugtitle_edit/#{#bug.pk}")= title
views/_bugtitle_edit.haml
%form.ajaxfetch-andswap(method='post' action='/update_bug/bugtitle')
%input(type="hidden" name="bug_id" value="#{#bug.id}")
%h1
%input(type="text" name="name" value="#{h #bug.name}")
%span.edit-buttons
%button(type="submit") update
%button(type="submit" name="cancel" value="cancel") cancel
sinatra really isn't meant to be a full stack framework. Its supposed to get you on the road very quickly. You could use an erb separately and then load into your sinatra code.