# Question
Title: Should we use Stash caching along side CE Cache?
I'm wondering what the best option is for better site performance in regards to caching with Stash and CE Cache. A few questions come to mind:

* Should we be running them side by side?
* Any advantages to run them side by side?
* If we run CE Cache should we turn off any Stash caching?
* If we use anything other than DB caching via CE Cache is that a good time to use Stash caching assuming it use DB caching (I think?)

# Answer
> 2 votes
Everyone has their own method for using Stash and the various caching tools.

I find that Stash is great for simplifying my structure (more DRY) which also has a side effect of dropping overhead. But my first goal with Stash is "stashing" a block of functionality so that I can move it elsewhere within my "waterfall" of template rendering and / or cloning that block to be used in multiple areas.

Caching with add-ons such as CE Cash and Template Morsels (from Solspace and similiar functionality as CE Cache) is great for making a dynamic area load as a static area (with control over refresh intervals) but not so great at moving that component elsewhere in the waterfall and not as great as Stash is for fine grained re-usability of code.

Stash has been pretty quick moving in added functionality and details can change quick, but in the past I have found caching tools like Template Morsels easier for just setting entire sections of templates as being cached and going on about my day. With Stash I'm much more targeted.

So, yes, Stash and caching options should be used side by side. Each option gives you similar answers to performance problem but I use them differently based on their differing capabilities.

---
Tags: stash, performance, caching, ce-cache
---


title: EE URL Structure? (For Dummies)

text:
# Question
Title: EE URL Structure? (For Dummies)
Is anyone able to provide some advice on how these guys might have achieved their URL structure/naming? Is it done with template group names, plugins, both?

They are listed in the CartThrob gallery: http://www.chicathome.co.uk/

Looks like they get http://www.chicathome.co.uk/category/sub-category/product-name

Even their checkout pages have super simple URLs

PART A: We currently have for categories: http://www.domain.co.uk/template\_group/template\_name/ Be nicer to have http://www.domain.co.uk/category

And for products we currently have: http://www.domain.co.uk/template\_group/template\_name/url\_title Be nicer to have http://www.domain.co.uk/category/url\_title (and to have breadcrumbs of home \> category \> product title)

Plus they have products grouped into categories rather than all lumped in together. We have a playa field {product\_category} for each product that says which categories the product needs to appear in - they can appear in more than one. Which also throws up how do you handle breadcrumbs for products that can appear in multiple areas?

PART B: Products can also be shopped for: by colour {by\_colour}, and by occasion {by\_occasion} - which are a playa field each in the product entry page of the EE CP.

So you'd want the following URL structure (and breadcrumbs of home \> red \> product title): http://www.domain.co.uk/red/url\_title

I know this is probably EE related more than CT related. This is only my third EE site and first store. I just can’t get my head around how to get it all to work… wish we could take a peak under the hood of Chic at Home!

Does anyone have an example template group setup or similar that would demonstrate how I should be going about this?

Thanks for your time.

# Answer
Ok, firstly, i would say that you really want URL's that when human read make sense and also work in a content & shop scenario, i'm not sure that having category as the first segment is optimal.

For example, a shop i have just developed has the url structure

**example.com/shop/product/product\_name**

**example.com/shop/category/category\_name**

This means that the user & the search engine are able to easily recognise by looking at the url where they are in the site. Also, it means that they can have example.com/blog and that is obviously separate from the shop as it's not preceded by "shop" in the URL.

Using this structure, you can have a template group of "shop" that allows you to have whatever templates you like and gives you lots of flexibility.

Alternatively, you can have:

**example.com/product/product\_name OR example.com/product/category/product\_name**

**example.com/category/category\_name**

Which means you simply have your default template group with templates called "products" & "category" and then you can drive your content from there using if statements if needed to detect what is in the URL segments and show the content how you see fit.

With regards to how you handle breadcrumbs where products appear in multiple categories? Well, if you have the url structure i'm suggesting where you have example.com/category/category\_name then as you go back in the segments, your template looks at the last url segment and shows all products that appear in that category. When you get right back to example.com/category you would show a page that lists all the categories.

If you are using playa fields for categorising, then you are going to need to do a fair amount of logic in your templates that works out what it should be showing dependent on the URL. So, if you have "category" as a url segment, then you can say if segment\_2 == category, then segment\_3 is the category itself and you use that value to pull in the data from your playa field to show products in that category.

There are, to be honest, a million different ways to do this. So my answer is right, but could also be wrong. It's up to you how you want your urls to work. My examples are simply personal preference.

With regards to your reference site, i imagine they've put loads of logic in the index template in their default template group or they've done some url routing with either the pages module or the structure add-on. Either way, i'm not mad keen on their url structure for a shop setup.
> 7 votes

# Answer
This URL schematic graphic is a great reference. Thanks to Jamessmith.co.uk:
> 4 votes

# Answer
You might want to take a look at the Freeway add-on so you can use conventional EE templating techniques but then route them via different URLs:

https://github.com/averyvery/freeway

I've never used it before myself, but looks pretty good.

Otherwise, as John says, you'll need a whole heap of convoluted logic in your templates (which in turn will see you having problems with advanced conditionals, parse order and poor performance)
> 3 votes

# Answer
@JohnWBaxter

Thanks very much for your help. I think I kind of prefer your second approach with having everything in the default template group as it takes out a URL segment from the display URL.

Does this sound right? …..in my default template group I could have templates:

* index (homepage)
* category
* shop\_by
* product
* cart
* checkout
* completed\_order

**PART A - GROUPING PRODUCTS:** I could use my playa field {playa\_categories} to group the product in their categories on the "category" template:

{exp:channel:entries channel="products" dynamic="no" search:playa\_categories="{segment\_2}" search:product\_for\_sale="y"}

example.com/category/bathroom

**PART A - DISPLAY ACTUAL PRODUCT:** A product listed on this category page would have a link to push to the 'product' template similar to:

example.com/product/{segment\_2}/{product\_url\_title}

example.com/product/bathroom/towel

And on the product template I'd have:

{exp:channel:entries channel="products" url\_title="{segment\_3}" limit="1"}

And the breadcrumb on this page would be:

home \>\> example.com/category/{segment\_2} \>\> example.com/category/{segment\_2}/{segment\_3}

home \>\> example.com/category/bathroom \>\> example.com/category/bathroom/towel

**PART B - GROUP ALTERNATE WAYS TO FIND PRODUCT:** I could use my playa fields {shop\_colour}, {shop\_types} to sort the types of groupings on the "shop\_by" template:

{exp:channel:entries channel="products" dynamic="no" search:shop\_colour="{segment\_2}" search:shop\_types="{segment\_2}" search:product\_for\_sale="y"}

example.com/shop\_by/{shop\_colour}

example.com/shop\_by/red

or

example.com/shop\_by/{shop\_types}

example.com/shop\_by/glassware

**PART B - DISPLAY ACTUAL PRODUCT:** A product listed on this shop\_by page would have a link to push to the 'product' template similar to:

example.com/product/{segment\_2}/{product\_url\_title}

example.com/product/red/bowl

And on the product template I'd have:

{exp:channel:entries channel="products" url\_title="{segment\_3}" limit="1"}

And the breadcrumb on this page would be:

home \>\> example.com/shop\_by/{segment\_2} \>\> example.com/shop\_by/{segment\_2}/{segment\_3}

home \>\> example.com/shop\_by/red \>\> example.com/shop\_by/red/bowl

I know that's a lot to take in - but am I on the right track?

Thanks very much for taking the time to help out :)
> 2 votes

---
Tags: cartthrob
---


# Question
Title: What is the best way to handle a matrix field in Stash
I have the following code in a template that I use to prepare the data for an embedded template using the Stash partials approach. It is for a single entry page that draws data from an entry that can have one or more images stored in a Matrix field.

```
{exp:stash:set_list name="business_listing" parse_tags="yes"}
  {stash:title}{title}{/stash:title}
  {stash:address_1}{b_address_1},{/stash:address_1}
  {stash:address_2}{b_address_2},{/stash:address_2}
  {stash:city}{b_city},{/stash:city}
  {b_images}
    {exp:stash:append_list:nested name="business_images" parse_tags="yes"}
    {stash:image}{b_img}{/stash:image}
    {/exp:stash:append_list:nested}
  {/b_images}
{/exp:stash:set_list}

```

Note that I am using the `set_list` on the outside and the `append_list:nested` inside.

I fetch these in the embedded template like so,

```
{exp:stash:get_list name="business_listing" orderby="title"}
  <ul class="business-images slides">
    {exp:stash:get_list:nested name="business_images" orderby=""}
    <li>
    {exp:ce_img:pair src="{image}" width="277" height="175" crop="yes"}
      <img src="{made}" alt="{title}" width="{width}" height="{height}" />
    {/exp:ce_img:pair}
    </li>
    {/exp:stash:get_list:nested}
  </ul>
  <h1>{title}</h1>
  {address_1}
  {address_2}
  {city}
{/exp:stash:get_list}

```

**Now whilst this code works**, I am not sure that it is the best way to do this. The `{stash:image_{count}}{b_img}{/stash:image_{count}}` feels decidedly dodgy, and as you can see I have left the `orderby` blank as I am not 100% sure what to put in there for a matrix field (that has only one column 'b\_img').

So, if anyone would like to chime in and give me some wisdom on this I would love to hear it.

# Answer
> 6 votes
The initial code block could be made more efficient by wrapping the outer list around Channel Entries tag pair and the nested {exp:stash:set\_list} around the Matrix variable pair instead of using {exp:stash:append\_list} inside it (which creates multiple append\_list tags). You can also create an explicit relationship between the outer and inner list by either prepending the entry\_id to the inner list name or setting the context of the inner list. This would also have the benefit of supporting multiple Channel entries should you ever need to capture more than one.

```
{exp:stash:set_list name="business_listing" parse_tags="yes" parse_depth="2"}
  {exp:channel:entries channel="my_channel" limit="1"}
    {stash:entry_id}{entry_id}{/stash:entry_id}
    {stash:title}{title}{/stash:title}
    {stash:address_1}{b_address_1},{/stash:address_1}
    {stash:address_2}{b_address_2},{/stash:address_2}
    {stash:city}{b_city},{/stash:city}
    {exp:stash:set_list:nested name="business_images" context="{entry_id}" parse_tags="yes"}
      {b_images}
        {stash:image}{b_img}{/stash:image}
      {/b_images}
    {/exp:stash:set_list:nested}
  {/exp:channel:entries}
{/exp:stash:set_list}

```

