Commit 30560212d346829cc52ebdc98037c18a2b95014b

Authored by Antonio Terceiro
1 parent 6b634fbb

Support running Noosfero as a /subdirectory

- Remove absolute URL's from stylesheets and javascripts
- Handle prefix in LinkListBlock
- add Noosfero.root method as a central data source

The application server needs to be started with the
RAILS_RELATIVE_URL_ROOT environment variable set to the desired prefix.

In development, this can be tested with

  # assuming /social prefix
  $ RAILS_RELATIVE_URL_ROOT=/social thin --prefix /social start

For production, see INSTALL.md
INSTALL.md
... ... @@ -186,8 +186,8 @@ Apache instalation
186 186  
187 187 # apt-get install apache2
188 188  
189   -Apache configuration
190   ---------------------
  189 +Configuration - noosfero at /
  190 +-----------------------------
191 191  
192 192 First you have to enable the following some apache modules:
193 193  
... ... @@ -257,6 +257,62 @@ Now restart your apache server (as root):
257 257  
258 258 # invoke-rc.d apache2 restart
259 259  
  260 +Configuration - noosfero at a /subdirectory
  261 +-------------------------------------------
  262 +
  263 +This section describes how to configure noosfero at a subdirectory, what is
  264 +specially useful when you want Noosfero to share a domain name with other
  265 +applications. For example you can host noosfero at yourdomain.com/social, a
  266 +webmail application at yourdomain.com/webmail, and have a static HTML website
  267 +at yourdomain.com/.
  268 +
  269 +**NOTE:** Some plugins might not work well with this setting. Before deploying
  270 +this setting, make sure you test that everything you need works properly with
  271 +it.
  272 +
  273 +The configuration is similar to the main configuration instructions, except for
  274 +the following points. In the description below, replace '/subdirectory' with
  275 +the actual subdirectory you want.
  276 +
  277 +1) add a `prefix: /subdirectory` line to your thin configuration file (thin.yml).
  278 +
  279 +1.1) remember to restart the noosfero application server whenever you make
  280 +changes to that configuration file.
  281 +
  282 + # service noosfero restart
  283 +
  284 +2) add a line saying `export RAILS_RELATIVE_URL_ROOT=/subdirectory` to
  285 +/etc/default/noosfero (you can create it with just this line if it does not
  286 +exist already).
  287 +
  288 +3) You should add the following apache configuration to an existing virtual
  289 +host (plus the `<Proxy balancer://noosfero>` section as displayed above):
  290 +
  291 +```
  292 +Alias /subdirectory /path/to/noosfero/public
  293 +<Directory "/path/to/noosfero/public">
  294 + Options FollowSymLinks
  295 + AllowOverride None
  296 + Order Allow,Deny
  297 + Allow from all
  298 +
  299 + Include /path/to/noosfero/etc/noosfero/apache/cache.conf
  300 +
  301 + RewriteEngine On
  302 + RewriteBase /subdirectory
  303 + # Rewrite index to check for static index.html
  304 + RewriteRule ^$ index.html [QSA]
  305 + # Rewrite to check for Rails cached page
  306 + RewriteRule ^([^.]+)$ $1.html [QSA]
  307 + RewriteCond %{REQUEST_FILENAME} !-f
  308 + RewriteRule ^(.*)$ http://localhost:3000%{REQUEST_URI} [P,QSA,L]
  309 +</Directory>
  310 +```
  311 +
  312 +3.1) remember to reload the apache server whenever any apache configuration
  313 +file changes.
  314 +
  315 + # sudo service apache2 reload
260 316  
261 317 Enabling exception notifications
262 318 ================================
... ...
app/models/environment.rb
... ... @@ -660,6 +660,7 @@ class Environment &lt; ActiveRecord::Base
660 660 url = 'http://'
661 661 url << (Noosfero.url_options.key?(:host) ? Noosfero.url_options[:host] : default_hostname)
662 662 url << ':' << Noosfero.url_options[:port].to_s if Noosfero.url_options.key?(:port)
  663 + url << Noosfero.root('')
