Answers.Body: <p>This query cannot be created in the "ideal" way described in the question using <code>craft()-&gt;elements-&gt;getCriteria</code>. It required several steps to build the results needed. The final solution was a bit specific to our needs. Here is some pseudocode that represents a solution:</p>
  
  <pre><code>$urls = array();
  
  // Fetch all enabled locales
  foreach (craft()-&gt;i18n-&gt;getSiteLocales() as $locale)
  {
      // Confirm there are elements in a specific locale and get them
      ...
      $criteria-&gt;locale = $locale-&gt;id;
      $elements = $criteria-&gt;find();
  
      foreach ($elements as $element)
      {
          // Add each location indexed by its id
          $urls[$element-&gt;id][] = array(...);
      }
  }
  
  // Process what we created above and adjust it to fit our needs
  $urls = $this-&gt;processUrlsIntoTheRightFormat($urls);
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2016-06-02T22:16:38.040Z
Answers.LastActivityDate: 2016-06-02T22:16:38.040Z
Answers.UserDisplayName: Ben Parizek
Body: <p>I'm trying to create a sitemap for a site with multiple locales.  An example of the format is described <a href="https://support.google.com/webmasters/answer/2620865?hl=en" rel="nofollow">here</a>, but as a quick summary: I need to output locales of related translated pages aside one another.</p>
  
  <pre><code>&lt;url&gt;
    &lt;loc&gt;http://www.example.com/english/&lt;/loc&gt;
    &lt;xhtml:link
       rel="alternate"
       hreflang="de"
       href="http://www.example.com/deutsch/"
       /&gt;
    &lt;xhtml:link 
       rel="alternate"
       hreflang="de-ch"
       href="http://www.example.com/schweiz-deutsch/"
       /&gt;
    &lt;xhtml:link 
       rel="alternate"
       hreflang="en"
       href="http://www.example.com/english/"
       /&gt;
  &lt;/url&gt;
  </code></pre>
  
  <p>To output a list of all entries like this I believe I need to query: <em>All entries, from all locales, grouped by elementId</em>.</p>
  
  <p>I've tried to do this using <code>$criteria-&gt;find()</code> but I seem to run into two problems.</p>
  
  <p>First, there appears to be no way to query all locales.  The best way I've found is to loop through all the locales.  I'm wondering if I'm overlooking something.  Right now I have:</p>
  
  <pre><code>foreach (craft()-&gt;i18n-&gt;getSiteLocales() as $locale)
  {
    ...
  }
  </code></pre>
  
  <p>A potential problem with doing it this way is that I won't be able to group the results of all locales by <code>elementId</code> during the query.</p>
  
  <p>Second, once I have all the entries, I need to make sure they are grouped by <code>elementId</code>.  This does not happen by default.  The entry for each locale just gets the next available ID when it's created.  It seems the way to do this would be to use <code>$criteria-&gt;order = 'elementId';</code> however, it doesn't appear Craft supports ordering a result set by <code>elementId</code>.</p>
  
  <p>The ideal query would look something like this:</p>
  
  <pre><code>$criteria            = craft()-&gt;elements-&gt;getCriteria(ElementType::Entry);
  $criteria-&gt;limit     = null;
  $criteria-&gt;status    = 'live';
  $criteria-&gt;sectionId = $sectionId;
  
  // Problem #1: I want to return all locales like you can return all entries using null
  $criteria-&gt;locale    = null; 
  
  // Problem #2: I want to group my results by Element ID
  $criteria-&gt;order     = 'elementId';
  
  $entries = $criteria-&gt;find();
  </code></pre>
  
  <p>Any ideas on what the best approach would be here?  Is there any crafty way of doing this or will I have to resort to using a custom query?</p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2015-04-03T08:45:50.030Z
