system76 / beansbooks

A revolutionary cloud accounting platform designed for small and medium businesses.
129 stars 36 forks source link

Put BeansBooks into a subdirectory, like www.example.com/beansbooks #238

Open Elyrith opened 9 years ago

Elyrith commented 9 years ago

Is there a way to put BeansBooks into a subdirectory properly? I'm assuming it's going to require something in .htaccess but I'm stumped.

Goal: Instead of example.com. I want to access my BeansBooks instance at example.com/beansbooks. I've got Apache set up (alias config below), but when I got to example.com/beansbooks I just get a BeansBooks 404 page with no style and all the links and images point to /dash and /customers instead of /beansbooks/dash.

(The reason I want to do this is that I have an SSL certificate for mydomain.com and I put things like this in aliased subfolders so I can use the same SSL certificate for things like this and ownCloud.)

The best I could figure out is putting this right after the RewriteEngine On line: (but it's not working for me)

RewriteCond %{REQUEST_URI} !^/beansbooks
RewriteRule ^(/?)(.*) /beansbooks/$2

Here's my Apache alias file in my virtual host:

Alias /beansbooks /path/to/beansbooks
<Directory /path/to/beansbooks>
    Options FollowSymLinks
    AllowOverride All
    Require all granted
</Directory>

This same Apache configuration works for MantisBT (bug tracker), ownCloud (cloud storage), LimeSurvey (surveys), phpmyadmin, and a bunch of other things, but for some reason BeansBooks insists on being at the root. When I put this exact same BeansBooks instance at the root of a domain (example2.com, same file system path and permissions) everything works flawlessly, so I know the files and database are all set up.

The reason I think a redirect in .htaccess is the correct answer for now is because many of the links are hard-coded, for instance the masthead_links in /application/classes/view/template.php.

I'm just a beginning programmer, but I think a long-term fix would be to make the links relative (for instance, have a config variable $root and add that to the beginning of all links that start with a backslash). If somebody smarter than me agrees, I can take some time and try to do that myself.

(On the other hand, am I way off-base with all of this?)

funnylookinhat commented 9 years ago

Hi @Elyrith -

So this is actually a pretty non-standard implementation to make in a SASS platform at this stage of the game. I know a couple of other applications that float out there ( like PHPMyAdmin ) use this sort of technique to create a virtual host in their post-install, but most platforms at this point are assuming a single root directory.

Your evaluation is correct though - the code would need to define a root directory and apply that to all of the URLs throughout the codebase. This could be a bit challenging as there are some URLs in the Javascript as well as template files - you would need to pass that variable along to the templates in a hidden input or attribute and then parse it when making any AJAX requests.

Your solution of using a rewrite within the .htaccess file won't work because those rules won't get hit until the source folder of the application is the active target for the request. Using some sort of $rootdir variable would be the best way to implement this - but it would get a bit gnarly because there are URLs coded both into the HTML templates and Javascript files.

I'm going to leave this issue open and re-categorize it to see if anyone else would potentially need it - thus far we haven't had any other requests for it, but I definitely understand your use case. Our solution to this problem was to use a wildcard SSL certificate so that we could put as many unique sub-domains as necessary on the same SSL cert.

MrJamesEllis commented 9 years ago

I'd 2nd the Wildcard SSL on a subdomain, they are cheap-as-chips nowadays and can be used on every subdomain.

michae1ho11ey commented 8 years ago

I'd love to see support for the software under a root directory (example.com/beansbooks). I currently have my site https://backoffice.example.com and I'm installing all of my back end tools as sub directories to make it easier to manage. So far SugarCRM, DokuWiki, WordPress, RoundCube, and others haven't complained about this arrangement. Can the code just use relative paths instead of hard paths, or look for a variable of what the root path is? I think that is how WordPress does it. Just saying it would be nice.

funnylookinhat commented 8 years ago

So - there are two ways to do this. Either we would have to convert every URL to a relative path and add a base tag to each page with the root path, or we prepend each link and reference with the root path. We'd have to just add the root path value to the config.php file and then go from there.

I tend to shy away from using the <base href="____" /> tag as they end up creating non-canonical URLs - so I would opt for the latter solution where every URL is prefixed with some site root directory.

If someone wants to submit a PR with support for adding a prefix to every URL in each template - e.g. <a href="{{url_base}}/customers/sales/{{id}}"> - we'd be more than happy to review it and work to merge it in.

[Edit] - I should clarify. That means that we would reject a PR that attempted to just use the <base /> tag.

cdp1337 commented 8 years ago

@funnylookinhat you are correct in assuming that every instance of the path would need a url_base, and that's exactly what we ended up fixing in our fork of the project. Unfortunately we also changed Kohana and virtually every other file of the project to correct some CamelCase issues that presented themselves when upgrading the framework, so I'm not sure how effective a PR would be.

Oh yeah, we also had to go through the javsacript and set the prefix there as well.

funnylookinhat commented 8 years ago

@cdp1337 Yeah - good points.

I think it'd be better if the views delivered a JS base_path that could be referenced by every file - it could even just be an attribute on the <body> tag.

cdp1337 commented 8 years ago

What I did is have a snippet in layout.mustache that's

<script>
            window.ROOT_WDIR = "{{root_wdir}}";
        </script>

Then in the javascript files,

$.ajax(ROOT_WDIR + 'customer/json/action'...);

And then yeah, in View.php, I'm adding that variable to every template on a global level.

There are also a few parts in the controllers that you have to keep an eye out for; they create the tabbed navigation and have some logic to determine what's currently selected, those need to be base_dir aware.

AND also the bootstrap needs modified with logic that can self-determine the current application's path. (All this work is now visible on my fork for your reference.)