663 664 url
664 665 end
665 666  
... ...
app/models/link_list_block.rb
... ... @@ -78,8 +78,13 @@ class LinkListBlock &lt; Block
78 78 address
79 79 end
80 80 if add !~ /^[a-z]+:\/\// && add !~ /^\//
81   - 'http://' + add
  81 + '//' + add
82 82 else
  83 + if root = Noosfero.root
  84 + if !add.starts_with?(root)
  85 + add = root + add
  86 + end
  87 + end
83 88 add
84 89 end
85 90 end
... ... @@ -96,4 +101,5 @@ class LinkListBlock &lt; Block
96 101 sanitizer = HTML::WhiteListSanitizer.new
97 102 sanitizer.sanitize(text)
98 103 end
  104 +
99 105 end
... ...
app/views/layouts/application-ng.html.erb
... ... @@ -19,6 +19,9 @@
19 19 <meta property="og:site_name" content="<%= profile ? profile.name : @environment.name %>">
20 20 <meta property="og:description" content="<%= @page ? truncate(strip_tags(@page.body.to_s), :length => 200) : @environment.name %>">
21 21  
  22 + <!-- site root -->
  23 + <meta property="noosfero:root" content="<%= Noosfero.root %>"/>
  24 +
22 25 <% if @page %>
23 26 <meta property="article:published_time" content="<%= show_date(@page.published_at) %>">
24 27 <% @page.body_images_paths.each do |img| %>
... ...
lib/noosfero.rb
... ... @@ -3,6 +3,10 @@
3 3 require 'fast_gettext'
4 4 module Noosfero
5 5  
  6 + def self.root(default = nil)
  7 + ENV.fetch('RAILS_RELATIVE_URL_ROOT', default)
  8 + end
  9 +
6 10 def self.pattern_for_controllers_in_directory(dir)
7 11 disjunction = controllers_in_directory(dir).join('|')
8 12 pattern = disjunction.blank? ? '' : ('(' + disjunction + ')')
... ...
public/designs/icons/tango/style.css
... ... @@ -106,7 +106,7 @@
106 106 .icon-activate-user { background-image: url(Tango/16x16/emblems/emblem-system.png) }
107 107 .icon-deactivate-user { background-image: url(Tango/16x16/emblems/emblem-unreadable.png) }
108 108 .icon-set-admin-role { background-image: url(mod/16x16/apps/user.png) }
109   -.icon-reset-admin-role { background-image: url(/images/icons-app/person-icon.png) }
  109 +.icon-reset-admin-role { background-image: url(../../../images/icons-app/person-icon.png) }
