This is a tricky topic for a simple answer. Off the top of my head, there are two general approaches you may fall in for this. I'll keep my answer fairly broad:
URL-Enabled Elements
You can create an Element Type and implement the method routeRequestForMatchedElement. This approach would require you to have a Custom Element, and have a need for that Element to be URL-enabled like Entries or Categories or Products.
For this approach you would not need to setup registerSiteRoutes
.The Element API would handle the front-end request in the same way other URL-enabled Element requests are handled.
Your Plugin has a template in the plugins template folder that you want to render on the front-end of the website
The main concept to understand here is that Craft has two Template Modes: Site
and CP
. Depending on which template mode is active, Craft will look in different places for the template to load.
To set the template mode in your code, you can use the following:
// Tell craft to look in the front end craft/templates folder for a template
craft()->templates->setTemplateMode(TemplateMode::Site);
// Tell craft to look in the back end craft/app/templates folder for a template (where you can later update the path to target your plugin template folder)
craft()->templates->setTemplateMode(TemplateMode::CP);
Once you are on the right side of the fence, you can then render the template you want and return it to the page. You would do this in one of two places:
Controllers If your logic is taking place in a controller you will need to render the template and return the rendered template to the page as a variable. Two scenarios in controllers where this may occur:
Responding to a page with errors:
$output = craft()->curiousService->getTemplate()
craft()->urlManager->setRouteVariables(array(
'stuff' => $output
));
Rendering a template as the final step in the controller action (this may apply to CP scenarios more than front-end scenarios).
$this->renderTemplate('curious/example', array(
'stuff' => $stuff,
));
Variables If your logic is taking place in the middle of the page, you may need to create a custom variable that renders your template and outputs it when the variable is called:
{{ craft.myCuriousPlugin.getMyTemplate() }}
Be sure to Flip/Flop
In either case, since you are flip/flopping on which part of the site is rendering your templates, you'll want to be sure to set your Template Mode back to the Site
side of things once you are done:
// Front end page calls your plugin
// Switch things to look for templates on the back end
craft()->templates->setTemplateMode(TemplateMode::CP);
// Do your thing
//
// Note the template path is just the name of the plugin
// and the folder in the plugins template folder that you
// want to access, and that we are omitting the word 'templates'
$html = craft()->templates->render('curious/example', array(
'someVariable' => $yourResults,
'someOtherVariable' => $someOtherStuff
));
// Switch things back to look for templates on the front-end
// so that any template-related things that after you behave
// as normal
craft()->templates->setTemplateMode(TemplateMode::Site);