By default a Stash list will be ordered by the order in which the list rows were captured, so you can leave that blank if you wish.

```
{exp:stash:get_list name="business_listing"}
  <ul class="business-images slides">
    {exp:stash:get_list:nested name="business_images" context="{entry_id}"}
    <li>
    {exp:ce_img:pair src="{image}" width="277" height="175" crop="yes"}
      <img src="{made}" alt="{title}" width="{width}" height="{height}" />
    {/exp:ce_img:pair}
    </li>
    {/exp:stash:get_list:nested}
  </ul>
  <h1>{title}</h1>
  {address_1}
  {address_2}
  {city}
{/exp:stash:get_list}

```

# Answer
> 3 votes
Looks fine to me, and you can't argue with "it works." ;)

You might try just leaving {count} out completely, though I may be missing something on why you have added that. The last version I used didn't have nesting built in yet, so I'm not totally up to date with the newest quirks.

# Answer
> 2 votes
One problem with that code is it doesn't scale beyond a single business listing as all of the listing images will be appended to the statically named `business_images` list. You could easily add support for multiple listings by adding an `{entry_id}` suffix to the name of each image set.

```
{exp:stash:append_list name="business_listing" parse_tags="yes"}
  {stash:entry_id}{entry_id}{/stash:entry_id}
  {stash:title}{title}{/stash:title}
  {stash:address_1}{b_address_1},{/stash:address_1}
  {stash:address_2}{b_address_2},{/stash:address_2}
  {stash:city}{b_city},{/stash:city}

  {b_images}
    {exp:stash:append_list:nested name="business_images_{entry_id}" parse_tags="yes"}
        {stash:image}{b_img}{/stash:image}
    {/exp:stash:append_list:nested}
  {/b_images}

{/exp:stash:append_list}

```

Within your business listing loop you'd tweak your `get_list` code to:

```
{exp:stash:get_list:nested name="business_images_{entry_id}"}

```

---
Tags: templates, stash
---


# Question
Title: See if URL segment is in either of the custom fields and then show results
I'm able to get a simple search:custom\_field="something" working fine after reading the docs. However, I'd like it to search three fields to see if the parameter passed through segment\_3 is met and then display the results.

Something like this:

```
{exp:channel:entries
    channel="products"
    dynamic="no"
    search:product_category="{segment_3}" OR
    search:product_by_colour="{segment_3}" OR
    search:product_by_collection="{segment_3}"
    search:product_for_sale="y"
    search:product_popup_only="=not y"
    orderby="product_price|product_sku" sort="asc|asc"
}

```

Thanks for your help.

# Answer
> 8 votes
You cannot use OR clauses inside of a {exp:channel:entries} tag. The best way to handle this would be to write a custom plugin that would do the selection, or use the Active Record plugin.

You should not use the built-in Query plugin because it unsafe to pass user-submitted values (such as {segment\_\*} variables) to this plugin, while the Active Record plugin does escape any of these values for you.

# Answer
> 2 votes
I believe Solspace Super Search may be able to handle this as well. You may want to take a peek!

# Answer
> 2 votes
As Isaac states this is not possible with the search tag. I know you were giving an example of the syntax you would like but the search doesn't work in this way.

I think you may need to approach the build in a different way. It seems like you would like to filter results based on certain fields. EE doesn't have any real solution for this as standard. It has been achieved before by using either SuperSearch or Low Search. John Henry gave a great talk at EEUK using SuperSearch in this way so it's possible but complex.

I have built a product store before and used Low Seg2Cat to great effect. Create category groups for each of options you'd like to filter the entries by. Then use Seg2Cat to map the category\_ids from the url to the entries category parameter.

You can do this using the magic {segment\_category\_ids}. It also won't matter what order your segments are in but setting out a standard structure would be a good idea. Also you'll need to restrict your category options to unique names.

Eg.

Set up 2 category groups:

* colour:

+ red
    + green
    + blue
* collection:

+ collection a
    + collection b

URL: example.com/products/red/collection\_a/

In the index template of 'products' template group:

```
{exp:channel:entries
  channel="products"
  dynamic="no"
  category="{segment_category_ids}"
}

```

{segment\_category\_ids} will contain a pipe delimited string of the category\_ids from the url segments, like: 2|45|4|9

In this way you can filter your entries based on the url.

# Answer
> 1 votes
One of the option you can try is to write a simple plugin extending the channel module. That sounds harder than it is. Here is a nice article by DMLogic to get you started.

---
Tags: channel, search
---


# Question
Title: Inconsistencies found in exp_channel_titles and exp_channel_data tables
While I was looking into a related issue, I found the following scenario: Entry IDs in the exp\_channel\_data table do not match entry IDs in the exp\_channel\_titles table. I want to clean these up so there are no inconsistencies. **Any suggestions as to how to clean this up?**

# Answer
Run this query in you SQL browser/tool/contraption of choice.

```
SELECT exp_channel_data.entry_id, exp_channel_titles.entry_id
FROM exp_channel_data
LEFT JOIN exp_channel_titles ON exp_channel_data.entry_id = exp_channel_titles.entry_id
WHERE exp_channel_titles.entry_id IS NULL

```

This will give you a list of entries in your exp\_channel\_data table that don't have a title row. you can reverse the query to do the opposite.
> 7 votes

# Answer
Well, if you mean that there are some entries in the channel data table but not in the channel titles table, then you can probably delete them (make a backup first!) I've never seen this myself and cannot think of a scenario where this might occur so cannot give you a exact definitive answer i'm afraid.

But certainly try what i've suggested, see if it causes any issues and make sure you have that backup just in case!
> 1 votes

---
Tags: channel
---


# Question
Title: What is the source of my 'Blacklist irretrievable' error?
When I go to download the blacklist in a recent install of v2.5.3 - Build Date: 20120911 I get this…

> Error: New blacklist was irretrievable.
>
> Did not receive a '200 OK' response from remote server. (HTTP/1.1 301 Moved Permanently)

I've raised a ticket with EllisLab about this with my new complimentary Silver plan. I'm guessing it's to do with the domain rerouting that's happened over the weekend.

Wonder if anyone here can offer suggestions quicker than EllisLab ;)

# Answer
> 6 votes
Looks like in `/system/expressionengine/modules/blacklist/mcp.blacklist.php` on line 593 it's pinging: http://ping.expressionengine.com/index.php. Most likely an oversight on EL

# Answer
> 3 votes
Unfortunately I don't think you're going to get a solution here. The same thing (new domain routing issue) happened with the EE CP Accessory, and I assume this is in the same boat. I'm not sure if 'I can't answer your question' is a good enough answer for SE though!

# Answer
> 1 votes
Unfortunately, you are at their mercy on this I think. You can always uninstall the addon if it's causing problems.

# Answer
> 1 votes
Well, i'd say you'll have to remove it and wait for an update to that module or for them to reinstate that url.

---
Tags: error, control-panel
---


# Question
Title: SLASH constant isn't the same as "/" character [in PHP]?
I recently discovered that the EE/CI's SLASH constant isn't the same as the "/" character. Or, at least, in my plug-in code, `(SLASH == "/")` evaluates to `FALSE`...

They output the same character, though. I'm confused... can anyone explain why this is the case?

# Answer
That's because `SLASH` is actually the encoded form of `/`. Here's how it's set:

```
define('SLASH', '/');

```
> 5 votes

---
Tags: add-on-development, php
---


# Question
Title: Is it possible to access channel variables inside of a reverse related entries tag without using an embed?
I'm wanting to access a variable from the series channel called {custom\_series\_field}, but I need to access that variable within the reverse related entries tag. Currently, this code doesn't parse the {custom\_series\_field} variable inside of the reverse entries tag.

Here is the sample code:

```
{exp:channel:entries channel='series' status='open|hidden' url_title='{segment_2}' dynamic='off'}
  {custom_series_field}

  {reverse_related_entries status='open|hidden' orderby='date' sort="desc" limit='1'}
    Reverse related content here
    {custom_series_field}
  {/reverse_related_entries}
{/exp:channel:entries}

```

I know you can do this with playa, but we're not ready to update quite yet. Is it possible to access a channel variable here?