110 110 .icon-clock { background-image: url(Tango/16x16/actions/appointment.png) }
111 111  
112 112 /******************LARGE ICONS********************/
... ...
public/designs/templates/leftbar/stylesheets/style.css
... ... @@ -41,7 +41,7 @@
41 41 }
42 42  
43 43 .profile-activity-article-forum .profile-activity-lead {
44   - background: url(/images/forum-activity-bg-onecol.png);
  44 + background: url(../../../../images/forum-activity-bg-onecol.png);
45 45 width: 489px;
46 46 }
47 47  
... ...
public/designs/templates/rightbar/stylesheets/style.css
... ... @@ -41,7 +41,7 @@
41 41 }
42 42  
43 43 .profile-activity-article-forum .profile-activity-lead {
44   - background: url(/images/forum-activity-bg-onecol.png);
  44 + background: url(../../../..//images/forum-activity-bg-onecol.png);
45 45 width: 489px;
46 46 }
47 47  
... ...
public/designs/themes/base/style.css
... ... @@ -257,7 +257,7 @@ body, th, td, input {
257 257 }
258 258  
259 259 #navigation .menu-submenu-trigger {
260   - background: #eee url(/images/down-arrow.png) center center no-repeat;
  260 + background: #eee url(../../../images/down-arrow.png) center center no-repeat;
261 261 border: 0px;
262 262 height: 8px;
263 263 width: 124px;
... ... @@ -1220,28 +1220,28 @@ hr.pre-posts, hr.sep-posts {
1220 1220 }
1221 1221  
1222 1222 .comment-from-owner .comment-wrapper-1 {
1223   - background: #fbf7b5 url(/images/comment-owner-bg-N.png) repeat-x;
  1223 + background: #fbf7b5 url(../../../images/comment-owner-bg-N.png) repeat-x;
1224 1224 }
1225 1225 .comment-from-owner .comment-wrapper-2 {
1226   - background: url(/images/comment-owner-bg-S.png) 0% 100% repeat-x;
  1226 + background: url(../../../images/comment-owner-bg-S.png) 0% 100% repeat-x;
1227 1227 }
1228 1228 .comment-from-owner .comment-wrapper-3 {
1229   - background: url(/images/comment-owner-bg-L.png) 100% 0% repeat-y;
  1229 + background: url(../../../images/comment-owner-bg-L.png) 100% 0% repeat-y;
1230 1230 }
1231 1231 .comment-from-owner .comment-wrapper-4 {
1232   - background: url(/images/comment-owner-bg-O.png) 0% 0% repeat-y;
  1232 + background: url(../../../images/comment-owner-bg-O.png) 0% 0% repeat-y;
1233 1233 }
1234 1234 .comment-from-owner .comment-wrapper-5 {
1235   - background: url(/images/comment-owner-bg-SL.png) 100% 100% no-repeat;
  1235 + background: url(../../../images/comment-owner-bg-SL.png) 100% 100% no-repeat;
1236 1236 }
1237 1237 .comment-from-owner .comment-wrapper-6 {
1238   - background: url(/images/comment-owner-bg-SO.png) 0% 100% no-repeat;
  1238 + background: url(../../../images/comment-owner-bg-SO.png) 0% 100% no-repeat;
1239 1239 }
1240 1240 .comment-from-owner .comment-wrapper-7 {
1241   - background: url(/images/comment-owner-bg-NL.png) 100% 0% no-repeat;
  1241 + background: url(../../../images/comment-owner-bg-NL.png) 100% 0% no-repeat;
1242 1242 }
1243 1243 .comment-from-owner .comment-wrapper-8 {
1244   - background: url(/images/comment-owner-bg-NO.png) 0% 0% no-repeat;
  1244 + background: url(../../../images/comment-owner-bg-NO.png) 0% 0% no-repeat;
1245 1245 }
1246 1246  
1247 1247 .comment-created-at {
... ...
public/javascripts/application.js
... ... @@ -5,6 +5,14 @@ function noosfero_init() {
5 5 // focus_first_field(); it is moving the page view when de form is down.
6 6 }
7 7  
  8 +var __noosfero_root = null;
  9 +function noosfero_root() {
  10 + if (__noosfero_root == null) {
  11 + __noosfero_root = jQuery('meta[property="noosfero:root"]').attr("content") || '';
  12 + }
  13 + return __noosfero_root;
  14 +}
  15 +
8 16 /* If applicable, find the first field in which the user can type and move the
9 17 * keyboard focus to it.
10 18 *
... ... @@ -167,7 +175,7 @@ function loading_done(element_id) {
167 175 jQuery(element_id).removeClass('small-loading-dark');
168 176 }
169 177 function open_loading(message) {
170   - jQuery('body').prepend("<div id='overlay_loading' class='ui-widget-overlay' style='display: none'/><div id='overlay_loading_modal' style='display: none'><p>"+message+"</p><img src='/images/loading-dark.gif'/></div>");
  178 + jQuery('body').prepend("<div id='overlay_loading' class='ui-widget-overlay' style='display: none'/><div id='overlay_loading_modal' style='display: none'><p>"+message+"</p><img src='" + noosfero_root() + "/images/loading-dark.gif'/></div>");
171 179 jQuery('#overlay_loading').show();
172 180 jQuery('#overlay_loading_modal').center();
173 181 jQuery('#overlay_loading_modal').fadeIn('slow');
... ... @@ -515,11 +523,12 @@ jQuery(function($) {
515 523 }
516 524 });
517 525  
518   - $.getJSON('/account/user_data', function userDataCallBack(data) {
  526 + var user_data = noosfero_root() + '/account/user_data';
  527 + $.getJSON(user_data, function userDataCallBack(data) {
519 528 if (data.login) {
520 529 // logged in
521 530 if (data.chat_enabled) {
522   - setInterval(function(){ $.getJSON('/account/user_data', chatOnlineUsersDataCallBack)}, 10000);
  531 + setInterval(function(){ $.getJSON(user_data, chatOnlineUsersDataCallBack)}, 10000);
523 532 }
524 533 $('head').append('<meta content="authenticity_token" name="csrf-param" />');
525 534 $('head').append('<meta content="'+$.cookie("_noosfero_.XSRF-TOKEN")+'" name="csrf-token" />');
... ... @@ -600,7 +609,7 @@ function display_notice(message) {
600 609  
601 610 function open_chat_window(self_link, anchor) {
602 611 anchor = anchor || '#';
603   - var noosfero_chat_window = window.open('/chat' + anchor,'noosfero_chat','width=900,height=500');
  612 + var noosfero_chat_window = window.open(noosfero_root() + '/chat' + anchor,'noosfero_chat','width=900,height=500');
604 613 noosfero_chat_window.focus();
605 614 return false;
606 615 }
... ...
public/javascripts/lightbox.js
... ... @@ -221,7 +221,7 @@ function addLightboxMarkup() {
221 221 lb.id = 'lightbox';
222 222 lb.className = 'loading';
223 223 lb.innerHTML = '<div id="lbLoadMessage">' +
224   - '<img src="/images/loading.gif"/>' +
  224 + '<img src="' + noosfero_root() + '/images/2loading.gif"/>' +
225 225 '</div>';
226 226 bod.appendChild(overlay);
227 227 bod.appendChild(lb);
... ...
public/javascripts/thickbox.js
... ... @@ -13,7 +13,7 @@ var tb_pathToImage = &quot;/images/loading.gif&quot;;
13 13 jQuery(document).ready(function(){
14 14 tb_init('a.thickbox, area.thickbox, input.thickbox');//pass where to apply thickbox
15 15 imgLoader = new Image();// preload image
16   - imgLoader.src = tb_pathToImage;
  16 + imgLoader.src = noosfero_root() + tb_pathToImage;
17 17 });
18 18  
19 19 //add thickbox to href & area elements that have a class of .thickbox
... ...
public/stylesheets/application.css
... ... @@ -1047,7 +1047,7 @@ code input {
1047 1047 width: 100%;
1048 1048 height: 16px;
1049 1049 text-align: left;
1050   - background: transparent url(/images/black-alpha-pixel.png);
  1050 + background: transparent url(../images/black-alpha-pixel.png);
1051 1051 border-bottom: 1px solid #333;
1052 1052 text-decoration: none;
1053 1053 }
... ... @@ -1065,7 +1065,7 @@ code input {
1065 1065 padding-left: 16px;
1066 1066 border-bottom: 1px solid #eee;
1067 1067 display: block;
1068   - background: transparent url(/images/zoom.png) left center no-repeat;
  1068 + background: transparent url(../images/zoom.png) left center no-repeat;
1069 1069 color: #fff;
1070 1070 }
1071 1071 #article pre {
... ... @@ -1257,7 +1257,7 @@ a.comment-picture {
1257 1257 background: transparent;
1258 1258 }
1259 1259 .comment-replies .comment-from-owner.comment-content {
1260   - background: transparent url(/images/comment-reply-owner-bg.png) left bottom repeat-x;
  1260 + background: transparent url(../images/comment-reply-owner-bg.png) left bottom repeat-x;
1261 1261 }
1262 1262 .comment-replies .comment-user-status {
1263 1263 top: 15px;
... ... @@ -1318,7 +1318,7 @@ a.comment-picture {
1318 1318 border: 1px solid #808080;
1319 1319 padding: 0;
1320 1320 margin-bottom: 10px;
1321   - background: transparent url(/images/black-alpha-pixel-5.png) left top repeat;
  1321 + background: transparent url(../images/black-alpha-pixel-5.png) left top repeat;
1322 1322 -moz-border-radius: 5px;
1323 1323 -webkit-border-radius: 5px;
1324 1324 border-radius: 5px;
... ... @@ -1527,7 +1527,7 @@ div.article-body p img {
1527 1527 /* NOT PUBLISHED BLOG POSTS */
1528 1528  
1529 1529 .blog-post.not-published {
1530   - background: url(/images/hachure.png);
  1530 + background: url(../images/hachure.png);
1531 1531 opacity: 0.25;
1532 1532 filter: alpha(opacity=25);
1533 1533 zoom: 1;
... ... @@ -1623,7 +1623,7 @@ body.noosfero a.button.with-text.icon-none, body.noosfero input.button.with-text
1623 1623 padding-left: 2px;
1624 1624 }
1625 1625 a.disabled{
1626   - filter: url(/filters.svg#grayscale); /* Firefox 3.5+ */
  1626 + filter: url(../filters.svg#grayscale); /* Firefox 3.5+ */
1627 1627 filter: gray; /* IE6-9 */
1628 1628 -webkit-filter: grayscale(1); /* Google Chrome & Safari 6+ */
1629 1629 cursor: default;
... ... @@ -1699,7 +1699,7 @@ a.button.disabled, input.disabled {
1699 1699 display: none;
1700 1700 }
1701 1701 .invisible-block {
1702   - background: url(/images/hachure.png);
  1702 + background: url(../images/hachure.png);
1703 1703 opacity: 0.25;
1704 1704 }
1705 1705 .msie .invisible-block {
... ... @@ -1914,7 +1914,7 @@ a.button.disabled, input.disabled {
1914 1914 width: 97%;
1915 1915 }
1916 1916 .link-list-row:hover {
1917   - background: #ddd url(/images/drag-and-drop.png) no-repeat;
  1917 + background: #ddd url(../images/drag-and-drop.png) no-repeat;
1918 1918 background-position: 98% 15px;
1919 1919 }
1920 1920 .link-list-row li {
... ... @@ -2007,7 +2007,7 @@ a.button.disabled, input.disabled {
2007 2007 }
2008 2008 #content .comment-header .comment-actions-reply {
2009 2009 float: right;
2010   - background-image: url(/designs/icons/tango/Tango/16x16/actions/go-jump.png);
  2010 + background-image: url(../designs/icons/tango/Tango/16x16/actions/go-jump.png);
2011 2011 height: 12px;
2012 2012 }
2013 2013 #content .comment-header ul {
... ... @@ -2104,13 +2104,13 @@ a.button.disabled, input.disabled {
2104 2104 height: 15px;
2105 2105 }
2106 2106 .common-profile-list-block .sex-male {
2107   - background: url(/images/icons-app/ico-male.png);
  2107 + background: url(../images/icons-app/ico-male.png);
2108 2108 }
2109 2109 .common-profile-list-block .sex-female {
2110   - background: url(/images/icons-app/ico-female.png);
  2110 + background: url(../images/icons-app/ico-female.png);
2111 2111 }
2112 2112 .common-profile-list-block .sex-undef {
2113   - background: url(/images/icons-app/ico-sex-undef.png);
  2113 + background: url(../images/icons-app/ico-sex-undef.png);
2114 2114 }
2115 2115 .msie6 .common-profile-list-block .sex-male {
2116 2116 background: none;
... ... @@ -2357,13 +2357,13 @@ div#activation_enterprise label, div#activation_enterprise input, div#activation
2357 2357 height: 15px;
2358 2358 }
2359 2359 .profile-info-picture .sex-male {
2360   - background: url(/images/icons-app/ico-male.png);
  2360 + background: url(../images/icons-app/ico-male.png);
2361 2361 }
2362 2362 .profile-info-picture .sex-female {
2363   - background: url(/images/icons-app/ico-female.png);
  2363 + background: url(../images/icons-app/ico-female.png);
2364 2364 }
2365 2365 .profile-info-picture .sex-undef {
2366   - background: url(/images/icons-app/ico-sex-undef.png);
  2366 + background: url(../images/icons-app/ico-sex-undef.png);
2367 2367 }
2368 2368 .msie6 .profile-info-picture .sex-male {
2369 2369 background: none;
... ... @@ -2805,7 +2805,7 @@ div#activation_enterprise label, div#activation_enterprise input, div#activation
2805 2805 font-size: 0.70em;
2806 2806 color: white;
2807 2807 font-weight: bold;
2808   - background: url(/images/catalog-expanders.png) no-repeat;
  2808 + background: url(../images/catalog-expanders.png) no-repeat;
2809 2809 display: block;
2810 2810 line-height: 15px;
2811 2811 background-position: left 100%;
... ... @@ -3844,7 +3844,7 @@ h1#agenda-title {
3844 3844 bottom: 5px;
3845 3845 position: absolute;
3846 3846 display: block;
3847   - background: transparent url(/images/loading-dark.gif) center center no-repeat;
  3847 + background: transparent url(../images/loading-dark.gif) center center no-repeat;
3848 3848 }
3849 3849 /* hide the close x on the loading screen */
3850 3850 .controller-invite .ui-dialog-titlebar-close {
... ... @@ -3860,7 +3860,7 @@ h1#agenda-title {
3860 3860 border: 1px solid #AABB88;
3861 3861 -moz-border-radius: 5px;
3862 3862 -webkit-border-radius: 5px;
3863   - background: url(/images/ccc.gif); /* image ccc.gif from http://www.wannabegirl.org/translucent */
  3863 + background: url(../images/ccc.gif); /* image ccc.gif from http://www.wannabegirl.org/translucent */
3864 3864 padding: 10px 30px 20px 30px;
3865 3865 }
3866 3866 #categories_container_wrapper {
... ... @@ -3869,7 +3869,7 @@ h1#agenda-title {
3869 3869 padding: 5px;
3870 3870 -moz-border-radius: 3px;
3871 3871 -webkit-border-radius: 3px;
3872   - background: url(/images/fff.gif); /* image fff.gif from http://www.wannabegirl.org/translucent */
  3872 + background: url(../images/fff.gif); /* image fff.gif from http://www.wannabegirl.org/translucent */
3873 3873 border: 1px solid #CCC;
3874 3874 border-bottom: 0;
3875 3875 position: relative;
... ... @@ -4668,7 +4668,7 @@ h1#agenda-title {
4668 4668 position: absolute;
4669 4669 bottom: 0;
4670 4670 z-index: 2;
4671   - background: transparent url(/images/black-alpha-pixel.png);
  4671 + background: transparent url(../images/black-alpha-pixel.png);
4672 4672 color: #fff;
4673 4673 text-decoration: none;
4674 4674 display: block;
... ... @@ -4750,10 +4750,10 @@ h1#agenda-title {
4750 4750 display: none;
4751 4751 }
4752 4752 .featured-product-prev {
4753   - background-image: url(/designs/icons/tango/Tango/16x16/actions/go-previous.png);
  4753 + background-image: url(../designs/icons/tango/Tango/16x16/actions/go-previous.png);
4754 4754 }
4755 4755 .featured-product-next {
4756   - background-image: url(/designs/icons/tango/Tango/16x16/actions/go-next.png);
  4756 + background-image: url(../designs/icons/tango/Tango/16x16/actions/go-next.png);
4757 4757 }
4758 4758 .featured-products-block-container {
4759 4759 width: 92%;
... ... @@ -4882,14 +4882,14 @@ h1#agenda-title {
4882 4882 top: -1px;
4883 4883 left: -3px;
4884 4884 overflow: hidden;
4885   - background: #efefef url(/images/top-arrow.png) center center no-repeat;
  4885 + background: #efefef url(../images/top-arrow.png) center center no-repeat;
4886 4886 border: 1px solid #ccc;
4887 4887 z-index: 2;
4888 4888 -moz-border-radius: 5px;
4889 4889 -webkit-border-radius: 5px;
4890 4890 }
4891 4891 .common-profile-list-block .vcard .menu-submenu-trigger:hover, .menu-submenu-trigger:hover, .comment-actions .vcard .menu-submenu-trigger:hover {
4892   - background: #fff url(/images/top-arrow.png) center center no-repeat;
  4892 + background: #fff url(../images/top-arrow.png) center center no-repeat;
4893 4893 border: 1px solid #ccc;
4894 4894 }
4895 4895 .menu-submenu-trigger span {
... ... @@ -4916,17 +4916,17 @@ h1#agenda-title {
4916 4916 right: -44px;
4917 4917 }
4918 4918 .menu-submenu-footer {
4919   - background: transparent url(/images/balloon-footer.png) center center no-repeat;
  4919 + background: transparent url(../images/balloon-footer.png) center center no-repeat;
4920 4920 height: 29px;
4921 4921 margin: 0;
4922 4922 }
4923 4923 .menu-submenu-header {
4924   - background: transparent url(/images/balloon-header.png) center center no-repeat;
  4924 + background: transparent url(../images/balloon-header.png) center center no-repeat;
4925 4925 height: 17px;
4926 4926 margin: 0;
4927 4927 }
4928 4928 .menu-submenu-content {
4929   - background: transparent url(/images/balloon-middle.png) top left repeat-y;
  4929 + background: transparent url(../images/balloon-middle.png) top left repeat-y;
4930 4930 margin: 0;
4931 4931 padding: 0;
4932 4932 width: 100%;
... ... @@ -5034,7 +5034,7 @@ h1#agenda-title {
5034 5034 height: 25px;
5035 5035 width: 100%;
5036 5036 position: absolute;
5037   - background: #ccc url(/images/icons-app/chat-22x22.png) 2px 2px no-repeat;
  5037 + background: #ccc url(../images/icons-app/chat-22x22.png) 2px 2px no-repeat;
5038 5038 }
5039 5039 #title-bar .title {
5040 5040 margin: 0;
... ... @@ -5280,7 +5280,7 @@ h1#agenda-title {
5280 5280 padding-left: 60px;
5281 5281 float: none;
5282 5282 overflow: hidden;
5283   - background: transparent url(/images/forum-activity-bg.png) left center no-repeat;
  5283 + background: transparent url(../images/forum-activity-bg.png) left center no-repeat;
5284 5284 }
5285 5285  
5286 5286 .profile-activity-article-forum .see-forum {
... ... @@ -5288,7 +5288,7 @@ h1#agenda-title {
5288 5288 }
5289 5289  
5290 5290 .profile-activity-article-forum .see-forum a {
5291   - background: transparent url(/images/forum-activity-icon.png) left center no-repeat;
  5291 + background: transparent url(../images/forum-activity-icon.png) left center no-repeat;
5292 5292 padding-left: 30px;
5293 5293 font-weight: bold;
5294 5294 color: #dadada !important;
... ... @@ -6263,7 +6263,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6263 6263  
6264 6264 #signup-form .invalid {
6265 6265 border-color: #7f0000;
6266   - background-image: url(/images/passwords_nomatch.png);
  6266 + background-image: url(../images/passwords_nomatch.png);
6267 6267 box-shadow: 0 0 7px red;
6268 6268 }
6269 6269  
... ... @@ -6277,7 +6277,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6277 6277  
6278 6278 #signup-form .checking {
6279 6279 border-color: #4A4A4A;
6280   - background-image: url(/images/login_checking.png);
  6280 + background-image: url(../images/login_checking.png);
6281 6281 }
6282 6282  
6283 6283 #signup-form span.checking {
... ... @@ -6290,7 +6290,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6290 6290  
6291 6291 #signup-form .validated {
6292 6292 border-color: #005000;
6293   - background-image: url(/images/passwords_match.png);
  6293 + background-image: url(../images/passwords_match.png);
6294 6294 }
6295 6295  
6296 6296 #signup-form span.validated {
... ... @@ -6348,7 +6348,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6348 6348 padding: 5px 10px 45px 10px;
6349 6349 margin: 0;
6350 6350 line-height: 1.5em;
6351   - background: transparent url(/images/gray-balloon.png) bottom center no-repeat;
  6351 + background: transparent url(../images/gray-balloon.png) bottom center no-repeat;
6352 6352 position: absolute;
6353 6353 z-index: 2;
6354 6354 right: -150px;
... ... @@ -6410,7 +6410,7 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
6410 6410 #content #signup-form .submit {
6411 6411 border: 0;
6412 6412 padding: 8px 36px 12px;
6413   - background: transparent url(/images/gray-bg.png) left center repeat-x;
  6413 + background: transparent url(../images/gray-bg.png) left center repeat-x;
6414 6414 font-size: 17px;
6415 6415 color: #FFF;
6416 6416 text-align: center;
... ...
public/stylesheets/filters.svg 0 → 120000
... ... @@ -0,0 +1 @@
  1 +../filters.svg
0 2 \ No newline at end of file
... ...
public/stylesheets/iepngfix/iepngfix.css
1   -img { behavior: url(/stylesheets/iepngfix/iepngfix.htc) }
  1 +img { behavior: url(iepngfix.htc) }
... ...
test/unit/link_list_block_test.rb
... ... @@ -65,6 +65,18 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase
65 65 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => '/address'}
66 66 end
67 67  
  68 + should 'handle /prefix if not already added' do
  69 + Noosfero.stubs(:root).returns('/prefix')
  70 + l = LinkListBlock.new(:links => [{:name => "foo", :address => '/bar'}] )
  71 + assert_tag_in_string l.content, :tag => 'a', :attributes => { :href => '/prefix/bar' }
  72 + end
  73 +
  74 + should 'not add /prefix if already there' do
  75 + Noosfero.stubs(:root).returns('/prefix')
  76 + l = LinkListBlock.new(:links => [{:name => "foo", :address => '/prefix/bar'}] )
  77 + assert_tag_in_string l.content, :tag => 'a', :attributes => { :href => '/prefix/bar' }
  78 + end
  79 +
68 80 should 'display options for icons' do
69 81 l = LinkListBlock.new
70 82 l.icons_options.each do |option|
... ... @@ -92,8 +104,8 @@ class LinkListBlockTest &lt; ActiveSupport::TestCase
92 104 assert_no_tag_in_string l.link_html(l.links.first), :attributes => { :onclick => /.*/ }
93 105 end
94 106  
95   - should 'add http in front of incomplete external links' do
96   - {'/local/link' => '/local/link', 'http://example.org' => 'http://example.org', 'example.org' => 'http://example.org'}.each do |input, output|
  107 + should 'add protocol in front of incomplete external links' do
  108 + {'/local/link' => '/local/link', 'http://example.org' => 'http://example.org', 'example.org' => '//example.org'}.each do |input, output|
97 109 l = LinkListBlock.new(:links => [{:name => 'categ', :address => input}])
98 110 assert_tag_in_string l.content, :tag => 'a', :attributes => {:href => output}
99 111 end
... ...