Comments.Text: Not an answer but I just found this related question [Retrieving an entry by ID in ALL locales](http://craftcms.stackexchange.com/q/8244/125). It seems like you have to build the query manually.
Comments.UserDisplayName: carlcs
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2015-04-03T19:20:56.487Z
Comments.Text: I'm with @carlcs - I think you're going to have to go through Query Builder.
Comments.UserDisplayName: Brad Bell
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2015-04-03T19:37:49.697Z
Comments.Text: Ok gentleman, I'll see what we come up with and post an update once we have something.  Thanks for the thoughts.
Comments.UserDisplayName: Ben Parizek
Tags: <localization><elementcriteriamodel>
Title: How to create a query to group alternate language pages?
ThreadText: # How to create a query to group alternate language pages?
  
  (Asked by: username_0 on 2015-04-03)
  
  I'm trying to create a sitemap for a site with multiple locales. An example of the format is described [here](https://support.google.com/webmasters/answer/2620865?hl=en), but as a quick summary: I need to output locales of related translated pages aside one another.
  
  ```
  <url>
    <loc>http://www.example.com/english/</loc>
    <xhtml:link
       rel="alternate"
       hreflang="de"
       href="http://www.example.com/deutsch/"
       />
    <xhtml:link 
       rel="alternate"
       hreflang="de-ch"
       href="http://www.example.com/schweiz-deutsch/"
       />
    <xhtml:link 
       rel="alternate"
       hreflang="en"
       href="http://www.example.com/english/"
       />
  </url>
  
  ```
  
  To output a list of all entries like this I believe I need to query: *All entries, from all locales, grouped by elementId*.
  
  I've tried to do this using `$criteria->find()` but I seem to run into two problems.
  
  First, there appears to be no way to query all locales. The best way I've found is to loop through all the locales. I'm wondering if I'm overlooking something. Right now I have:
  
  ```
  foreach (craft()->i18n->getSiteLocales() as $locale)
  {
    ...
  }
  
  ```
  
  A potential problem with doing it this way is that I won't be able to group the results of all locales by `elementId` during the query.
  
  Second, once I have all the entries, I need to make sure they are grouped by `elementId`. This does not happen by default. The entry for each locale just gets the next available ID when it's created. It seems the way to do this would be to use `$criteria->order = 'elementId';` however, it doesn't appear Craft supports ordering a result set by `elementId`.
  
  The ideal query would look something like this:
  
  ```
  $criteria            = craft()->elements->getCriteria(ElementType::Entry);
  $criteria->limit     = null;
  $criteria->status    = 'live';
  $criteria->sectionId = $sectionId;
  
  // Problem #1: I want to return all locales like you can return all entries using null
  $criteria->locale    = null; 
  
  // Problem #2: I want to group my results by Element ID
  $criteria->order     = 'elementId';
  
  $entries = $criteria->find();
  
  ```
  
  Any ideas on what the best approach would be here? Is there any crafty way of doing this or will I have to resort to using a custom query?
  
  **Tags:** localization, elementcriteriamodel
  
  > **Comments:**
  > **username_1**: Not an answer but I just found this related question [Retrieving an entry by ID in ALL locales](http://craftcms.stackexchange.com/q/8244/125). It seems like you have to build the query manually.  
  > **username_2**: I'm with @username_1 - I think you're going to have to go through Query Builder.  
  > **username_0**: Ok gentleman, I'll see what we come up with and post an update once we have something.  Thanks for the thoughts.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2016-06-02. Score: 2 | Accepted answer
  
  This query cannot be created in the "ideal" way described in the question using `craft()->elements->getCriteria`. It required several steps to build the results needed. The final solution was a bit specific to our needs. Here is some pseudocode that represents a solution:
  
  ```
  $urls = array();
  
  // Fetch all enabled locales
  foreach (craft()->i18n->getSiteLocales() as $locale)
  {
      // Confirm there are elements in a specific locale and get them
      ...
      $criteria->locale = $locale->id;
      $elements = $criteria->find();
  
      foreach ($elements as $element)
      {
          // Add each location indexed by its id
          $urls[$element->id][] = array(...);
      }
  }
  
  // Process what we created above and adjust it to fit our needs
  $urls = $this->processUrlsIntoTheRightFormat($urls);
  
  ```
  
  
  ---
  
  