# Answer
Yes, just use Stash (you're using it already right, like everyone else? ;-))

```
{exp:channel:entries channel='series' status='open|hidden' url_title='{segment_2}' dynamic='off'}
  {exp:stash:set name="parent_title"}{title}{/exp:stash:set}
  {reverse_related_entries status='open|hidden' orderby='date' sort="desc" limit='1'}
    Reverse related content here
    {exp:stash:get name="parent_title"}
  {/reverse_related_entries}
{/exp:channel:entries}

```
> 3 votes

# Answer
Unfortunately you can't. You will have to pass the `entry_id` or `url_title` to an embed to get a custom field from that channel. See Docs for more info
> 3 votes

# Answer
I don't know that this should be needed as the docs for Reverse Related Entries certainly show it using custom fields just fine... but, you can use this quick plugin, More Entries, I just put up to do this. It basically is a {exp:channel:entries} tag with a different name, allowing you to call the tag within an existing {exp:channel:entries} tag.

Note that as pointed out in the comments, it is still not a good idea to run database queries in a loop that is itself a result of a database query because the performance of the nested loops will be very bad. That said, if you're going to use an expensive embed and do it anyway, you might as well skip the embed and just run the query directly, which this plugin allows you to do.

```
{exp:channel:entries channel="series" status="open|hidden" url_title="{segment_2}" dynamic="off"}
    {reverse_related_entries status='open|hidden' orderby='date' sort="desc" limit='1'}
        {exp:more_entries entry_id="{entry_id}" status="open|hidden" dynamic="off"}
            {whatever_field_here}
        {/exp:more_entries}
    {/reverse_related_entries}
{/exp:channel:entries}

```

Note that this still won't let you parse the same channel in the nested more\_entries loop because the outer {exp:channel:entries} will replace all of the fields before the plugin gets a chance to do it. I'll work on a version that works around this - it should be possible - but you'd need to still use Stash or an embed if you need to relate entries to their same channel.
> 1 votes

---
Tags: ee2, relationships
---


# Question
Title: How to store temporary data for a user just for their session?
I need to allow a user to add articles to a wishlist that they can then e-mail or print. The data doesn't need to be saved or last longer than their session.

Is there a native EE way of doing this without writing a plugin myself? Or can anyone recommend a plugin that they know does this and that they have experience with please?

# Answer
> 5 votes
I would try a 3rd party favorites/bookmark addon like Remember Me. Then you would need to dump that info into a form to send off in an email or print.

# Answer
> 6 votes
Session Variables is a great little plugin and we've used it without any issue. Easy to setup and does what you need.

# Answer
> 5 votes
It's pretty easy to save user-scoped data in Stash; by default this will expire at the end of the user's session. You could save just the entry ids or the whole entry.

```
{exp:stash:append_list name="wishlist" save="yes" replace="yes"}
{stash:entry_id}67{/stash:entry_id}
{/exp:stash:append_list}

```

# Answer
> 1 votes
i have happily used http://devot-ee.com/add-ons/remember-me a few times. super easy to work with, and to configure. did not use session variables yet though

---
Tags: sessions
---


# Question
Title: Is it possible to modify the output of pagination urls?
I'm currently using the following code for pagination:

```
{pagination_links}
    {page}
        <a href="{pagination_url}">{pagination_page_number}</a>
    {/page}
{/pagination_links}

```

Because of an addon I'm using, I need to modify the output of the {pagination\_url} variable.

{pagination\_url} outputs http://sitename.com/blog/P20, and I need to add a segment before blog.

I attempted to use the Find and Replace Plus addon, but due to the parse order, I'm not able to use the {site\_url} variable to find/replace.

Is there an easier way to accomplish this?

# Answer
If you just need to modify the part of the URL before the pagination segment (and your use case is relatively simple) you can use the `paginate_base` parameter on your entries loop (docs here):

```
{exp:channel:entries paginate_base="blog/foo"
  {pagination_links}
    {page}
        <a href="{pagination_url}">{pagination_page_number}</a>
    {/page}
  {/pagination_links}
{/exp:channel:entries}

```

Now your output should look like this: `http://example.com/blog/foo/P20`
> 13 votes

# Answer
If you're feeling brave, you can also head to:

system/codeigniter/system/libraries/Pagination.php

All of the opening and closing elements are there and you can override them. Just make a note of those changes so you can restore them after an upgrade.
> 1 votes

---
Tags: ee2, channel, pagination
---


# Question
Title: Add items to a User via front end tags, (ie. travel Itineraries)
I'm working on a travel site and one of the requests is to create user itineraries. I was planning on using Zoo Visitor for some of the user functionality, but wondering if there is any add-ons that I could use to allow a user to just click a button on an event/attraction and have it added to an itinerary tied to their account.

One potential option might be to have a Safe Cracker on each page and have all the field be hidden. Then when they click the button, have that submit a form which would create an itinerary item which would relate to the user. Are there any better/simpler solutions? Checked devotee and couldn't find anything that seemed to match, but I could be missing something.

# Answer
Looks like you want a favorite/bookmark addon. Check out Remember Me or others depending on your specific needs. ie. saved to session, save to member account, etc.
> 4 votes

# Answer
Personally I would go with Solspace Favorites. I've used a different method with safecracker but it's a bit more complicated and time-consuming.
> 1 votes

# Answer
I was looking at this today, it might just be the thing you need! - http://squarebit.co.uk/shortlist
> 1 votes

# Answer
Shortlist was built for a tourism site specifically for a users itinerary, it does not require a member to be logged in to use it. The dev (Joel) is very supportive and there's a nice little demo here: http://shortlist.squarebit.co.uk/
> 1 votes

# Answer
My personal recommendation is Solspace Favourites for this. We've used it for "wish lists" which could work as travel itineraries (if you're not too concerned about the time component).
> 0 votes

---
Tags: safecracker, users
---


title: Listing entries, ordering by Category

text:
# Question
Title: Listing entries, ordering by Category
I want to list a channel's entries by category. It's a kind of hybrid of using EE's **category\_archive** tag but inside of **exp:channel:entries**. I have an ugly solution (shown here); it violates every DRY principle out there, but I don't know how to do it better.

The channel is a glorified list of links with explanation text and image.

---

*The results I'd like to have:*

**Resource Page Title heading H1**

**Category A H2**
Resource Link 1
Another Resource Link
And another

**A different Category H2**
Resource Link
Yet Another one
One more here

etc.

---

*How the channel fields are set up:*

{title} (obviously)

**Channel fields**
{resource\_url\_link} — *Link to destination website*
{resource\_src\_logo} — *Destination website logo*
{resource\_rte\_blurb} — *Brief description of destination site*

Note: {title\_url} has no business in this channel. At all.

---

Option I considered but rejected:

Category Archive (link to EE Docs): Limited to only entry title and a path or entity akin to title\_url, which will not work.

---

*Ugly workable code/tags I'm using at the moment*

(It is ugly, it violates DRY/Don't Repeat Yourself, but the total number of categories are limited so it's doable.)

For each category (see H2 tags), I hand-code category ID in the low\_title item, and match that ID in the subsequent exp:channel:entries.

```
<h2>{exp:low_title:category category_id="7"}</h2>
    {exp:channel:entries channel="resources" disable="pagination|member_data|category_fields" category="7"}
    <div>
        <div><img alt="{title}" src="{resource_src_logo:medium}"></div>
        <div><h3><a href="{resource_url_link}">{title}</a></h3>{resource_rte_blurb}</div>
    </div>
    {/exp:channel:entries}

<h2>{exp:low_title:category category_id="10"}</h2>
    {exp:channel:entries channel="resources" disable="pagination|member_data|category_fields" category="10"}
    <div>
        <div><img alt="{title}" src="{resource_src_logo:medium}"></div>
        <div><h3><a href="{resource_url_link}">{title}</a></h3>{resource_rte_blurb}</div>
    </div>
    {/exp:channel:entries}

```

Do you know how I can do this better?

# Answer
I had the same problem and found that the Stash solution was the best approach for this.

```
{exp:channel:entries channel="resources" dynamic="no" disable="pagination|member_data|category_fields"}
{exp:stash:append name="resources_{categories limit='1'}{category_id}{/categories}" parse="inward"}
 <div>
    <div><img alt="{title}" src="{resource_src_logo:medium}"></div>
    <div><h3><a href="{resource_url_link}">{title}</a></h3>{resource_rte_blurb}</div>
</div>
{/exp:stash:append}
{/exp:channel:entries}

{exp:channel:categories channel="resources" style="linear" disable="category_fields" show_empty="no"}
    <h2>{category_name}</h2>
    {exp:stash:get name="resources_{category_id}"}
{/exp:channel:categories}

```
> 9 votes

# Answer
If you're not opposed to using an add-on ee-garage's http://ee-garage.com/nsm-categories does exactly what you describe.
> 3 votes

# Answer
I'm not too sure on how to make the underlying code better - but the first way you could make this DRY would come with a bit of a performance hit

You could take the below and set this as a new template

```
<h2>{exp:low_title:category category_id="{embed:id}"}</h2>
{exp:channel:entries channel="resources" disable="pagination|member_data|category_fields" category="{embed:id}"}
<div>
    <div><img alt="{title}" src="{resource_src_logo:medium}"></div>
    <div><h3><a href="{resource_url_link}">{title}</a></h3>{resource_rte_blurb}</div>
</div>
{/exp:channel:entries}

```

And then in your existing template call it in such a fashion...

```
{embed="_embeds/.category-info" id="7"}
{embed="_embeds/.category-info" id="10"}

```

That would work pretty nicely, but as mentioned would have a performance hit with the embeds being used to this degree. That said, this is a nice example where embeds' ability to parse parameters is a nice thing.

---

My next method is completely made up, I'm not sure if any plugins exist to allow this but if they do you could achieve the same with less of a performance hit.

Firstly, we could set a Preload Replace variable of a comma separated values of the IDs you wish to use...

```
{preload_replace:pre_categories="7,10"}

```

Now, we would have a new snippet, for examples sake I'm calling this `{sn_category-info}`

```
{exp:counter:increment} {!-- this made up plugin would +1 each time the snippet is called --}
<h2>{exp:low_title:category category_id="{exp:comma_seperated:grab x="{exp:counter:return}" values="{pre_categories}"}"}</h2> {!-- This made up plugin would take the current count position, the comma separated list and find the x'th value, so on the first run 7, on the second 10 --}
{exp:channel:entries channel="resources" disable="pagination|member_data|category_fields" category="{exp:comma_seperated:grab x="{exp:counter:return}" values="{pre_categories}"}"}
<div>
    <div><img alt="{title}" src="{resource_src_logo:medium}"></div>
    <div><h3><a href="{resource_url_link}">{title}</a></h3>{resource_rte_blurb}</div>
</div>
{/exp:channel:entries}

```

A bit hypothetical, I understand, but those plugins should be relatively simple to write and I think it'd be pretty damn DRY and fast!
> 2 votes

# Answer
This is exactly what I wrote Category Entries for - you tell it what categories you want to list entries for, and it sorts them by the order that you specify. Omitting the list of categories simply ends up sorting by whatever categories are on the entries. The tag is otherwise identical to the {channel:entries} tag.

You end up extracting category information from the entries' {categories} loop, or through other mechanisms such as Category Info.

Example code to sort entries by three specified categories:

```
<ul>
  {exp:category_entries category="2|3|1" orderby="date"}
    <li>{title} {categories}{category_name}{/categories} - {entry_date}</li>
  {/exp:category_entries}
</ul>

```

If you need anything added to the tag, you can post a request in the support forum for it and I will add it.
> 2 votes

# Answer
This is the use case for which I wrote Category Sorted Entries Lite (free) and, later, Category Sorted Entries (commercial).

Check them out, as I think they'll accomplish what you need.

n.b. NSM Categories is another great add-on with very similar functionality. It handles advanced custom fields (Matrix/Playa) a bit better, but doesn't include as many options for sorting and filtering by different category groups.
> 1 votes

---
Tags: categories
---


# Question
Title: What do you need to do to make a Fieldtype Addon SafeCracker compatible?
I've built a Fieldtype Addon and have a request to make it SafeCracker compatible.

The docs are not very clear on how to achieve this.

http://ellislab.com/expressionengine/user-guide/modules/safecracker/development.html#section\_getting\_it\_to\_work

I am including my own JS files for EE's CP and this works, if I add the JS file to the theme's folder will SafeCracker just work?

# Answer
So long as you are using those approved methods for adding JS and CSS for your fieldtype, and your end-users aren't using `safecracker_head="no"`, yes, it will indeed work.
> 4 votes

