2

The title pretty much says it all.

I'm trying to connect to a RESTful API within Craft templates to pull various showtimes, prices, availability, etc. of a theater. I have my URL endpoints and username & password but have no idea where they need to go in the templates. The API uses Basic Authentication. Everything I'm reading is PHP specific and I'm not quite sure how that translates to Craft/Twig.

I like the Rest plugin by Dukt (https://dukt.net/rest) but it uses OAuth.

Any help/direction would be appreciated.

2 Answers 2

3

I have built something similar so hopefully this will help get you rolling.

You are going to need to (or at least I would) create a plugin that you can call in your twig template. Pay special attention about creating a variable and services.

Let's say your plugin is called theater. Let's also pretend you have a url "mysite.com/showtimes"

In your showtimes template, you would make a call to your theater plugin to get showtimes.

showtimes.twig

{# Get all upcoming showtimes from the api. #}
{% set showtimes = craft.theater.showtimes %}

I won't get into the specifics of building an entire plugin, but here are the main players you'll need.

First you'll need a file called TheaterVariable.php that has this:

TheaterVariable.php

<?php
namespace Craft;

class TheaterVariable
{
    /**
     * Get all upcoming showtimes from the api.
     *
     * @return mixed
     */
    public function showtimes()
    {
        $showtimes = craft()->theater->getShowTimes();

        return $results['data'];
    }
...

}

Now you'll need a file called TheaterService.php to do the real work of getting your showtimes.

TheaterService.php

<?php
namespace Craft;

class TheaterService extends BaseApplicationComponent
{
    /**
     * Get all upcoming showtimes from the api.
     *
     * @return \Guzzle\Http\EntityBodyInterface|string
     */
    public function getShowTimes()
    {
        try {
            error_log((craft()->config->get('devMode')) ? 'Getting all upcoming showtimes.' . '' : '');

            $client = new \Guzzle\Http\Client('http://your-api-domain.com/);
            $uri = 'api/api-endpoint';

            $request = $client->get($uri, array(
                'content-type' => 'application/json'
            ));

            $request->addHeader('Accept', 'application/json');
            $request->addHeader('Authorization', 'YOUR CREDS');

            $response = $request->send();

            return $response->json();
        } catch
        (\Exception $e) {
            if (craft()->config->get('devMode')) {
                error_log('Error: Could not get upcoming showtimes.');
                error_log($e->getResponse()->getBody());
            }
        }

    ...

    }
}

Finally, back to your showtimes template:

showtimes.twig

{% if showtimes|length %}
    {% for showtime in showtimes %}
        ...
    {% endfor %}
{% else %}
    {# Could not find any upcoming showtimes for some reason. #}
{% endif %}

I am using oAuth to handle my authorization, so that part might be a bit different for you. But in the big picture this should be pretty close.

Hope this helps!

2

Thank you for pointing me in the right direction! That was super helpful.

Here's what I ended with so far. Things may change depending on what I need down the road. It uses Basic Auth like I mentioned in the original post. The main thing I wanted was to be able to pass the URL as a parameter so I could use the same function to get various data.

I created a plugin, like you mentioned. I ended up putting my code in the Variable.php file...not sure if that's how you're supposed to do it or not. I found a plugin called Guzzle (https://github.com/davist11/craft-guzzle) and most of it was taken from that.

TheaterVariable.php

<?php

namespace Craft;

class TheaterVariable {

    public function get($options){

        $url = $options['url'];
        $limit = array_key_exists('limit', $options) ? NumberHelper::makeNumeric($options['limit']) : null;
        $offset = array_key_exists('offset', $options) ? NumberHelper::makeNumeric($options['offset']) : 0;

        try {

            //API Credentials
            $login = 'USERNAME';
            $password = 'PASSWORD';

            $client = new \Guzzle\Http\Client();
            $request = $client->get($url);

            //cURL Options for Basic Authentication
            $request->getCurlOptions()->set(CURLOPT_RETURNTRANSFER, true);
            $request->getCurlOptions()->set(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
            $request->getCurlOptions()->set(CURLOPT_USERPWD, "$login:$password");

            $response = $request->send();

            if (!$response->isSuccessful()) {
                return;
            }

            $items = $response->json();

            $items = array_slice($items, $offset, $limit);

            return $items;

        } catch (Exception $e) {

            return;

        }
    }
}

Then in my template I am able to set the URL to whatever I need it to.

_entry.html

{% set showtimes = craft.theater.get({ url: 'http://api-domain.com/showtimes.json' }) %}
{% for show in showtimes.data %}
    <h1>{{ show.title }}</h1>
{% endfor %}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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