What is best way to handle multiple *sub* sites?

i have got this website structure:

Homepage (template 1)
How it works (template 1)

API (template 2)
Documentation (template 3)
Forum (template 4)

so i need different system.yaml and site.yaml for make this; what is the best practice to do that?

i’m still stuck on this.
i’ve tried everything to use multiple theme, but nothing, i’m unable to make it work.

For example, i have in the same structure learn template and antimatter template and i’m only able to have got only one at once working (by setting it inside system.yam)

this is the error:
The template file for this page: “chapter.html.twig” is not provided by the theme: “Antimatter”

found the answer!
Grav can handle only one single theme for site.
So, i will have to create another full installation (basic a directory copy) and work on that, i will try now :slight_smile:

It’s possible to have a git repo containing grav, and symlink it. There are some docs on how to do this on this site, but the docs are not very clear. I was able to do this with plugins, and when you do a bin.gpm install xxx, it will ask if you want to downlod or use a symlink.

Hi @shakisha, there are many ways to setup a multi-site page. If each of your websites have its own subdomain, then you can make use of environment configurations and set your theme there.

If your structure is based on subfolders, then you may try out Themer plugin and setup collections for each of your pages (read the docs or more on usage here).

If you want to setup your own multi-site environment with different page folders for each website, then you may stick to adding a setup.php at the root of your Grav install with the following contents

<?php 
use Grav\Common\Filesystem\Folder;

// Get relative path from Grav root.
$path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : Folder::getRelativePath($_SERVER['REQUEST_URI'], dirname($_SERVER['SCRIPT_NAME']));
$first = Folder::shift($path);
$name = Folder::shift($ path);
$folder = "sites/{$name}";
$prefix = "/{$first}/{$name}";

if ($first != 'site' || !$name || !is_dir(__DIR__ . '/' . $folder)) {
    return [];
}

$container['pages']->base($prefix);

return [
    'environment' => $name,
    'streams' => [
        'schemes' => [
            'site' => [
                'type' => 'ReadOnlyStream',
                'prefixes' => [
                    '' => [$folder],
                ]
            ],
            'config' => [
                'type' => 'ReadOnlyStream',
                'prefixes' => [
                    '' => ['site://config', 'user://config', 'system/config'],
                ]
            ]
        ]
    ]
];

Here, this example allows you to create separate grav instances in subdirectories, like shop/ demo/ etc with their own configuration and pages and call them via “site/shop”, “site/demo” etc. At the moment there exists no direct documentation for it, but @rhukster will adding them soon.

Hi Sommerregen, thanks for your answer.

I was ending making two different directory structures, like this:

one full grav structure for theme n.1
and
one full grav structure for theme n.2

Ok, Ok, you guys win! I’m going to have to spend some time today to document the power of Grav’s multisite configuration capabilities. Really it’s not strictly multisite, it’s just a way to achieve that with a powerful setup file.

Looking forward to the setup file document :slight_smile:

@rhukster, I want to use multi subsite function for next project, can you tell more about how to use setup.php file, thanks~~

Ack, still need to write it!

Hi Andy or Sommerregen,

Would it be possible for you to post a screenshot of the folder set up? I’m not sure what the contents of the sub folder should be. I’ve tried a few different variations but keep getting a 404 on any link I try.

Thanks!

Hi @Anthony,

I’m using a different setup than the one I posted. If you stick to the above example you have to place all your sub-sites into a folder sites of your Grav root directory. Each sub-site can then be fetched from the browser via the URL www.localhost.com/site/<subsite>. You can change the folder place by changing the line

—php
if ($first != ‘site’ || !$name || !is_dir(DIR . ‘/’ . $folder)) {
return [];
}


for example to:

---php
if ($first != 'site' || !$name || !is_dir(USER_DIR . "/$folder")) {
    return [];
}

and

'site' => [
  'type' => 'ReadOnlyStream',
  'prefixes' => [
    '' => ["user://$folder"],
  ] 
],

which changes the location of your subsites to theuser/sites/<subsite> folder. This is probably a better place to store things. If you don’t like the URL address (maybe you want your sites be accessed via the URL www.localhost.com/sites/<subsite>) you may change it, too ($first != 'sites'). Thus, all in all you have to write:

—php
if ($first != ‘sites’ || !$name || !is_dir(USER_DIR . “/$folder”)) {
return [];
}


with the above stream changes.

Hi @Sommerregen,

if I want the subsite can be call with URL like www.locathost.com/subsite. How can I achieve that?

Hi @n2ray and @all who are reading this. Currently I’m writing up a consise documentation (will at least take this WE) about multisite stuff and will most likely explain the snippet below:

—php

<?php use Grav\Common\Filesystem\Folder; // Get relative path from Grav root. $path = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : Folder::getRelativePath($_SERVER['REQUEST_URI'], dirname($_SERVER['SCRIPT_NAME'])); $name = Folder::shift($path); $folder = "sites/{$name}"; $prefix = "/{$name}"; if (!$name || !is_dir(USER_DIR . "/$folder")) { return []; } $container['pages']->base($prefix); return [ 'environment' => $name, 'streams' => [ 'schemes' => [ 'site' => [ 'type' => 'ReadOnlyStream', 'prefixes' => [ '' => ["user/$folder"], ] ], 'user' => [ 'type' => 'ReadOnlyStream', 'prefixes' => [ '' => ['site://'], ] ], 'config' => [ 'type' => 'ReadOnlyStream', 'prefixes' => [ '' => ['site://config', 'user://config', 'system/config'], ] ] ] ] ]; ``` which will maps any `www.locathost.com/` to a `user/sites/` folder. Inside this folder you can create the usual and necessary folders `config`, `pages` etc. Hope this helps at the first stage. Best, @Sommerregen

BTW: I have a typo. Should be

'config' => [
   'type' => 'ReadOnlyStream',
      'prefixes' => [
         '' => ['site://config', 'system/config'],
      ]
]
---