1

I need to serve different home pages (structure entries) depending on the subdomain. For example:

foo.example.com -> this will render an entry with slug "foo" 
bar.example.com -> this will render an entry with slug "bar"

So far I created a plugin and fetched the proper entry based on the subdomain:

class LocationsPlugin extends BasePlugin
{
    (...)
    public function init()
    {
        if (craft()->request->isSiteRequest()) {
            (...)
            // at this point $entry is the entry I want to render 
            // the problem is the following doesn't work:
            craft()->templates->render("subdomains/_entry", ["entry" => $entry]);
        }
    }
}

I get the layout rednered but without the content. Twig's blocks aren't rendered at all and I suspect init() hook is called before some initializations required by render().

The question: How can I, having $entry in init(), just render it instead of the main page?

Thanks! Jan

2
  • 1
    Wouldn't it be easier to select the correct entry in the template instead? Something like {% if siteUrl == 'foo.example-com' %}{%set entry = craft.entries.section('my-section').slug('foo') %}{% endif %}
    – megatrond
    Jul 15 '15 at 12:34
  • @megatrond I thought about this but I plan doing some additional steps in the init() hook that can't be made easily in Twig. Jul 15 '15 at 13:05
3

So I've been playing around with this and got stuck a few times, but I think I have a solution that could work for you.

I think the problem is actually because craft()->templates->render() simply just gives you the compiled template back, it doesn't try and render it in the browser. So your plugins init method is being hit, everything is working just fine, then it just goes past it and just keeps going until the end.

There is a controller method for rendering a template which is called like $this->renderTemplate which according to the docs:

This is a shortcut for TemplatesService::render(), but rather than returning the rendered template, it will output it to the browser and end the request. It will also include any CSS and JS that is queued up via includeCssFile(), includeJsFile(), et al., and it will set the appropriate MIME type header based on the template file’s extension.

You can see the method from the Class reference here

Now I don't think you can or should try and call controller methods from within your plugin's init, so I think you need to do something inspired by this method i.e just echo the content and end the request.

So this is what I have used and it worked for me just fine, it might need some tweaking and more inspiration from the renderTemplate method, but it works as a start.

if (craft()->request->isSiteRequest()) {

  // Get your entry however you wish
  $entry = craft()->entries->getEntryById(264);

  // Render the template with $entry and set it to output
  $output = craft()->templates->render('arena', ["entry" => $entry]);

  // ** From renderTemplate **

  // Output it into a buffer, in case TasksService wants to close the connection prematurely
  ob_start();

  echo $output;

  // End the request
  craft()->end();
}

From this i got a rendered template in the browser, output the entries title using {{ entry.title }} and also all the {% extends %} {% block %} tags and everything else seemed to work.

If there is a better solution then i'm all ears, but this is what I could come up with from looking around the source/docs/stackexchange.

Hope that helps :)

1
  • hacky but it's one way to do it. In the end we decided to go around domains. Thanks for help! Jul 29 '15 at 15:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.