# Answer
Just try adding your fieldtype to a Safecracker field and see whether you have any problems. Look for php errors, and javascript console errors.

Generally, the main issues you will run into will either be loading static css/js files which aren't accessible outside the control panel, or calling php functions which aren't accessible outside the control panel.

For example, a fieldtype I added Safecracker support to was making an AJAX call to a method on my mcp file. I had to change this to a regular EE action so that it could be called from outside the control panel.

One final thing to watch for is making sure your fieldtype looks alright with a white/different color background.
> 0 votes

---
Tags: add-on, add-on-development, safecracker
---


# Question
Title: Renaming system directory if directory is outside root?
What's the general consensus regarding the renaming of the system directory if it resides above root? I was recently updating my default EE install to initially start with the directory above root and thought that it was overkill. It seems to me that if someone discovers the system directory when it's above root you have much bigger problems to worry about. Is renaming the system directory overkill or should I rename both the admin.php file AND the system directory?

# Answer
We setup a folder called "private\_ee" (to compliment "public\_html") above the web root which contains directories for snippets, system, templates, and third\_party. As you said, if someone gets access above the web root, you've got bigger problems.

In other words, there's no need to rename it for security's sake; the security advantage you obtain is gained by moving it above the web root, not by obscuring the path.
> 7 votes

# Answer
It doesn't hurt to do both and takes literally five minutes.

If you started out like probably most people with the system directory below root, you probably already have an alternate name convention. Rather stick to it.
> 2 votes

# Answer
Renaming the **system** directory if it's located above your web root makes absolutely no difference in terms of security or anything else. If someone gains access to your server above web root, you're pooched regardless.
> 0 votes

---
Tags: config, system
---


# Question
Title: Javascript errors when using Exp-resso Store with requireJs
We are trying to setup Store in /webshop and are using RequireJs to setup the deps for each main part of the site.

When loading a page with (from what i can see) any of Store's own javascripts, forms and such 1-2 errors are thrown. I am guessing the first one has to do with the storeJs not liking that we are loading requireJs.

```
Uncaught ReferenceError: accounting is not defined

```

> Update: The error above breaks every page where Store's JS is used when i use require-jquery.js

And the other one is thrown from require.js.

```
Uncaught Error: Mismatched anonymous define() module: function (){return n}
http://requirejs.org/docs/errors.html#mismatch

```

I load a combined requirejs+jquery build (tested with a clean build) in the head of every page using js and require that pages specific .js in the footer.

The error seems to originate från **line 338 in themes/third-party/store/store.js** Adding an id to the define method seems to supress the warning but i cant say for effects elsewhere.

Has anyone had the same problem or know of a solution?

# Answer
> 3 votes
I had the same problem in another context, so I don't know if this will help. I had the problem using safecracker with its own JS loader. The only thing that worked for me was to load my own js (in this case jquery) and set the safecracker parameter to "no" to stop it loading its own.

As an aside, I lament the lack of a unified approach to integrating common scripts like jquery and Requirejsj. Most of my sites end up with multiple copies spread about the place between EE code, add-on codes and my own code. There must be a better way.

---
Tags: add-on, expresso-store, javascript, requirejs
---


# Question
Title: How do you prevent being logged out of the control panel?
One of my clients' irritations is being logged out of the control panel when he has left his session idle for a few hours. How can I prevent this?

# Answer
> 14 votes
If for some reason you need to use sessions, you can change the session time with a config variable

http://ellislab.com/expressionengine/user-guide/general/hidden\_configuration\_variables.html#cp-session-ttl

```
$config['cp_session_ttl'] = 86400; // Keep admins logged in for one day!

```

# Answer
> 10 votes
Try changing the Control Panel Session type to Cookies Only: http://ellislab.com/expressionengine/user-guide/cp/admin/security\_settings.html

# Answer
> 2 votes
I use the following code within the config.php file that is located at /system/expressionengine/config/config.php.
And you have to set "cookies" in your security preferences.

```
// Cookie Settings
$config['cookie_prefix'] = "";
$config['cookie_domain'] = '.yourdomain.com';
$config['admin_session_type'] = 'c'; // if c does not work try 's' (session)

// logout time controlling: it's best to set only cookies in security prefs
// be sure to set cookies domain as well
$config['user_session_ttl'] = 14400; // user session
$config['cp_session_ttl'] = 14400;  // control panel session

```

This works quite well! Cheers outline4

# Answer
> 2 votes
I'd prefer to just up vote MediaGirl's comment, but since I don't have enought rep yet to do that I'll just say that we did the two things recommended here: 1) switch to cookies only and 2) up the cp\_session\_ttl and that seems to have worked best for us. Probably didn't need to set both, but it worked regardless.

# Answer
> 1 votes
I was under the impression the staying logged-in problem was a known bug. As recently as 3 months ago complaints were still showing up on Ellis Labs official support forums, and that seemed to be the standard response.

# Answer
> 1 votes
John D Wells mentioned this on his site, not me, but "as of EE 2.2.*somethingorother*, there are two new hidden configuration variables that allow you to control the session length of both CP users and front-end visitors. See **User Session Length** and **Control Panel Session Length** for more."

Here's a link to the "Hidden Configuration Variables" page: http://ellislab.com/expressionengine/user-guide/general/hidden\_configuration\_variables.html

# Answer
> 1 votes
This is somewhat tangential, but I highly recommend your client use something like 1password to manage credentials instead of staying logged in for a long time,

---
Tags: control-panel, sessions
---


# Question
Title: 404 error when trying to access a template with an beginning underscore _ after upgrading to 2.5.3
I'm running into this strange issue I've never seen before. I have a template that starts with an underscore, I'm using it to pull in some results via ajax.

After upgrading to 2.5.3 and only on my local machine, I'm getting a 404 response when I try to access the template. Going to view the file in Template Manager, it seems like now every template that's starting with an underscore is grayed out.

Any idea what's going on here?

# Answer
Do you have `$conf['hidden_template_indicator'] = '_';` set? This could be causing the issue
> 6 votes

---
Tags: templates, ajax
---


# Question
Title: Assigning member group at same time as activating Pending member
I have a site in which each member group has (of course) a different set of viewing and posting privileges. It is also set up to place new membership requests into Pending, until manually activated by the site admin -- at which time the applicant receives an email informing them that their account is active, and the member's account moves from Pending to the default group, Member\_group\_X. All this is, of course, completely normal EE out-of-the-box behaviour.

What I have not found, either natively or via an add-on, is a way to assign a new account to a different (non-default) member group *at the time that it is manually activated by the admin*. Not having this ability risks letting the newly-activated member log-in before the admin has had a chance to move them to the correct member group, thereby exposing information that should be hidden.

Does anyone have a way of combining the 'Activate Pending members' process with the 'moving a member to a different group' process?

# Answer
> 5 votes
I'm pretty sure that the Solspace User Module allows you to assign a specific 'on activation' member group for new registrations created through the modules front end tags. When approved the user is then automatically moved to the relevant group.

# Answer
> 3 votes
You can always edit the member directly, click on Member Preferences in the left hand menu and change them from Pending to whatever member group they should belong to. (Instead of following the usual Activate Members admin routine.)

# Answer
> 0 votes
Unfortunately, your only hope here was the cp\_members\_validate\_members extension hook. But alas, it gives you no access to the information you might need about which members were just validated.

---
Tags: ee2, control-panel, members
---


# Question
Title: How can I show multi-lingual front end system messages?
I have a MSM set up with site A in english and site B in chinese. What I'd like is for the system messages on site B to show in chinese rather than english (think "Thanks - you're now logged in" etc, etc).

Does anyone know if that's possible and if so how?

Cheers in advance,

Jim

# Answer
If you use this method then I have the perfect solution. the missing piece I was looking for so long!

In fact you have to find a way on how to trigger a) language related messages from add-ons, and b) language related messages AND emails from expressionengine itself.

you can do that by adding two variables within the index.php file, just before "END OF USER CONFIGURABLE SETTINGS":

a)

```
// $assign_to_config['language'] = 'deutsch';

```

(attention, when activating this, you have to translate all of your add-ons, or at least, duplicate the language folders. )

b)

```
// overrides the default language for expressionengine (use the name of the language folder)
$assign_to_config['deft_lang'] = 'deutsch';

```

this is much more important and will set the language of system messages and emails!

