13

Totally possible. Just loop through the blocks and add whatever data you want from them to the response array: 'transformer' => function(EntryModel $entry) { // Create an array of all the "Body" Matrix field's blocks $bodyBlocks = []; foreach ($entry->body as $block) { switch ($block->type->handle) { case 'text': ...


8

The ElementAPI plugin itself doesn't seem to offer a caching solution, but there is a fork from a guy which has implemented a caching option cache and cacheTime: https://github.com/theolampert/ElementAPI Update: They have introduced a new cache option in the official ElementAPI plugin (version 1.5).


8

You’d do this with a brand new element query using the relatedTo param. Craft 2: // This is the PHP equivalent of typing `craft.entries()` in a template: $criteria = craft()->elements->getCriteria(ElementType::Entry); // Only fetch Location entries that are related to the Site entry: $criteria->section = 'locations'; $criteria->relatedTo = ['...


7

You can fetch GET parameters using HttpRequestService::getQuery() or getRequiredQuery(): 'entries-by-category' => function() { $categoryIds = craft()->request->getRequiredQuery('categoryIds'); return [ 'elementType' => 'Entry', 'criteria' => [ 'relatedTo' => ['targetElement' => $categoryIds], ...


7

Sure – the element-api.php config file is just plain ol' PHP, and the functions that make up the individual endpoints (e.g. 'news.json' => function () { ...) doesn't necessarily have to be declared inside that file. One way to split up the file would be to create one PHP class per element type or section. You could compose these classes however you'd ...


6

The $entry variable that is passed to your endpoint’s transformer function will be an EntryModel object - the same type of object you use when interacting with entries in your templates. So everything you can do in your templates you can also do from this function. The easiest way to get a Structure section entry’s children is with the getChildren() ...


6

Try this: ... 'transformer' => function (EntryModel $entry) { return [ 'title' => $entry->title, 'url' => $entry->url, 'summary' => (string) $entry->summary ]; }, ...


6

$entry->postDate will give you the postDate property of the EntryModel, which itself is a DateTime object. The JSON transformer will do its best to convert that object to JSON by returning its visible properties, which produces the JSON object in your example. Angular has built-in date filters, but it requires the input data to be in a recognized format....


6

You can actually use the StringHelper::toKebabCase function for this: $string = 'Hello there'; $result = StringHelper::toKebabCase($string); // => 'hello-there'


5

Currently, Element API is hard coded to throw a 404 exception for single element endpoints, if the element criteria returns no results. There's no way to prevent this exception, add "fallback" criteria or to display an error message. Note that the 404 exception will only be thrown if the first parameter is set to true, though. If it isn't, Element API will ...


5

You have to set the criteria model's limit parameter to null and disable pagination. 'criteria' => [ 'group' => 'fullMembership', 'limit' => null, ], 'paginate' => false,


5

Your approach is technically correct – the problem is that craft()->imager->transformImage() requires two additional parameters; $transformDefaults and $configOverrides. You can read more about these parameters and the transformImage method in the plugin's official docs, but it's not super important. The two parameters can actually be null, which ...


5

Following is an example of using the search feature in a GET request with parameter 'search'. return [ 'elementType' => 'Entry', 'criteria' => ['search' => (craft()->request->getParam('search')) ? 'title:'.craft()->request->getParam('search') : '' ], 'paginate' => true, 'elementsPerPage' => 10, 'pageParam' =&...


5

Something like the following should work: // elementapi.php return [ 'endpoints' => [ 'assets.json' => [ 'paginate' => false, 'elementType' => ElementType::Asset, 'criteria' => [ 'limit' => null, ], 'transformer' => function(AssetFileModel $asset) { ...


5

A couple of issues: First, the EntryModel::getParent() method returns an EntryModel, not an ElementCriteriaModel, which means that calling getParent()->first() will throw an exception. In other words, you'll need to remove the call to first(). Second, you'll need to be specific about which fields you want to return from your parent entry – just passing ...


5

If you want to restrict the whole API, you can add some code to the top of your /config/elementapi.php file (right below namespace Craft;) that checks for a logged in user, and ends the request with an appropriate status if the user isn't logged in: <?php namespace Craft; $user = craft()->userSession->getUser(); if (!$user) { HeaderHelper::...


4

I think (well, I know) I am confused by where "regular" php is and where the ElementAPI takes over. This is returning me data, but I'm not sure if it's just dumb luck or I've actually got something working... $slug = craft()->request->getRequiredPost('location'); // chicago $criteria = craft()->elements->getCriteria(ElementType::Category); $...


4

Change function (EntryModel $user) to function (UserModel $user) You were passing in a user to a function that’s expecting an EntryModel. That’s the reason for the error you are getting.


4

I was also very interested in this, so i forked the repo from theoplampert and added some extra features. You can find it here, https://github.com/jacobnijgh/ElementAPI. This fork allows you to not only cache the results but also the paginated results just what we needed in our case for loading some results with AJAX.


4

Yes - you can access it exactly the same way you do in the templates; you just need to use PHP syntax (e.g. -> for accessing sub-properties rather than .). 'transformer' => function(EntryModel $entry) { // Begin defining the response data for this entry $data = [ 'excerpt' => $entry->excerpt, ]; // Get the first asset in ...


4

You're very close! $criteria = craft()->elements->getCriteria(ElementType::Entry); $criteria->myFieldHandle = array( 'target' => 90210, 'range' => 100 ); $criteria->order = 'distance'; $results = $criteria->find(); I've never actually tested it with the Element API plugin, but in theory it should work just fine. In response ...


4

I had the same problem lately and solved it with a locale query parameter. The code for this inside craft/config/elementapi.php looks like this: return [ 'endpoints' => function () { 'entries.json' => function () { // Get the `locale` query param and fallback to // current locale if not defined. $locale ...


4

You can do this by assigning your endpoint(s) to a function: return [ 'endpoints' => [ 'my-endpoint' => function() { HeaderHelper::setHeader(['Surrogate-Control: max-age=300']); return [ // ... ]; } ] ]; UPDATE Alternatively as of v1.2, you can do it from a separate plugin ...


4

In case anyone finds this in a Google search, this is how you'd do it in Craft 3, if, say, you wanted to add an Expires header: $response = Craft::$app->getResponse(); $response->headers->set('Expires', gmdate('D, d M Y H:i:s \G\M\T', strtotime("+1 month"))); Yii2 Responses


4

Since Global Sets are elements just like entries, users, etc., you can create API endpoints that are all about them: 'globals/<handle:\w+>' => function($handle) { return [ 'elementType' => 'GlobalSet', 'criteria' => ['handle' => $handle], 'first' => true, 'transformer' => function(\Craft\...


4

Here's an example elementapi.php that should get you going...this is returning shipping details but you can modify the transformer for whatever data you need of course... return [ 'endpoints' => [ 'api/json/orders/whatever.json' => [ 'paginate' => false, 'elementType' => 'Commerce_Order', 'criteria' => ['...


4

You didn’t tell where that Twig file is located, but I assume your issue has to do with being in the wrong “Template Mode”. Here’s how you can switch mode: Craft::$app->view->setTemplateMode() Documentation: https://docs.craftcms.com/v3/extend/updating-plugins.html#rendering-plugin-templates-on-front-end-requests


4

You're using $view->resolveTemplate('_blog-entry') which is returning the absolute path to the template as a string, and then passing that to $view->render which is expecting a relative path, not an absolute one. Internally I expect it's trying to run resolveTemplate on its argument, and it isn't sophisticated enough to recognize that a path is already ...


4

The cart is not baked into \Craft, but craft\commerce\Plugin. Try the following: $cart = craft\commerce\Plugin::getInstance()->getCarts()->getCart(); Uses the following function: /** * Get the current cart for this session. * * @param bool $forceSave Force the cart to save when requesting it. * @return Order * @throws Exception * @throws \...


3

Same as you would access it from a Twig template. If you're positive there will always be one category selected, then this would work: 'transformer' => function(EntryModel $entry) { return [ 'category' => (string)$entry->categoryHandle[0], ]; },


Only top voted, non community-wiki answers of a minimum length are eligible