(for multilanguage emails you have to go to: "design -\> message pages -\> email notifications" and de-check the checkbox for each template: "*Enable This Template? If disabled, this template will not be used. Instead, the message will be generated dynamically in each user's chosen language*"

good luck! stefan
> 3 votes

# Answer
Check out the Custom System Messages addon: http://devot-ee.com/add-ons/custom-system-messages

This lets you move EE system messages into EE templates so you can have finite control over messages.
> 8 votes

# Answer
We always use this Multi Language Module for things like these: http://devot-ee.com/add-ons/multi-language-module

This allows you to create "phrases" in your backend and provide different translations.

You can ouput these in your template like this:

```
{exp:multi_language:phrase index=“phrase_name”}

```

Depending on the user's language this will output the correct translation. The user’s language is determined by the url. So for a webpage at mysite.com/links/ the italian version will be at mysite.com/it/links/. This makes for easy navigation and setup in ExpressionEngine.
> 3 votes

# Answer
I don't think you need an add-on for this, you can set the default language per MSM site.
> 2 votes

# Answer
I'm with Media Girl on this one. I use Custom System Messages to display all error pages and i've never looked at another solution. It's simple and effective.
> 1 votes

---
Tags: multilingual, system, messages
---


# Question
Title: What is the best method for exporting channel entries as a spreadsheet?
My client has asked me to export all data as a spreadsheet. This includes playa and matrix data. What method would you suggest for accomplishing this?

# Answer
For the sake of completeness you can create a spreadsheet by outputting a simple HTML table.

You can use regular {exp:channel:entries} tag loops to output your table rows and some PHP as shown in another answer to get this to download as an Excel file rather than be rendered in the browser.

```
<?php
    header("Content-type: application/vnd.ms-excel");
header("Content-Disposition: attachment; filename=myFile.xls");
header("Pragma: no-cache");
header("Expires: 0");
?>
<table>
<tbody>
{exp:channel:entries channel='myChannel' limit='500' disable="categories|member_data|pagination|trackbacks" status="not Closed"}
    <tr>
            <td>{first-field}</td>
            <td>{second-field}</td>
            <td>{third-field}</td>
            <td>{you-get-the-idea}</td>
    </tr>
{/exp:channel:entries}
</tbody>
</table>

```
> 16 votes

# Answer
How much data? I am not a programmer, so I would accomplish this with a template - here's an example. PHP is on on output.

```
<?php
$output_file='nameofmyexport.csv';
header("Content-type: application/download");
header('Content-Disposition: attachment;filename="' . $output_file . '"');
?>
"Item name","Title","Date","Some data","Status"
{exp:channel:entries limit="500" channel="channel-name" disable="categories|member_data|pagination|trackbacks" status="not Closed"}"{item-name}","{title}","{entry_date format="%F %d %Y"}","{some-data}","{status}"
{/exp:channel:entries}

```

This is just an edited example of a template that I have in use, yours would likely have more content fields and it would output your playa and matrix data. For the CSV, you have to have all of your tags squished together so that the output is in one row. Your hard returns have significance. This always requires a bit of trial and error for me.

If I needed a very large quantity of data, I'd need to paginate this into multiple files. I have a limit here of 500 but that may be too much for some situations.
> 7 votes

# Answer
I've done with just using a template and the native channels tags. You can configure it to any output you'd like. Then just saves the results to a file. I used XML since you can nest nodes (ie. matrix fields) and it's easy to import back in with DataGrab

Use the limit and offset params as needed

```
<?xml version="1.0" encoding="UTF-8"?>
<products>
{exp:channel:entries
   channel="products"
   disable="category_fields|member_data|pagination|trackbacks"
   dynamic="no"
   limit="150"
   offset="450"
   require_entry="yes"
}
   <product>
      <name>{title}</name>
      <categories>{categories backspace="2"}{category_name}, {/categories}</categories>
      <model_num>{product_ci_model}</model_num>
      <product_description>{if product_description}<![CDATA[{product_description}]]>{/if}</product_description>
      <product_sizes>
         {product_sizes}
         <item>
            <model>{model_num}</model>
            <length>{model_length}</length>
            <width>{model_width}</width>
            <height>{model_height}</height>
         </item>
         {/product_sizes}
      </product_sizes>
      <colorchart_file>{product_color_chart}</colorchart_file>
      <images>
      {product_images}
         <item>
            <alt>{img_alt}</alt>
            <file>{img_file}</file>
         </item>
      {/product_images}
      </images>
      <product_size_headings>
         {product_size_headings}
         <item>
            <length>{heading_length}</length>
            <width>{heading_width}</width>
            <height>{heading_height}</height>
         </item>
         {/product_size_headings}
      </product_size_headings>
      <youtube_url>{youtube_video}</youtube_url>
   </product>
{/exp:channel:entries}
</products>

```
> 4 votes

# Answer
I've had great success with Export It. It handles all manner of third party fieldtypes, and support is phenomenal. The cost is worth the time it will save you in trying to construct an error-free export template.
> 4 votes

# Answer
In addition to foamcow answer (which is exactly how I do it). Here's some extra fruity code.

* Add a date to the file name.
* IE can cause problems.
* As it's just HTML, use the segment as a 'switch' to output as a page or download file. Handy when building your export.

```
>    $date = date('Y-m-d_G-i');
>    $export=$IN->fetch_uri_segment('3');
>
>   if($export)
>   {
>       if (strstr($_SERVER['HTTP_USER_AGENT'], "MSIE"))
>       {
>           header('Content-Type: application/octet-stream');
>           header('Content-Disposition: inline; filename="custom_name_'.$date.'.xls"');
>           header('Expires: 0');
>           header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
>           header('Pragma: public');
>       }
>       else
>       {
>           header('Content-Type: application/octet-stream');
>           header('Content-Disposition: attachment; filename="custom_name_'.$date.'.xls"');
>           header('Expires: 0');
>           header('Pragma: no-cache');
>       }
>   }
>?>

```
> 4 votes

# Answer
Is this just channel data?

I've always been a fan of using Zenbu for displaying channel data in the control panel, and now Zenbu Studios has released Hokuku (http://zenbustudio.com/software/hokoku) which allows for exporting saved Zenbu searches in different formats, including CSV.
> 3 votes

---
Tags: export
---


# Question
Title: Channel Entries tag not recognizing passed params
For some reason my Channel Entries tags aren't recognizing the passed parameters consistently. For example, the below works on the home page but not on any internal pages:

```
{exp:channel:entries channel="files" entry_id="12"}

```

# Answer
Try adding `dynamic="no"` parameter. Does that fix it?
> 11 votes

---
Tags: channel-entries
---


title: How to strip white space in EE?

text:
# Question
Title: How to strip white space in EE?
I'd like the rendered markup to be absent any carriage returns, line feeds, or tabs. I'm looking for a functionality similar to Smarty's `{strip}` tag. Does EE have this?

# Answer
> 7 votes
not natively but something like http://devot-ee.com/add-ons/hacksaw could easily do what you need. There's also http://devot-ee.com/add-ons/supergeekery-tag-stripper as well as some commercial add-ons that also give this kind of functionality.

# Answer
> 8 votes
How about John Wells' Minimee? http://johndwells.github.com/Minimee/

It minifies the rendered HTML (EE 2.4+), and as far as I know, that's what you're looking for? I've only used it for CSS/JS and it works fabulously for that.

# Answer
> 2 votes
A plugin is not really appropriate for this usage since you would need to wrap every root-level template you have with said plugin. Instead, you should write an extension which does the following:

1. Check if the PHP constant REQ == 'PAGE', if not, do nothing
2. Register a shutdown function
3. Turn on output buffering
4. In the shutdown function, capture the buffer
5. Turn off output buffering
6. Run your regex on the resulting page text and print it

I have used this technique to accomplish several similar requirements.

# Answer
> 1 votes
Remember, **you need to be careful stripping all whitespace from HTML**, especially HTML generated by a CMS/where you can't be certain of the origin of every line of markup (eg some of it comes from WYSIWYG fields etc).

Although commonly thought of whitespace agnostic, HTML is a fragile language and some of that whitespace might well actually be significant, for example content in `<pre>` or `<code>` elements. There's also CSS like as `white-space: pre` to bear in mind. This sort of thing can be a nightmare to debug.

If you're doing this for the purposes of reducing the size of the pageload sent to the client, I'd argue you are far better off enabling gzip (with `mod_deflate` or similar) to this end, as with gzip enabled the benefits to payload size of stripping whitespace are often not worth the trade off in increased fragility/unpredictability of output.

# Answer
> 0 votes
Have you considered/tried PHPStringFun (documentation)? With it you ought to be able to use PHP's native trim.

Something like the below perhaps?

```
{exp:phpstringfun function="trim" par1="\r"}
{exp:phpstringfun function="trim" par1="\n"}{html}{/exp:phpstringfun}
{/exp:phpstringfun}

```

Maybe just one `\r\n` would do, I dunno.

---
Tags: templates, template-scripting
---


# Question
Title: Clustering two identical markers in Google Maps for EE
I'm using the clustering feature in Google Maps for EE version 3.0.190 to plot people on a map, but have a problem as some people have the exact same coordinates as they're based at the same address.

I'm finding that the clustering marker shows this as 2 points, but as I keep zooming in, they never split. Until eventually, at the very last zoom level, the marker disappears completely.

Is there a way to work around this at all?

Here's the code I'm using:

```
{exp:gmap:init id="map1" class="gmap" scrollwheel="false" style="width:930px;height:700px" clusterStyles="{url: '/assets/images/cluster-icon-blue.png', textColor: '#fff', textSize: '12', height: 52, width: 53, anchor: [0, 0]}" overviewMapControl="true" overviewMapControlOptions="{opened:true}" zoom="6" center="Silecroft"}

{exp:channel:entries channel="people" status="open" disable="categories|category_fields|member_data|pagination" limit="1000" dynamic="no" sort="asc"}
  {cf_people_geo_location id="map1" show_one_window="true" icon="/assets/images/map-icon-white.png" infobox="true" offsetY="0" offsetX="15" closeBoxMargin="5px" class="ui-infobox-dark" closeBoxURL="/themes/third_party/gmap/css/images/white-close-button.png" style="width: '250px'" clearanceX="10" show_one_window="true" clustering="true" extend_bounds="false"}
    <h3><a href="/people/{url_title}/" title="View {title}">{title} »</a></h3>
  {/cf_people_geo_location}
{/exp:channel:entries}

```

# Answer
> 2 votes
Currently this is the default behavior of MarkerCluster v3. Using the duplicate\_makers="false" should work, but you tested it and said it did now, but even if it did, it's not the desired functionality anyway.

Currently the only way to work around this would be to write some of your own JavaScript to slightly offset each duplicate location. Given that the core add-on uses procedural JS to plot markers, it would be difficult without completely rewriting your own methods (which I have done).

I even wrote some custom JS to make the infowindow content different it has more than 1 entry in the same location. This is always a possibility, but again, requires writing your own JS.

I will definitely keep this in mind for a future release.

---
Tags: google-maps
---


# Question
Title: How do you prevent admins from being locked out of the control panel even with correct password?
This has been a continuous issue with ExpressionEngine - admins having to clear their cookies to login to the site.

Even when typing in the correct username and password, the user is return back to the control panel login page with no error message. How do you prevent this?

# Answer
> 7 votes
I think this has to do with secure forms being enabled. I've noticed that sometimes when I hit the CP my browser will load a cached version of the page. The problem though is the hidden XID form field will have an expired value so submitting the form causes the POST to be invalid and the page refreshes requiring a second login attempt.

# Answer
> 7 votes
Typically I've found this to be caused by logging into the same site in multiple environments. For example - widgetsite.com, dev.widgetsite.com, and widgetsite.dev. The cause seems to be ExpressionEngine getting confused by the cookies from one version of the site when accessing another. I've only found two solutions to the problem. The first is to clear cookies as you're already doing. The second is to use a different browser for each version to avoid cookie conflicts.

All of this, of course, only applies if you're referring to an environment like I'm describing. If not then this won't help you.

# Answer
> 5 votes
The dynamic IP issue was fixed in EE 2.5.0 I believe \- but I recently ran into this issue due to the server having an incorrect time set, causing sessions to immediately expire after they were created.

The fix was to have my host set the correct server time.

# Answer
> 1 votes
I've added these config overrides to my master config file and haven't had any issues logging in:

```
// Cookie Settings
$env_config['cookie_domain']            = $_SERVER['HTTP_HOST'];
$env_config['cookie_path']              = '';
$env_config['cookie_prefix']            = ENV . '_';

```

---
Tags: control-panel, login
---


# Question
Title: Channel entry notification isn't working on entries created by SafeCracker
Channel entry notifications are not working on new entries generated by SafeCracker. This seems to be a recent development, as the notifications were working previously. The only change has been in updating EE versions and a change to the client's SMTP servers. We tried switching to PHP and Sendmail, and now are working with a new SMTP account.

I believe I've narrowed it to a problem between SafeCracker and the channel. Email notifications are working via FreeForm and Tools \> Communicate.

Strangely, I did receive 2 new entry notifications via the forms submitted by real users, but the client (whose email address was also in the recipients list) did not, and I was unable to replicate success using test form submissions.

Channel entry notifications do work just fine when manually adding a new entry in the Control Panel.

Has anyone experience something similar to this, or have any ideas about what might be preventing notifications from being sent?

EE version 2.5.2

# Answer
After changing the email method to IMAP, and creating a new user to test from, the notifications began coming through again. Not sure what exactly broke it loose, but wondering if it was an issue with the mail server after all.
> 1 votes

# Answer
The entries API notifications are triggered at around line 1858 of Api\_channel\_entries.php. A few `var_dump()`s in that area should be enough to determine a) whether the notifications are being triggered at all and b) where the system is attempting to send them to.
> 3 votes

---
Tags: safecracker, channel, entry, notification
---


title: Config Bootstrap Options

text:
# Question
Title: Config Bootstrap Options
Which config bootstrap options are available for ExpressionEngine? Which one works best in a multi server environment?

# Answer
> 15 votes
I can recommend Focus Lab's EE Master Config. It's easy to set up and easy to add options to as needed and it is perfect for multi server environments.

I usually don't bother with the multi server set up, and am just building the site on a subdomain and then just transferring to the live domain. But even in this basic case, the master config makes going live quicker and easier.

# Answer
> 12 votes
Solutions mentioned in the thread are all nice, but I think you learn a lot by creating your own config bootstrap. To that end, I found the following resources can help a great deal:

Armed with those, it is easy to create bootstrap config files that will suit your needs.

# Answer
> 6 votes
The NSM Bootstrap technique has never let us down in multi-server environments.

# Answer
> 6 votes
Many options are available as stated in other posts.

To add to that here is the default config.php & database.php file templates for ExpressionEngine we use.

# Answer
> 4 votes
I built my own config file, because I had a setup that most of the prebuilt configs didn't have... My normal setup is, Local, Staging (Located on subdirectory, inside a folder) and then Production.

A lot of hooks were added for NSM .htaccess, CE Image, CE Tweet etc...

Just pushed the latest version of it to my Github.

https://github.com/madebymayo/ExpressionEngine-Environment-Config

# Answer
> 4 votes
I'll second tidy's vote for the Focus Labs EE Master config. We are using it in a multi server deployment set up and it's awesome. Saves lots of time and I no longer worry about code deploying out with the wrong environment configs.

# Answer
> 3 votes
Agreed with building your own. I built my own then modified FL's EE Master Config to suit my needs. Super flexible and it is really nice having a plug-and-play EECMS install ready to be loaded on to any server.

If you are using multiple environments then use something like Deeploy Helper to get URL's/Paths stored in the DB updated when you migrate http://www.hopstudios.com/software/deeploy\_helper

# Answer
> 3 votes
Focus Lab's Master Config also supports MSM (with the aid of this gist).

---
Tags: bootstrap, config
---


# Question
Title: What add-on/method do you use to create snippets as files?
For version control purposes, it's better to store snippets as files. What add-on or method would you recommend?

# Answer
We use **Snippet Sync** (http://devot-ee.com/add-ons/snippet-sync) almost exclusively now for our repeatable snippets ... we also use Low Variables (as mentioned by aelvan, but not so much for 'snippets' but more for the content that the users need to edit infrequently.

We tend to use snippets for sections of repeatable HTML/EE code (for example we may create an address snippet, that has the HTML tags to FORMAT the Low Variables CONTENT ... then we can use that snippet in the footer, on the contact page, etc).

Hope that this has helped.
> 11 votes

# Answer
Low Variables FTW.

It combines global variables, snippets and embedding templates all into one addon that also gives you flat files for snippets and global variables. You can also easily hide some variables from the client - great for code snippets that are developer only.

Finally low variables has many variable types including compatibility with wygwam, matrix, and other popular field types. This makes it very easy for clients to manage content that is too small for a full on channel - say telephone numbers, various one off paragraphs across the site, home page sliders etc...

You really can't go wrong with Low Variables.
> 6 votes

# Answer
I use SnippetsSync (http://devot-ee.com/add-ons/snippetssync) to accomplish this on any site that doesn't use Low Variables.

Note that this is not the same as the confusingly similarly-named Snippet Sync already mentioned above! This one is free, and is less configurable with no extension settings, but has always worked very well for what I wanted it to do.
> 5 votes

# Answer
I use Low Variables when the project calls for it otherwise Libraree is part of my base isntall http://devot-ee.com/add-ons/libraree
> 3 votes

# Answer
Low Variables. It does a lot more than just that of course, but the ability to save to files and to select if it's early parsed or not, is gold.
> 1 votes

---
Tags: snippets
---


# Question
Title: A conditional to show if a entry has a playa parent or has entry in another channel with category?
Sorry for the convoluted question. Let me add some clarity to this:

I have a two channels: products & videos. On the videos channel I have custom field for a YouTube url along with a Playa field to relate the video to a specific product(s). I also tied the same category group the products channel is using to the video channel. I have this setup for two reasons:

1. Client can add a video to a category so this video is shown on all products pages with that category
2. Client has the option to relate the video to a specific product(s)

I realize I could potentially just use the Playa filter to get the correct entries and do a mass dump but I thought it would be a lot easier to just use a category if the video is a general overview of a certain product category.

How do I structure the conditional to show/hide if a video matches those options?

I'm using the awesome URL Helper addon for segment variables so I can easily do something like this on the single product page:

```
{exp:channel:entries
   category="{segment_2_category_id}"
   channel="videos"
   disable="category_fields|member_data|pagination|trackbacks"
   dynamic="no"
}
    show video stuff
    {if no_results}no video here{/if}
{/exp:channel:entries}

```

or use the Playa tag `{exp:playa:total_parents}` in a conditional. The problem is I need to check both before displaying the data

# Answer
> 3 votes
Well, I figured it out! I had to buy Entries Number add-on. This allowed me to find/search if any entries were tied to a certain category and return a number. Take note of the `{segment_2_category_id}` variable, this variable is from the URL Helper add-on I mentioned above. You could potentially use `{segment_category_ids_any}` to do an inclusive search also–which I'm using b/c I have true nested URI's `domain.com/products/parent_cat/sub_cat/entry`

```
{if {exp:playa:total_parents channel="videos"} > 0 || {exp:entries_number category="{segment_2_category_id}" channel="videos"}{entries_number}{/exp:entries_number} > 0}
    has video
{/if}

```

I'm still curious to see if anyone has any other solutions.

---
Tags: conditionals, categories, playa
---


title: DevDemon Updater Error or My Fault?

text:
# Question
Title: DevDemon Updater Error or My Fault?
I am using DevDemon Updater for the first time, so bear with me if I am being dense.

I updated the site from v2.3 to v2.5.3 last night along with Matrix and Wygwam. But for some reason, I noticed one of my templates is just white now.

I am looking the template over to see if `dynamic="no"` is getting me or what not, but it was working before the update, so I wanted to see if this has been experienced before.

Thanks.

# Answer
I don't think it is Updater or your fault. The issue is most likely that the new version of ExpressionEngine is causing an error on some older code. Turn on errors in your main index.php file and see what it gives you. It should be easy to debug from there.
> 6 votes

# Answer
This is very likely due to an add-on (or two) that needs to be updated for 2.4+ because of a change EllisLab made to the pagination class with that release. You can enable debiugging on the template to catch the name of the add-on in question, than make sure to update it.

I ran into this very issue only last week updating a site from 2.1.3 to 2.5.3. I had to update at least four add-ons because of the pagination issue. See pagination notes in the 2.4.0 changelog. Cuplrits for me were a few Solspace add-ons and a Pixel & Tonic add-on.
> 6 votes

# Answer
I have had that happen before where a template just died... I deleted it and restored from a backup template and, like magic, it worked.
> 1 votes

---
Tags: templates, devdemon-updater, updating
---


# Question
Title: Running subsections of a site through subdomains
Is it possible to run a subsection of a site, a blog for instance, from a subdomain (i.e. blog.mysite.com) and manage it from the same EE Control Panel without the use of MSM?

# Answer
> 6 votes
Yes. Copy the index.php from the main site and update the system path variable, and the following

```
$assign_to_config['template_group'] = 'your-template-group';
$assign_to_config['template'] = 'your-template';
$assign_to_config['site_index'] = 'http://blog.yoursite.com/';

```

# Answer
> 5 votes
Another option is having a faux subdomain mapped to a template group in the existing site via .htaccess.

For example:

```
RewriteCond %{HTTP_HOST} ^blog.mysite.com [NC]
#whatever exclusions you need for index rewrite:
RewriteCond $1 !^(images|themes|assets|media\/|index\.php|([a-z0-9-]+).html) [NC]
RewriteRule ^(.*)$ /index.php/blog/$1 [L]

```

This would need to go before the main site's index.php rewrite in the .htaccess.

Going to *blog.mysite.com/category-1* would really be accessing *www.mysite.com/blog/category-1*

It's likely not the most elegant solution, but I've seen it work well for a mobile site.

# Answer
> 4 votes
Another option is to serve all the domains out of the same set of files. This will point the primary and subdomain at the same file set. Then all you have to do is just check the $\_SERVER\['SERVER\_NAME'\] and set the config variables based on the different subdomains.

Its how I setup a mobile site in EE. Only one set of files, but I just changed a few vars (including template path) and was able to serve up a totally different template set, but using the exact same content, based on the server name.

```
if($_SERVER['SERVER_NAME'] == 'm.example.com'){
    $assign_to_config['template_group'] = '';
    $assign_to_config['template'] = '';
    $assign_to_config['site_index'] = '';
    $assign_to_config['site_url'] = 'http://m.example.com/';
    $assign_to_config['site_404'] = '';
}

```

# Answer
> 3 votes
The old method of running multiple sites still works as of the latest EE 2 release. To use that, you need an index.php for each site and you'd use the assign\_to\_config values for anything site-specific. For example, I have this setup for one of my subsites (it runs in a subfolder rather than a subdomain, but principle should be the same I believe):

```
$assign_to_config['template_group'] = '';
$assign_to_config['template'] = '';
$assign_to_config['site_index'] = '';
$assign_to_config['site_url'] = 'http://www.westeros.org/BoD/';
$assign_to_config['site_404'] = '';
$assign_to_config['global_vars'] = array('site' => 'BoD');

```

I basically just set a default site url to get the right base url for that site and then I define a site variable so that I can have two or more sites sharing my "News" template group, for example.

---
Tags: multi-site-manager, subdomain
---


title: Add-ons and front-end performance

text:
# Question
Title: Add-ons and front-end performance
One of the fun and powerful aspects I love about EE is using add-ons to make the content editing and creation experience excellent. However, I've also discovered that using an excessive amount of add-ons can really slow down the performance on the front-end. (While it's nice to have a speedy control panel, I am more worried about the website visitor experience.)

**What add-ons have you found really slow down front-end performance?** And is there anything about how these add-ons could be configured that you've found helps performance? I'm especially interested to know which of the *most common add-ons* you've seen be performance hogs.

# Answer
> 2 votes
This question impossible to answer without benchmark numbers to compare against some sort of community accepted standards for acceptable ranges (which don't exist.)

Also, any list you come up with would be constantly changing and may miss the point of using Add-ons (or of using PHP in general, which is slow than C.) The point of these add-ons is largely the reduce development time. In some cases, you need the functionality now, and you can work on performance issues later.

However, there are things you can do.

To identify performance issues, turn on your debugging and query output. Generally it's easy to see that a certain add-on is creating a an unacceptable number of queries or queries which are resource intensive.

If you do find such an add-on, then you can minimize the performance impact by using one of the many caching options (assuming a front-end template and data which doesn't have to refresh with every page load.)

Contact the developer of the add-on to optimize the add-on or have another developer build a different add-on.

One important point to keep in mind is that most add-ons serve very general purposes, and that may require more resource usage than an add-on which is much more targeted for your exact situation. Often I have used a resource intensive add-on to get the functionality ready for launch and then later built my own replacement to deal with the specific functionality of the site.

# Answer
> 0 votes
It more depends on HOW you use third-party add-ons, than on WHAT addons are used.

If your site expects heavy (or even medium) page load, always enable template debugging. Compare different options.

Have as few separate calls of same tag as possible (unless you're re-using results that was cached/stashed). Avoid too many embeds. Use "disable" parameter where applicable. Finally, use caching.

---
Tags: add-on, performance
---


# Question
Title: How to get pagination page number outside of its tags?
I want to avoid duplicate titles/descriptions on pages (P1,P2...) so I want to add Page 1, Page 2 in the page title.

Is there a way to know if we are on pagination and which page it is, but outside of pagination tags? Maybe Stash or something like that?

Thank you

# Answer
> 3 votes
I wrote a plugin a while back to do this. It was the first one I wrote so apologies in advance if it's not up to scratch.

Example is included in the plugin usage, but basically, place `{exp:page_number url_segment="{segment_1}" limit="5"}` somewhere in your template.

Parameters:

**url\_segment:** the segment which contains your page number
**limit:** the same value you have in your channel entries tag which limits the number of entries shown per page

# Answer
> 2 votes
With Stash, inside you pagination tag pair you could do:

```
{paginate}
    {exp:stash:set name="page_number"}
        Page {current_page}
    {/exp:stash:set}
    {!-- any other pagination stuff here --}
{/paginate}

```

Which would give you "Page X" accessible as `{exp:stash:get name="page_number"}`.

Another potential is to use Mo' Variables, which provides a Pagination Detect Conditional and Page Offset as `{if paginated}` and `{page_offset}`, respectively.

So for example

```
{if paginated}This is a paginated view{/if}

```

But I just realized `{page_offset}` isn't going to be quite what you wanted. It will give you some multiple of whatever you have in your `limit` parameter so will not directly give you "Page 1" "Page 2" etc.

---
Tags: stash, pagination
---


# Question
Title: Safecracker entry form, specifying categories across multiple pages
I have a multiple page Safecracker form, as there are a number of large category groups that need to be chosen from. On Page 2, I have a content type select. On Page 3, I have a topic select. And, on Page 4, I have a number of selects to reference syllabus documents.

The select fields look like this, that is the categories shown are being filtered by group\_id:

```
<select name="category[]" id="select_syll-ac" multiple="multiple" class="multiselect">
          {categories group_id="17"}
                  <option value="{category_id}"{selected}>{category_name}</option>
          {/categories}
</select>

```

Currently, only the options selected on Page 4 are making it to the final entry. I thought that previously the options selected on page 2 were also being retained.

preserve\_checkboxes=“yes” does not fix the behaviour.

Given Pages 2, 3 and 4 are all dealing with categories, do I have to add a hidden select of the category groups on Page 2 and 3 to Page 4?

# Answer
> 3 votes
You probably need to output the already checked categories in order to preserve the selection. You can output those categories in hidden fields in each pages:

```
{categories}
{if '{selected}' != ''}<input type="hidden" name="category[]" value="{category_id}" />{/if}
{/categories}

```

otherwise, on each submit containing the field category\[\], the categories will be reset to the new form values.

---
Tags: safecracker, categories
---


# Question
Title: Is there an easy way to import content from a site built with static files?
I have a site with a few hundred pages that I've inherited. It is all built with static html files, one file for every page. It's clear that the previous developer didn't really have a plan for the site as each page as many different elements that seem to be all randomly combined.

What I'd like to do is convert the site to be ExpressionEngine based. Building the site is no problem, but importing the content does not look like it's going to be very fun. Does anyone know if there is a way to some how scrape the main content of each page and get it into a form at that EE can use and do it all automatically?

# Answer
Consider Yahoo Pipes for scraping content from webpages. You can export it to a number of formats and then use Solspace's Importer or AJW's DataGrab to move it into place on EE. You can find an walkthrough on how to grab content via Pipes here:

http://www.daybarr.com/blog/yahoo-pipes-tutorial-an-example-using-the-fetch-page-module-to-make-a-web-scraper
> 6 votes

# Answer
It's a bit rough and ready but I wrote a EE 2.x plug-in to crib content from a static site we have to convert to EE. It had tons of news entries and there wasa common pattern in the markup we were able to leverage to scrape the content and insert it as a channel entry.

You may need to download/fork this and adjust to fit your needs.

https://github.com/ninefour/crib.pi.ee\_addon

Hope that's of some help. :)
> 4 votes

# Answer
One option would be to build a PHP parser that would take the site map and loop through each page, collecting the content in the main content div and saving that into the database (or CSV file with title and other fields that could be imported then via Data Grab).

As long as all the content is in the same main div, you should be good to go. You could even have it check for the first H1 on the page and have it save that as the Title field. If you want to get really fancy, you could also have the PHP file keep track of site hierarchy and import the necessary information for a structure.

You could start here for some information on some basic code samples for the php parser. https://webmasters.stackexchange.com/questions/2969/possible-to-only-load-specifiv-div-of-a-website

It may take a few hours to build the script, but I think it would be a lot quicker than copying all the pages over.
> 3 votes

# Answer
Using http://fuckyeahmarkdown.com/ with the readability option turned on may get you much of the way to getting just the content without the structure imported in markdown format.
> 0 votes

---
Tags: ee2, import, how-to
---


# Question
Title: Would it be confusing, and is it possible, to use Structure on only part of a site?
I am developing an EE site using the very useful Structure add-on for the first time. I want to make adding and editing content as easy as possible for my client. Currently I have a product section on the site where the client can easily add products by adding pages in Structure and it is very clear what they need to do. However, there is another section of the site which I can't currently see working with the same model.

Is it possible to develop/add data to part of a site without using Structure? If it is, would it be wise to do this when the client has a clear understanding of how to add/edit data to the section using Structure? Would this become too confusing for the client?

Thanks in advance.

# Answer
> 8 votes
Possible yes, easily, not overly confusing no, but sitting down with the client and explaining the use for 15 minutes would be really useful.

That said you do want to make things as clear as possible for the client and each client have different levels of experience and general nous / common computer sense. We normally make short video tutorials built into an accessory to explain things if they get lost. Generally though they don't refer to it much after initial training.

# Answer
> 5 votes
I normally use Zoo Flexible Admin to create a navigation that makes it obvious to the client how and where to edit the appropriate sections of their site.

In the case of a site with Structure, I'd usually have a 'Main Site Structure' nav item and then the remaining non-structure channels in nav items like 'News \> Add, News \> Edit, etc'.

# Answer
> 5 votes
We have built multiple sites where one 'area' is not managed by Structure. For example, we gave a member group access to one set of channels, which worked in a template group, inside which was a 'controller' template (powered by Switchee). This combination of entries and templates created 'microsites' for these users.

The rest of the site, which was mainly editorial content, was managed by Structure. As there was a clear delineation of the content, I don't think we had any problems re: different ways of managing entries.

So, in practice: If you create a template group, and point a browser at it, as long as it doesn't match any Structure URL, it will be 'free' of Structure.

As an aside, check out Freebie, which lets you ignore Structure for URLs that you specify.

# Answer
> 3 votes
Possible yes. Confusing? Depends on the client and what the other content is. Have you considered using Structure's Assets? That might help too (though Jason makes an excellent point with ZFA).

# Answer
> 3 votes
You might also try Zoo Flexible Admin with Low-Reorder. I have found this combo lets me control the backend client experience to a really high degree.

Low Reorder lets you rearrange channel entries display order, and also now links directly to each channel entry from the reorder list.

---
Tags: ee2, add-on, structure
---


# Question
Title: Comment form missing XID - Form submits but data doesn't save
As noted, the form submits but the data doesn't go into the db. Looking at the rendered HTML, I notice a missing XID. I think this is what is causing the problem - anyone know why this would happen?

```
{exp:comment:form channel="articles" entry_id="{embed:entry_id}"}

    {if logged_out}
            <label for="name">Name:</label><input type="text" name="name" value="{name}" size="50" /><br />
            <label for="email">Email:</label> <input type="text" name="email" value="{email}" size="50" /><br />
    {/if}

    <label for="comment">Comment:</label>
    <textarea name="comment" cols="70" rows="10">{comment}</textarea>
    <label><input type="checkbox" name="save_info" value="yes" {save_info} /> Remember my personal information</label>
    <br />
    {if captcha}
            <label for="captcha">Please enter the word you see in the image below:</label><br />
            <p class="captcha">{captcha}<input type="text" name="captcha" value="{captcha_word}" maxlength="20" style="width: 200px; float: left;" /></p>
    {/if}
    <br />
    <input type="submit" name="submit" value="Submit" />

{/exp:comment:form}

```

Source:

```
<form id="comment_form" method="post" action="http://domain.com/newsroom_article/core-to-corporate">
        <div class="hiddenFields" style="display: none;">
        <input type="hidden" name="ACT" value="29">
        <input type="hidden" name="RET" value="http://domain.com/newsroom_article/core-to-corporate">
        <input type="hidden" name="URI" value="newsroom_article/core-to-corporate">
        <input type="hidden" name="PRV" value="">
        <input type="hidden" name="XID" value="">
        <input type="hidden" name="entry_id" value="3327">
        <input type="hidden" name="site_id" value="1">
        </div>
        <label for="name">Name:</label><input type="text" name="name" value="" size="50"><br>
        <label for="email">Email:</label> <input type="text" name="email" value="" size="50"><br>

        <label for="comment">Comment:</label>
        <textarea name="comment" cols="70" rows="10"></textarea>
        <label><input type="checkbox" name="save_info" value="yes"> Remember my personal information</label>
        <!--                                                    <label><input type="checkbox" name="notify_me" value="yes"  /> Notify me of follow-up comments?</label> -->
        <br>
        <label for="captcha">Please enter the word you see in the image below:</label><br>
        <p class="captcha"><img src="http://domain.com/images/captchas/1354086872.7556.jpg" width="140" height="30" style="border:0;" alt=" "><input type="text" name="captcha" value="" maxlength="20" style="width: 200px; float: left;"></p>
        <br>
        <input type="submit" name="submit" value="Submit">
        </form>

```

# Answer
> 4 votes
Generally if form submissions aren't working, your `.htaccess` file is to blame.

Specifically, if you are using **NSM htaccess generator**, I've seen numerous problems with that, so avoid it. Also, if you are trying to force trailing slashes, **stop now**. EE 2.x really likes no trailing slash, and fighting it gets you nowhere.

The best solution is always to use the official htaccess, and nothing else:

```
RewriteEngine On

# Removes index.php from ExpressionEngine URLs
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

```

# Answer
> 5 votes
If secure forms is set to no in security settings, EE's forms don't use XID. Whilst this doesn't solve the problem of the data not saving, it should explain why there is no XID...

---
Tags: module, comment-form, xid
---


title: Log out upon tab/window close

text:
# Question
Title: Log out upon tab/window close
I have an ExpressionEngine application that displays some financial information, and the client is requesting that the user is logged out upon closing a tab/window.

Is that possible?

I currently have the security settings set to both Session and Cookies.

Thanks for the help.

# Answer
> 9 votes
I think this should be the solution, http://api.jquery.com/unload/

> After this code executes, the alert will be displayed whenever the browser leaves the current page. It is not possible to cancel the unload event with .preventDefault(). This event is available so that scripts can perform cleanup when the user leaves the page.

```
$(window).unload(function() {
  alert('Handler for .unload() called.');
});

```

Obviously you will want to call your logout script rather than the alert, something like:

```
$(window).unload(function() {
  var logout_path = '{path="logout"}';
  $.get(logout_path);
});

```

# Answer
> 4 votes
This is a bad idea - explain to your client that it's against the principles of HTTP.

For example, a customer opens different pages of your site in two tabs/windows. The close the second one, and go back to the first tab, but not it's logged out and any link/page submit is going to cause an error. That would piss me right off.

Secondly, Andy's solution is only going to work if the customer has javascript enabled. This may or may not be an issue for you, but it's hardly secure.

Instead you should look at options like a short login timeout (e.g. 10-15 minutes if it's really sensitive data).

---
Tags: security, sessions, logout, cookies
---


# Question
Title: How to have multiple data table layouts on a CP page?
I'm trying to figure out how to have more than 1 data table (filtering AJAX paginating table like the entry view in the Control Panel) on a page but there's a problem; the div used for pagination is hard coded in the JS. This means that the pagination icons all get stacked onto a single table and becomes unusable.

I've taken a look at the Table class and using a data source but am unclear if that will allow for multiple data tables.

Any ideas?

# Answer
Your best bet is to construct your own data tables - see the DataTables site

I have used DataTables to make multiple tables on a page - for example, my HooKan module has nine large tables on a page. Once you have had a look at how DataTables works, come back if you have any problems implementing
> 2 votes

# Answer
Maybe you should re-think why you want multiple datatables on a page. To me that sounds like a UI disaster, especially if they were stacked vertically.

That said, you should be able to do it using the built in table class (note: from memory, it actually uses tablesorter, not datatables). I highly recommend using that class over rolling your own, it makes your code much simpler. I expect you would need to make sure there are no overlapping POST parameters between the two tablesorters.

I don't really understand your pagination issue (can you elaborate?), but knowing PHP and JS I bet there is a way for you to override it. If all else fails, just dig around in the EE source til you find a solution!
> 0 votes

---
Tags: add-on, control-panel, jquery, table, add-on-development
---


title: How do I remove index.php from my URLs?

text:
# Question
Title: How do I remove index.php from my URLs?
How can I remove index.php from my URLs? Please provide rationale for why the specific method should be used.

# Answer
> 14 votes
I use the officially supported method. Why? because it's officially supported and I haven't had any problems using it.

add the following to your .htaccess file.

```
<IfModule mod_rewrite.c>
        RewriteEngine On

        # Removes index.php from ExpressionEngine URLs
        RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule ^(.*)$ /index.php/$1 [L]
</IfModule>

```

# Answer
> 4 votes
I've created a new method that works well on all hosts I have tried it on, and allows the use of regular query/GET parameters in URLs (unlike the built in QUERY\_STRING protocol).

This method is needed on some hosts where the other methods are not available (such as where PATH\_INFO is not set properly by the server configuration).

I call this method protocol "QUERY\_PARAM" since it uses a single query parameter named QSTR to pass the requested page URI into the index.php script, rather than replacing the entire query string.

Here are the changes you'd need to make to use this method:

**.htaccess**

```
#### Do our rewrites

# Don't rewrite requests for real files or directories
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

# Match the entire query string value, this gets put into %1
RewriteCond %{QUERY_STRING} ^(.*)$

# Create a new redirect that packs the requested URI into QSTR and preserves the existing query string
RewriteRule ^(.*)$ index.php?QSTR=$1&%1 [L]

```

**config/config.php**

Use the new URI protocol that we're about to create.

```
$config['uri_protocol'] = 'QUERY_PARAM';

```

**manager/codeigniter/system/core/URI.php**

Find this block, and insert the // IRAWAY // section as shown:

```
if ($uri == 'REQUEST_URI')
{
        $this->uri_string = $this->_parse_request_uri();
        return;
}

// IRAWAY: add query param support
if ($uri == 'QUERY_PARAM' && isset($_GET['QSTR']))
{
        $this->uri_string = $_GET['QSTR'];
        return;
}
// END IRAWAY

$this->uri_string = (isset($_SERVER[$uri])) ? $_SERVER[$uri] : @getenv($uri);

```

There are a few other notes on the gist where I originally posted this.

# Answer
> 3 votes
I have a fairly extensive .htaccess template at https://gist.github.com/3438705

This uses the official rewrite method with a few more bells and whistles too.

# Answer
> 2 votes
The standard method cited in the docs doesn't work in all hosting environment. This rule is specific to MediaTemple (dv) accounts, but may work elsewhere also. I host quite a few sites with them & this works everytime. Note the `?` in the last rewrite rule

```
## BEGIN ExpressionEngine Rewrite

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteRule ^(.*)$ /index.php?/$1 [L]

## END ExpressionEngine Rewrite

```

Why? Because it simple and works every time.

# Answer
> 2 votes
For nginx this is what I use in my virtual host configurations specifically for removing EE's index.php:

```
  location / {
    index index.php;
    try_files $uri $uri/ @ee;
  }

  location @ee {
    rewrite ^(.*) /index.php$1 last;
  }

```

What that does is look for the files as the requested URI, with a /, then try the @ee directive instead of just going to a 404. That basically appends the not found uri to index.php.

I also include a separate configuration file for PHP which includes this:

```
location /index.php {
  # Prevent duplicate content
  if ($request_uri ~ "^/index\.php/") {
    return 404;
  }

  #php config stuff here
  ...
}

```

(For older versions of nginx you'll need a separate config for PHP under SSL to add `HTTPS` manually as a server variable. Later versions have the `if_not_empty` directive, just google it you'll see.)

So nginx knows to hand off those requests to my choice of PHP, along with a whole bunch of environment stuff esp. for path\_info, https, and "scheme\_url" (so EE's "site" can be http or https dynamically), and the rest is all up to EE (it seems I neglected to include these, so if anyone ever needs just ask away).

For more details see: http://wiki.nginx.org/ExpressionEngine

# Answer
> 1 votes
Like CreateSean, I also use the officially supported method — and for the same reasons. I’ve seen plenty of support requests in the EE Forums where the poster has been using some other method of removing index.php and quite often the first thing that the person trying to help says is “disable your ‘Remove index.php’ code and see if the problem persists”. To be fair, they also sometimes say that if you're using the official method, but I think not so much, since it's more tried and tested.

In summary then: it’s official, it works, and you might have slightly less code unpicking to do if you ever have a problem.

# Answer
> 1 votes
I use an extended version of the 'official' rewrite which also redirects any index.php requests to the shortened URL. This basic rewrite introduces a situation whereby all of your content can be accessed both with and without `index.php` in the URL. This is easily avoided with a few extra lines of code:

```
<IfModule mod_rewrite.c>

# Enable Rewrite Engine
# ------------------------------
RewriteEngine On
RewriteBase /

# Redirect index.php Requests
# ------------------------------
RewriteCond %{THE_REQUEST} ^GET.*index\.php [NC]
RewriteCond %{THE_REQUEST} !/system/.*
RewriteRule (.*?)index\.php/*(.*) /$1$2 [R=301,L]

# Standard ExpressionEngine Rewrite
# ------------------------------
RewriteCond $1 !\.(css|js|gif|jpe?g|png) [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

</IfModule>

```

Full credit for this goes to Kevin Thompson who posted it on his blog last year.

---
Tags: htaccess
---