# Question
Title: Cause of Massive Performance Issues after EE Upgrade 2.5.2 to 2.7.2?
Newest Edit - 27 Feb 2014 - In case some poor soul with the same issue stumbles on this thread, I did not find a solution and ended up removing Matrix and replacing it with Grid.

---

My company would like to upgrade EE from 2.5.2 to the latest 2.7.2

I have created a sandboxed copy of our website, and executed the upgrade.

As a result, our template for our products page went from an execution time of approximately two seconds to an execution time of over sixty seconds.

After a lot of trial and error, I have broken it down to one particular chunk of code. The code works just fine in the old version of EE, but not in the new version.

See the following code (edited to correct conditionals as per commenters statements):

````
                                  {if cf_product_options}

                 {if entry_id==20}
                                              <hr class="soften">
                                              <h2>Configuration Options</h2>
                        <table class="table table-striped table-bordered table-condensed table-disable-hover">
                      <thead>{cf_product_options_labels limit="1"}<tr><th width="50%">{col_1}</th><th width="50%">{col_2}</th></tr>{/cf_product_options_labels}</thead>
                      <tbody>{cf_product_options limit="1"}<tr> <td>{col_1}</td><td>{col_2}</td></tr>{/cf_product_options}</tbody>
                        </table>
                                          {/if}
                                    {if entry_id==22}
                    <hr class="soften">
                                            <h2>Configuration Options</h2>
                    <table class="table table-striped table-bordered table-condensed table-disable-hover">
                      <thead>{cf_product_options_labels limit="1"}<tr><th width="50%">{col_1}</th><th width="50%">{col_2}</th></tr>{/cf_product_options_labels}</thead>
                      <tbody>{cf_product_options limit="1"}<tr> <td>{col_1}</td><td>{col_2}</td></tr>{/cf_product_options}</tbody>
                    </table>
                                            {/if}
                                    {if entry_id==76}
                    <hr class="soften">
                                            <h2>Typical Options <small>( <span style="font-size:12px;">*</span> ) represents standards features</small></h2>
                    <table class="table table-striped table-bordered table-condensed table-disable-hover">
                      <thead>{cf_product_options_labels limit="1"}<tr><th width="33%">{col_1}</th><th width="33%">{col_2}</th><th width="33%">{col_3}</th></tr>{/cf_product_options_labels}</thead>
                      <tbody>{cf_product_options limit="1"}<tr><td>{col_1}</td><td>{col_2}</td><td>{col_3}</td></tr>{/cf_product_options}</tbody>
                      <thead>{cf_product_options_labels limit="1"}<tr><th width="33%">{col_4}</th><th width="33%">{col_5}</th><th width="33%">{col_6}</th></tr>{/cf_product_options_labels}</thead>
                      <tbody>{cf_product_options limit="1"}<tr><td>{col_4}</td><td>{col_5}</td><td>{col_6}</td></tr>{/cf_product_options}</tbody>
                    </table>
                                            {/if}
                                    {if entry_id==77}
                    <hr class="soften">
                                            <h2>Compatible Options</h2>
                    <table class="table table-striped table-bordered table-condensed table-disable-hover">
                      <tbody>{cf_product_options limit="1"}<tr><td>{col_1}</td><td>{col_2}</td><td>{col_3}</td></tr>{/cf_product_options}</tbody>
                    </table>
                  {/if}
                                    {if entry_id==79}
                    <hr class="soften">
                                            <h2>Typical Options <small>( <span style="font-size:12px;">*</span> ) represents standards features</small></h2>
                    <table class="table table-striped table-bordered table-condensed table-disable-hover">
                      <thead>{cf_product_options_labels limit="1"}<tr><th width="20%">{col_1}</th><th width="20%">{col_2}</th><th width="20%">{col_3}</th><th width="20%">{col_4}</th><th width="20%">{col_5}</th></tr>{/cf_product_options_labels}</thead>
                      <tbody>{cf_product_options limit="1"}<tr><td>{col_1}</td><td>{col_2}</td><td>{col_3}</td><td>{col_4}</td><td>{col_5}</td></tr>{/cf_product_options}</tbody>
                    </table>
                                            {/if}
                                    {if entry_id==89}
                    <hr class="soften">
                                            <h2>Typical Options</h2>
                    <table class="table table-striped table-bordered table-condensed table-disable-hover">
                      <tbody>{cf_product_options limit="1"}<tr><td width="50%">{col_1}</td><td width="50%">{col_2}</td></tr>{/cf_product_options}</tbody>
                    </table>
                  {/if}
                                    {if entry_id==101}
                    <hr class="soften">
                                            <h2>Typical Options <small>( <span style="font-size:12px;">*</span> ) represents standards features</small></h2>
                    <table class="table table-striped table-bordered table-condensed table-disable-hover">
                      <thead>{cf_product_options_labels limit="1"}<tr><th width="16%">{col_1}</th><th width="16%">{col_2}</th><th width="16%">{col_3}</th><th width="16%">{col_4}</th><th width="16%">{col_5}</th><th width="16%">{col_6}</th></tr>{/cf_product_options_labels}</thead>
                      <tbody>{cf_product_options limit="1"}<tr><td>{col_1}</td><td>{col_2}</td><td>{col_3}</td><td>{col_4}</td><td>{col_5}</td><td>{col_6}</td></tr>{/cf_product_options}</tbody>
                    </table>
                                            {/if}

                  {/if}

````

Above, in the code, "cf\_product\_options" is a matrix field. The code checks with the first conditional to see that data exists, and if so, it checks the entry\_id and serves up the appropriate code.

Removing this chunk of code entirely returns the execution time to normal.

(I was originally using a switchee statement here, and while that works in our old version of EE, it is JUST as slow here in the updated version... so I have removed switchee code for the time being to simplify and make it easier to see what is going on)

Thank you for any suggestions.

*** DEBUGGING ***

Here is the output from the debugging in EE (when I use switchee in addition to the code above):

`(0.375135 / 19.24MB) Calling Class/Method: Channel/entries
(0.383207 / 19.28MB) -> Class Called: Channel
(0.385074 / 19.29MB) -> Method Called: entries
(0.393458 / 19.40MB) Calling Extension Class/Method: Assets_ext/channel_entries_query_result
(0.411238 / 19.58MB) Calling Extension Class/Method: Playa_ext/channel_entries_tagdata
(0.413006 / 19.61MB) Calling Extension Class/Method: Matrix_ext/channel_entries_tagdata
(36.993778 / 21.28MB) Calling Extension Class/Method: Pt_field_pack_ext/channel_entries_tagdata
(37.032971 / 21.14MB) Calling Extension Class/Method: Playa_ext/channel_entries_tagdata
(37.034998 / 21.17MB) Calling Extension Class/Method: Matrix_ext/channel_entries_tagdata
(69.008183 / 21.34MB) Calling Extension Class/Method: Pt_field_pack_ext/channel_entries_tagdata
(69.041813 / 20.97MB) -> Data Returned`

Here is the debugging, after removing switchee and using a fix as suggested below: `(0.886224 / 19.24MB) Calling Class/Method: Channel/entries
(0.892344 / 19.27MB) -> Class Called: Channel
(0.896914 / 19.29MB) -> Method Called: entries
(0.954155 / 19.39MB) Calling Extension Class/Method: Assets_ext/channel_entries_query_result
(1.011197 / 19.57MB) Calling Extension Class/Method: Playa_ext/channel_entries_tagdata
(1.017665 / 19.59MB) Calling Extension Class/Method: Matrix_ext/channel_entries_tagdata
(19.454163 / 21.26MB) Calling Extension Class/Method: Pt_field_pack_ext/channel_entries_tagdata
(19.519405 / 21.13MB) Calling Extension Class/Method: Playa_ext/channel_entries_tagdata
(19.521837 / 21.16MB) Calling Extension Class/Method: Matrix_ext/channel_entries_tagdata
(33.768249 / 21.32MB) Calling Extension Class/Method: Pt_field_pack_ext/channel_entries_tagdata
(33.818316 / 20.96MB) -> Data Returned`

With suggested UPDATE2 the debug output: `(0.826544 / 19.24MB) Calling Class/Method: Channel/entries
(0.832316 / 19.28MB) -> Class Called: Channel
(0.835756 / 19.29MB) -> Method Called: entries
(0.853860 / 19.40MB) Calling Extension Class/Method: Assets_ext/channel_entries_query_result
(0.878189 / 19.57MB) Calling Extension Class/Method: Playa_ext/channel_entries_tagdata
(0.880296 / 19.60MB) Calling Extension Class/Method: Matrix_ext/channel_entries_tagdata
(18.803853 / 21.26MB) Calling Extension Class/Method: Pt_field_pack_ext/channel_entries_tagdata
(18.863077 / 21.13MB) Calling Extension Class/Method: Playa_ext/channel_entries_tagdata
(18.865144 / 21.16MB) Calling Extension Class/Method: Matrix_ext/channel_entries_tagdata
(35.012716 / 21.32MB) Calling Extension Class/Method: Pt_field_pack_ext/channel_entries_tagdata
(35.067242 / 20.96MB) -> Data Returned`

Total Execution time: 37.3617

**UPDATE:**

I know that this is related to the matrix field in particular. If I remove the matrix field and simply use the if/else conditionals to display regular html code, the load time drops to just 3 seconds.

Add a matrix field and try to display it's contents, and suddenly the execution seems to multiply exponentially for each if/else that exists.

**UPDATE 2**

To simplify debugging, I have stripped the problem area of my template to contain the following plain html code: (note that there is plenty more to the template, just not shown here)

*I can't seem to force my post to remove html code between my code tags, so I have substituted regular brackets for now*

````
(hr class="soften")
(h2)Configuration Options(/h2)

```

Which has a total execution time of: 2.5+ seconds

If I add my matrix field to that simple code like so:

```
(hr class="soften")
(h2)Configuration Options(/h2)
{cf_product_options_labels limit="1"}{col_1}{col_2}{/cf_product_options_labels}
{cf_product_options limit="1"}{col_1}{col_2}{/cf_product_options}

````

Total Execution time jumps to: 4.6+ seconds

The debug looks the same as all the other problem debugs with the execution time jumping drastically when calling " Matrix\_ext/channel\_entries\_tagdata " and " Pt\_field\_pack\_ext/channel\_entries\_tagdata "

Unfortunately, I have contacted P&T and they responded that there would be a fee to help as debugging a template falls outside the normal scope of their support. Fair enough. I believe I have narrowed it enough right now and have sent them another email, so hopefully they will have ideas on where to go next. I'm at a complete loss.

NEW EDIT: I thought I had this issue licked, but it turns out I didn't. In my excitement over an improved load time, I didn't notice that by embedding my template, I of course was not actually rendering the matrix data, and instead was just displaying variable names. I hadn't edited the template to take into account that I would have to pass the entry\_id to the embedded template in order for it to show relevant data.

So this is still unsolved, and I believe I'm going to have to do a MASSIVE amount of work to use an alternate solution.

# Answer
> 2 votes
Yeah, you've got a mess on your hands. Try this no add-on method. If it doesn't help you out, notacouch's suggestion to use IfElse should be helpful.

```
{if entry_id == "20" && cf_product_options:total_rows > "0"}
    <hr class="soften">
    <h2>Configuration Options</h2>
    <table class="table table-striped table-bordered table-condensed table-disable-hover">
      <thead>{cf_product_options_labels limit="1"}<tr><th width="50%">{col_1}</th><th width="50%">{col_2}</th></tr>{/cf_product_options_labels}</thead>
      <tbody>{cf_product_options limit="1"}<tr> <td>{col_1}</td><td>{col_2}</td></tr>{/cf_product_options}</tbody>
    </table>
{/if}

{if entry_id == "22" && cf_product_options:total_rows > "0"}
    <hr class="soften">
    <h2>Configuration Options</h2>
    <table class="table table-striped table-bordered table-condensed table-disable-hover">
      <thead>{cf_product_options_labels limit="1"}<tr><th width="50%">{col_1}</th><th width="50%">{col_2}</th></tr>{/cf_product_options_labels}</thead>
      <tbody>{cf_product_options limit="1"}<tr> <td>{col_1}</td><td>{col_2}</td></tr>{/cf_product_options}</tbody>
    </table>
{/if}

{if entry_id == "76" && cf_product_options:total_rows > "0"}
  <hr class="soften">
  <h2>Typical Options <small>( <span style="font-size:12px;">*</span> ) represents standards features</small></h2>
  <table class="table table-striped table-bordered table-condensed table-disable-hover">
    <thead>{cf_product_options_labels limit="1"}<tr><th width="33%">{col_1}</th><th width="33%">{col_2}</th><th width="33%">{col_3}</th></tr>{/cf_product_options_labels}</thead>
    <tbody>{cf_product_options limit="1"}<tr><td>{col_1}</td><td>{col_2}</td><td>{col_3}</td></tr>{/cf_product_options}</tbody>
    <thead>{cf_product_options_labels limit="1"}<tr><th width="33%">{col_4}</th><th width="33%">{col_5}</th><th width="33%">{col_6}</th></tr>{/cf_product_options_labels}</thead>
  <tbody>{cf_product_options limit="1"}<tr><td>{col_4}</td><td>{col_5}</td><td>{col_6}</td></tr>{/cf_product_options}</tbody>
  </table>
{/if}

{if entry_id == "77" && cf_product_options:total_rows > "0"}
  <hr class="soften">
  <h2>Compatible Options</h2>
  <table class="table table-striped table-bordered table-condensed table-disable-hover">
    <tbody>{cf_product_options limit="1"}<tr><td>{col_1}</td><td>{col_2}</td><td>{col_3}</td></tr>{/cf_product_options}</tbody>
  </table>
{/if}

{if entry_id == "79" && cf_product_options:total_rows > "0"}
  <hr class="soften">
  <h2>Typical Options <small>( <span style="font-size:12px;">*</span> ) represents standards features</small></h2>
  <table class="table table-striped table-bordered table-condensed table-disable-hover">
    <thead>{cf_product_options_labels limit="1"}<tr><th width="20%">{col_1}</th><th width="20%">{col_2}</th><th width="20%">{col_3}</th><th width="20%">{col_4}</th><th width="20%">{col_5}</th></tr>{/cf_product_options_labels}</thead>
    <tbody>{cf_product_options limit="1"}<tr><td>{col_1}</td><td>{col_2}</td><td>{col_3}</td><td>{col_4}</td><td>{col_5}</td></tr>{/cf_product_options}</tbody>
  </table>
{/if}

{if entry_id == "89" && cf_product_options:total_rows > "0"}
  <hr class="soften">
  <h2>Typical Options</h2>
  <table class="table table-striped table-bordered table-condensed table-disable-hover">
    <tbody>{cf_product_options limit="1"}<tr><td width="50%">{col_1}</td><td width="50%">{col_2}</td></tr>{/cf_product_options}</tbody>
  </table>
{/if}

{if entry_id == "101" && cf_product_options:total_rows > "0"}
  <hr class="soften">
  <h2>Typical Options <small>( <span style="font-size:12px;">*</span> ) represents standards features</small></h2>
  <table class="table table-striped table-bordered table-condensed table-disable-hover">
    <thead>{cf_product_options_labels limit="1"}<tr><th width="16%">{col_1}</th><th width="16%">{col_2}</th><th width="16%">{col_3}</th><th width="16%">{col_4}</th><th width="16%">{col_5}</th><th width="16%">{col_6}</th></tr>{/cf_product_options_labels}</thead>
    <tbody>{cf_product_options limit="1"}<tr><td>{col_1}</td><td>{col_2}</td><td>{col_3}</td><td>{col_4}</td><td>{col_5}</td><td>{col_6}</td></tr>{/cf_product_options}</tbody>
  </table>
{/if}

```

**UPDATE**

What happens if you put all your Matrix calls inside of the entry\_id conditional check? What does the debugger say?

```
{if entry_id == "20"}
  {if cf_product_options:total_rows > "0"}
    <hr class="soften">
    <h2>Configuration Options</h2>
    <table class="table table-striped table-bordered table-condensed table-disable-hover">
      <thead>{cf_product_options_labels limit="1"}<tr><th width="50%">{col_1}</th><th width="50%">{col_2}</th></tr>{/cf_product_options_labels}</thead>
      <tbody>{cf_product_options limit="1"}<tr> <td>{col_1}</td><td>{col_2}</td></tr>{/cf_product_options}</tbody>
    </table>
  {/if}
{/if}

```

**UPDATE 2**

Looks like my update above helped some. Still haven't heard if IfElse helps you. If this doesn't help, can you tell what PHP version you have, what's in your Matrix fields, and verify that all of them have `limit="1"` where you need that?

```
{exp:ifelse parse="inward"}
  {if entry_id == "20"}
    {if cf_product_options:total_rows > "0"}
      <hr class="soften">
      <h2>Configuration Options</h2>
      <table class="table table-striped table-bordered table-condensed table-disable-hover">
        <thead>{cf_product_options_labels limit="1"}<tr><th width="50%">{col_1}</th><th width="50%">{col_2}</th></tr>{/cf_product_options_labels}</thead>
        <tbody>{cf_product_options limit="1"}<tr> <td>{col_1}</td><td>{col_2}</td></tr>{/cf_product_options}</tbody>
      </table>
    {/if}
  {if:elseif entry_id == "22"}
    {if cf_product_options:total_rows > "0"}
      <hr class="soften">
      <h2>Configuration Options</h2>
      <table class="table table-striped table-bordered table-condensed table-disable-hover">
        <thead>{cf_product_options_labels limit="1"}<tr><th width="50%">{col_1}</th><th width="50%">{col_2}</th></tr>{/cf_product_options_labels}</thead>
        <tbody>{cf_product_options limit="1"}<tr> <td>{col_1}</td><td>{col_2}</td></tr>{/cf_product_options}</tbody>
      </table>
    {/if}
  {/if}
{/exp:ifelse}

```

# Answer
> 1 votes
If that is really the case I'm surprised any of those conditions are even working. Programmatically speaking those are assignments, not conditions, which in EE templating terms... is neither, unless they let that slide as conditions then that'd be interesting.

Once that is fixed, if those conditions are really the issue (even if they aren't!) I would try using Mark Croxton's IfElse, or Switchee plugins to handle your conditions so that only the code you need to run is parsed.

the below wouldn't be advanced conditionals due to the IfElse plugin and only the passing condition's content would work/be parsed (if I understand this correctly)

```
{exp:ifelse parse="inward"}
  {if entry_id == 78}
  ...
  {if:elseif entry_id == 79}
  ...
  {/if}
{/exp:ifelse}

```

or switchee, only the valid case's content would be parsed (if I understand this correctly)

```
{exp:switchee variable="{entry_id}" parse="inward"}
  {case value="78"}...{/case}
  {case value="79"}...{/case}
  ...
{/exp:switchee}

```

---
Tags: ee2, matrix, pixelandtonic, upgrade, performance
---


# Question
Title: Using Low Seg2Cat to list and filter Category Entries
I'm new to using Seg2Cat and I'm wondering if one of you extremely helpful folks out there may be able to help/offer advice or guidance based on my needs. A buddy told me Seg2Cat is what I need to pull this off, however I'm uncertain as to even set it up and get going.

I have a listing channel for some 'staff' who are spread throughout the US and some other countries. Each staffer is in a category based on their state of residence.

I want to be able to have a select dropdown list of the states, then upon selection of a state, it takes you to a page or renders the results of staffers residing in the state.

Thanks all!

# Answer
> 2 votes
You don't necessarily need Seg2cat to do that, category views are already built into EE.

Assuming you have a template group set up called /staff all you need to do is add the Channel entries tag, plus category links for navigation, into the /staff/index template.

Sample channel entries tag for your staff entries

```
{exp:channel:entries channel="your_staff_channel_short_name"}
{title}
{/exp:channel:entries}

```

Sample categories list for staff navigation...

```
{exp:channel:categories channel="your_staff_channel_short_name"}
<a href="{path='staff/index'}">{category_name}</a>
{/exp:channel:categories}

```

For basic drop down code example look at http://ellislab.com/expressionengine/user-guide/modules/channel/categories.html#category-dropdown-menu

# Answer
> 0 votes
I'm a little confused by your setup. If by staffers in categories you mean like Zoo Visitor entries with literal categories then it may not always make sense for your urls to have the category url\_title (again, it's not clear to me what your setup is like).

You could instead utilize this other add-on Cat2 to grab the category id and list channel entries by that.

---
Tags: low-seg2cat
---


# Question
Title: Possible to compress images to be not larger than certain size?
That title might be a little confusing (sorry) but I'm using Channel Images to run some galleries; the client is giving me jpegs that were saved at highest quality, so they are too large (about 1-1.5MB each). CI can compress all the images at a specified rate, but what I'm looking for instead is a variable compression rate, so that images will be saved at the highest quality that keeps them under 200kb (for example).

In other words, I want the images compressed to the point that they reach 200kb, and not more: highly saturated images would therefore be more compressed than simple images.

Any ideas on how to achieve this? I'm trying to make things a little simpler for one of my clients.

# Answer
> 3 votes
As I know, is no EE add-ons which can completely help you to get what you want.

Possible solution:

1. Upload file using any of exist EE add-ons, make manipulation with exist option (width, height, crop etc.)
2. Then setup on the server CRON job with batch which will run couple times per day and check if new files in upload folder exist. For new files needs to run jpegoptim with key --size

> -S, --size=\< size \>
>
> Try to optimize file to given size (disables lossless opti- mizaiont mode). Target size is specified either in kilobytes (1 - n) or as percentage (1% - 99%) of the original file size.

example of optimization script for this:

```
#!/bin/sh
declare -a iPath=('/home/user/site.com/public_html/images/upload');
lof_file=('/tmp/otimazer.log')

start_time=$(date +%s)

if [ -f $lof_file ];
then
    dt_mod=("-newer $lof_file")
else
    dt_mod=""
fi

for i in "${iPath[@]}"
do
    find $i  -iname "*.j*g" $dt_mod -type f | xargs jpegoptim --strip-all --size=200
done

end_time=$(date +%s)

duration=$(($end_time-$start_time))

echo "$(date +%Y-%m-%d-%H-%M-%S) : duration = $duration" >> $lof_file

```

p.s. For my clients servers I usually setup IMGO.

# Answer
> 0 votes
Try enforcing an upload limit and the different image manipulation settings on your upload directory.

Adjusting the output settings on the fly would be difficult to pull off. If you require more advanced manipulation, take a look at CE Image from CausingEffect.

# Answer
> 0 votes
While not allowing you set a max file size CE Image will let you set an image quality percentage - see the docs here. Otherwise I think Max's answer is best ATM.

# Answer
> 0 votes
Use the "maxb" parameter of phpThumb: http://phpthumb.sourceforge.net

---
Tags: image, channel-images, resize
---


# Question
Title: Save Templates as Files and Google Analytics
I am saving templates as files and now just recently I noticed that when I open a template in my Code Editor via FTP the then open template gets displayed in Google Analytics "Realtime" report, like this:

url/public\_html/assets/templates/default\_site/template.group/index.html

I find this to be quite confusing and I am wondering why this is happening and if there is anything I can do to prevent this behaviour.

Thanks and Cheers!

Marc

**Additional Info**

Two more things to consider: I am using Config Master and Stash with this particular site. I set the Analytics code like this: $env\_global\['global:google\_analytics'\] = 'UA-XXXXXXX-X'; and get it like this {global:google\_analytics} in my Stash wrapper template later on.

# Answer
> 3 votes
A quick Google search seems to indicate that it's the thumbnail icons that Coda continually regenerates, which will render the HTML (including your Google Analytics code).

See this thread

The solution they offered is to collapse the preview thumbnails into text. I don't have a copy of Coda, so I don't know exactly how to do that, but it sounds pretty simple.

# Answer
> 1 votes
The better approach would be to exclude your development IP address/machines from Google Analytics.

This has the added advantage that your testing/use of the site won't account towards your analytical tracking data.

---
Tags: templates, files, google-analytics
---


title: Caching and flock()

text:
# Question
Title: Caching and flock()
I'm developing an EE site. I've used `cache="yes"` and `refresh="60"` parameters throughout. Locally, the site was running super quick (as expected).

However, when I pushed to the staging server, the 'wait' time on the site was painfully slow. Sometimes 5 seconds +. Tested via Pingdom

I contacted the host and their reply was this:

> ...it's an Expression Engine issue. It uses flock() which on our cloud platform is much slower than on local storage because we use network storage. By commenting out the flock statements it should speed up the site considerably.

Can anyone shed any light on this please? I've never come across it before.

What would my options be?

* Move host?
* Remove the cache tags?
* Comment out the flock() statement? (somewhere in CI?)
* CE Cache?
* Something else...?

Thanks! : )

# Answer
> 2 votes
CE Cache and ExpressionEngine's cache="yes" are not true caches. I hate that they advertise themselves as "caches" - they are not! They simply cache *ExpressionEngine template parsing's output at a very high level*, the entire PHP stack and ExpressionEngine core still needs to run. Not to mention database traffic, even for non-logged in members due to EE's horrible session management.

If you're suffering from slow IO performance due to high latency network storage. Absolutely no "cache" plugin or EE core modification is going to solve this.

If you want true caching, use nginx and fastcgi\_cache which will give you true caching that will completely bypass PHP/EE stacks. It can very easily be set-up to achieve per-logged in member caches too.

We're doing this for many of our clients, with one in particular this method allows us to get hundreds of thousands of hits per second out of EE2.

# Answer
> 0 votes
Yes those are your options.

I personally suggest removing EE tags and using **CE Cache**. It's a great alternative which allows for multiple methods for caching:

> file-based caching, database, APC, Redis, Memcache or Memcached) or full-page static caching

# Answer
> -1 votes
You can use "Stash" to store (in the database) entire pages or parts of pages, with tags and conditionals rendered. I find that this speeds up pageload tremendously in some cases with some modules/fieldtypes.

another interesting one is "preparse" by solspace (which i haven't used yet). "*Preparse allows you to parse EE template data when publishing/editing an entry...*" and then stores it in a custom field.

---
Tags: cache, server, codeigniter, hosting, speed
---


title: Low Search - Filtering by Grid count

text:
# Question
Title: Low Search - Filtering by Grid count
Is it possible to filter entries in Low Search based on the number of rows/count of a specific Grid Field?

For example something like,

`Get all rows whos field X(a Grid field) has a count greater than 0`

# Answer
Short answer: No.

Slightly longer answer: it could, if you create an extension to cater for it, using Low Search's extension hooks.
> 1 votes

---
Tags: low-search, grid
---


title: Unable to login after upgrading to 2.6

text:
# Question
Title: Unable to login after upgrading to 2.6
I just tried to upgrade to 2.6 - the installation went fine, however now I am unable to login - after logging in, I am always returned to the login screen again.

I know the system has actually logged me in because I can tell from the front end. However I notice the S=0 in the query string so I am guessing it's something to do with the session not being set correctly?

Does anyone have any ideas? I am using structure 3.3.8 if that is of any help.

Thanks,

Tom

# Answer
> 2 votes
I've just found the culprit and solution for anyone who is having a similar problem.

The problem was being caused by an incompatible version of Zoo Flexible Admin.

1.7.1 has just being released and it

http://devot-ee.com/add-ons/support/zoo-flexible-admin/viewthread/9326

# Answer
> 2 votes
I don't know if it would be helpful or not, but, you could try disabling the session stuff (by using cookies only) via your config.php by using the following:

```
$config['user_session_type'] = 'c';
$config['admin_session_type'] = 'c';

```

# Answer
> 0 votes
I hit this one also just now with an upgrade from EE 2.5.3 to 2.7.2 - turned out it was Structure causing this in my case - to disable the redirect on login I ran this:

```
UPDATE exp_extensions SET 'enabled'='n' WHERE class='Structure_ext' AND hook='cp_member_login'

```

---
Tags: control-panel, ee2-upgrades
---


title: Checking If tags has content or not

text:
# Question
Title: Checking If tags has content or not
I want to check if two tags have content in them, and set html markup accordingly. And I reuse this snippet several places and I'm having inconsistent results.

```
{if site_hvite_left == "" OR site_hvite_right == ""}
    <div class="row-small">
{if:else}
    <div class="row">
{/if}

```

Some places this works just fine, but other places, I need to add a space in between the quotes for it to make it work. Which makes me think there might be a better way of doing this. Any ideas?

# Answer
Try this:

```
{if '{site_hvite_left}' == '' OR '{site_hvite_right}' == ''}
    <div class="row-small">
{if:else}
    <div class="row">
{/if}

```

.. a bit verbose but it should work every time.
> 1 votes

---
Tags: channel-entries, conditionals, ifelse
---


# Question
Title: Limiting stash:get_list to specific entry based on param or url?
all - I'm trying to find a new way to return a single entry view and list view within a single template using stash and the only thing holding me up - and maybe I'm overlooking a simple solution - is the absence of a url\_title parameter in the stash:get\_list tag pair. Here's a bit more detail about what I'm trying to do:

In the main logic template, I have:

{embed="layouts/.inside"}

```
{exp:stash:set_list name="entries_loop" parse_tags="yes" save="yes" scope="site"}

{exp:low_reorder:entries set="apis" dynamic="no" disable="categories"}

    {stash:entry_title}{title}{/stash:entry_title}
    {stash:entry_url_title}{url_title}{/stash:entry_url_title}
    {stash:entry_icon}{cf_api_icon}{/stash:entry_icon}
    {stash:entry_short_description}{cf_api_short_description}{/stash:entry_short_description}

{/exp:low_reorder:entries}

{/exp:stash:set_list}

```

In the .inside layout template, I have:

{exp:ifelse parse="inward"} {if segment\_2 == ""}

```
                    <h1>API Documentation</h1>

                    <p>Interdum et malesuada fames ac ante ipsum primis in faucibus. Proin convallis, arcu blandit iaculis sodales, orci purus imperdiet libero, nec vestibulum ligula nulla sit amet metus. Proin aliquam ante id sapien scelerisque lobortis. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Suspendisse eu mattis est, id vulputate erat. Proin suscipit venenatis tristique. Nam aliquet ullamcorper dolor, sed sodales augue varius non. Morbi nisl nisi, placerat ut malesuada eu, lobortis a nisl. Quisque non ultricies nulla. Proin mollis ut nisi at elementum. Aliquam nec lacus quis magna auctor feugiat vitae a velit. Morbi tempor risus non semper vehicula. Praesent mattis ligula nec mattis sollicitudin.</p>

<h3>Current APIs</h3>

    {exp:stash:get_list name="entries_loop"}
        {if count == "1"}<ul class="small-block-grid-2 medium-block-grid-3 large-block-grid-3 api-list">{/if}
        <li><a href="{path='{segment_1}/{entry_url_title}'}"><img src="{entry_icon}" alt="{entry_title}" /><h4>{entry_title}</h4></a>
        <p>{entry_short_description}</p>
        </li>
        {if count == total_results}</ul>{/if}
    {/exp:stash:get_list}

    {if:else}

    {exp:stash:get_list name="entries_loop" limit="1" dynamic="yes" url_title="{entry_url_title}"}

    <div class="row">
        <div class="large-3 small-3 columns">
            <img src="{entry_icon}" alt="{entry_title}" />
        </div>
        <div class="large-9 small-9 columns">
            <h1>{entry_title}</h1>
            {entry_short_description}
        </div>
    </div>

    <hr/>

    <p>Additional details here</p>

    <h3>Contents</h3>

    <ul class="side-nav">
        <li><a href="#">Item One</a></li>
        <li><a href="#">Item Two</a></li>
        <li><a href="#">Item Three</a></li>
        <li><a href="#">Item Four</a></li>
        <li><a href="#">Item Five</a></li>
    </ul>

    {/exp:stash:get_list}
{/if}
{/exp:ifelse}

```

So basically, what I was trying to do is stash the complete set of entries in the main template, then get that stashed list, conditionally showing all or one, depending on the url (yes, I will have to switch to switchee rather than ifelse add-on to accommodate pagination).

What I'm getting for a result right now is the same entry in either single entry view rather than the one I want. If the get\_list loop has a parameter similar to url\_title that I could point at a url segment, I'd be all set. Is there something similar that I can do? I was just trying to be as strategic as possible with the stashing of the content - rather than stash the complete list of entries and the single entry I want to see separately, I thought I could limit the get\_list to a single entry in a way that would mirror how that could be done in an entries loop.

# Answer
> 1 votes
If your ifelse is handling segment3 then when you want to show single entry, could you use

```
{exp:stash:get_list name="entries" match="#^{segment_3}$#" against="entry_URL_title"}
...{snippet with layout}
    {/exp:stash:get_list}

```

Basically use the match function against the URL title. It has to be a regex. Have replied via phone so excuse the shortness of my reply.

---
Tags: stash
---


# Question
Title: Solspace Freeform Pro Captcha Error erases all form data
I'm using Freeform pro 4.1.3 and everything is working great with the default EE captcha, etc. However, when your captcha field is incorrect or not filled in, all of the data is lost on submit. This is a non-https page. Am I missing a setting somewhere?

# Answer
I had my fields hard-coded instead of using {freeform:form} tag as mentioned here:

http://www.solspace.com/forums/viewthread/17716/#63420

This solved the issue.
> 2 votes

---
Tags: solspace-freeform, captcha
---


# Question
Title: How to display pagination in following formate?
I want to display Pagination in following format

page first entry to page last entry of total entry

example : in first page i want to display 10 entry so i want to following output

1 to 10 of 100

this can be possible ? if possible please guide me. Thank you.

# Answer
You can do most of this with the default EE pagination tags, but I think in order to get the last number of the entries on the page you should check out the AB Pagination add-on. Using that add-on makes outputting pagination like "1 to 10 of 100" easy.
> 2 votes

---
Tags: pagination
---


title: Cartthrob MSM Sagepay 5006 error

text:
# Question
Title: Cartthrob MSM Sagepay 5006 error
I have a Cartthrob MSM installation (2 stores) that use sagepay (europe offsite) for processing payments.

Every time I try to make a payment through the sites, I get all the way through the payment process and at the very end I get the following error:

```
> HTTP Status Code:    500
> HTTP Status Message: The request was unsuccessful due to an unexpected condition encountered by the server.
> Error Code :         5006
> Error Description :  Unable to redirect to Vendor's web site. The Vendor failed to provide a RedirectionURL.

```

I've checked that extload.php is configured correctly, and when I output the NotificationURL value from the gateway plugin it looks correct:

```
http://mysite.com/themes/third_party/cartthrob/lib/extload.php/sage_s

```

Does anyone have any experience of this error and possible solutions? I contacted the hosts (Nexcess) who said they couldn't think of any security that might be on the server, stopping a callback from sage.

I've been trying to get these sites working for a week through a host of errors, I'm hoping this is the last hurdle.

# Answer
I spoke at length with Chris Newton (Cartthrob developer) and he eventually tracked the problem down to a combination of me using Focus Lab's multi-environment config, changes in the way that EE 2.7.2 handles `$assign_to_config[]` and how this affected CT2.4. We're still working on a fix, but it looks like this was a very specific environment/config issue.
> 1 votes

---
Tags: cartthrob, multi-site-manager, sagepay
---


# Question
Title: structure of menu with stucture (3.3.13)
i'm working on a website with structure ( 3.3.13) and expression engine (2.7.2). I'm struggling with the menu. The html of the menu has to be like the image (with the same classes and data options):

Can i create this menu with structure?

# Answer
> 2 votes
If the native Entries method doesn't suit your need, Structure Entries will solve your problem.

---
Tags: structure
---


# Question
Title: Configure wygwam configuration via field parameter?
Within a channel form, is it possible to override/specify the editor configuration that wygwam uses?

For example:

```
{exp:channel:form channel="post"}
    <label>Post Content</label>
    {field:wygwam_field editor="basic"}
{/exp:channel:form}

```

Basically, I want the users in the CP to have access to the "Full" editor. But users submitting content via the front-end/Channel Form to have a "basic" editor load.

Is this possible?

# Answer
> 3 votes
For developers:

Not easy, the display\_field() method from wygwam gets its settings early on. However you maybe able to pluck apart the toolbars in the hook "wygwam\_config".

See https://github.com/pixelandtonic/wygwam\_super\_admin\_source for an extension that adds a "source" button for super-admins. You could use that as a basis to remove / set other config options as well (e.g. based on REQ == CP or ACTION or PAGE)

**Edit**: more info http://docs.pixelandtonic.com/wygwam/developers/wygwam\_config.html
**Edit2**: even better http://dmlogic.com/blog/managing-wygwams-settings-via-code/

---
Tags: safecracker, wygwam, channel-form
---


# Question
Title: Getting count to work for playa field within Matrix
I've got a page which is displaying information based on a playa entry within a matrix field, when using the matrix :search parameter, this works as intended. But I need to be able to use the {count} tag. The problem is that the image thumbnails and information for each matching entry are simply looping, so the {count} just displays 1 for each of the returned results. I would like them to be 1, 2, 3, 4 etc. I have tried all the other Matrix tags, such as {row\_count}, {total\_rows}, {field\_row\_index} etc. but none of these do the job.

If any one could offer any guidance, or other ways round this, I'd be grateful. Thanks.

```
{exp:channel:entries channel='profile-entry' disable="member_data|pagination|categories" orderby="surname" sort="asc" dynamic="no"}
{services_new search:parent="{segment_3}"}<!-- Matrix Entry, 'parent' is the Playa column within it-->
    <!-- Playa 'related' fields that match segment_3-->
    <a href="{site_url}our-people/{url_title}" class="{if {count} == 1}col4 firstfour firstthree firsttwo {/if}{if {count} == 2}col4{/if}{if {count} == 3}col4 firsttwo{/if}">
        <img src="{profile-portrait}" alt="{title} Profile Picture" width="100%" />
        <h3>{title}</h3>
        <h3 class="title">{profile-position}</h3>
    </a>
{/services_new}
{/exp:channel:entries}

```

# Answer
Are you trying to get the count of multiple playa entries for each matrix row? If so, you should be able to do something like the following, setting a different namespace prefix for matrix and playa to separate their tags:

```
{your_matrix_field_name var_prefix="mx"}
    Matrix row {mx:row_count} of {mx:total_rows} total rows.<br>

    {mx:your_playa_column_name var_prefix="pl"} {!-- Playa column --}
        Playa entry "{pl:title}" with count of {pl:count}.<br>
    {/mx:your_playa_column_name}

{/your_matrix_field_name}

```

UPDATE: Based on your code example it looks like you're counting Matrix rows, so try:

```
class="{if {row_count} == 1}classnames {/if}
or
{if {row_count} == 1}class="classnames"{/if}

```
> 3 votes

---
Tags: matrix, playa, count
---


# Question
Title: Multiple Sites, Selling The Same Inventory Items
I need to build a network of online stores that all have access to the same inventory items (which will contain stock levels, purchase cost to the store, etc.). The individual stores must have access to this centralized inventory and opt to either sell or not sell the inventory items. They should be able to also see the purchase cost of the inventory items, set their own pricing for the inventory items (ability to do this via bulk would be great, like "20% profit for all items in category x"), etc.

Additionally, it is necessary for the individual stores to be able to add their own inventory items to the their stores. Meaning, they are not limited to just selling the items from the centralized inventory.

The inventory would ideally be stored in a single repository so that adds/edits/deletes can be done centrally.

Also, there needs to be a way to categorize the inventory items in a hierarchical manner.

Is there an addon I can use for this? I have never used Expr-esso or Cathrob -- and I'm not sure if those are the only options I should be looking at.

# Answer
At least with Store, you could do this but it will require some custom development. Out of the box with Store, each MSM site is completely separate and you can't sell items across sites.

However, there are plenty of extension hooks which would let you access the items across sites, and add a site-specific mark-up to the prices.
> 2 votes

# Answer
There is not an addon you can use for this. If you use Store or Cartthrob, you will be customizing heavily IMO since your project requirements are so specific.
> 1 votes

# Answer
No doubt there's a hundred ways to do this - but I think you could do it with CartThrob as well - especially since I think they've recently implemented MSM.

"They should be able to also see the purchase cost of the inventory items, set their own pricing for the inventory items (ability to do this via bulk would be great, like "20% profit for all items in category x")"

I wonder if one way to handle this would be to think of the base cost as an MSRP and use discounts, rather than add price modifiers. As discounts are essentially entries stored in a channel, they could be built by/assigned to different stores via status or custom field, and can be applied to whole cart or entire category, etc, etc.

Will take tinkering, but seems possible.
> 1 votes

---
Tags: expresso-store, add-on, cartthrob, ecommerce, recommendation-request
---


# Question
Title: Is it possible to check (in a template) if a certain ip address has ordered the same article within the last 24 hours?
Is it possible with Expresso Store to check (in a template) if a certain ip address has ordered the same article within the last 24 hours? I have a website where someone can order maxiumum 1 piece of each item. I don't want people to just buy one, then go to the homepage again and be able to buy another ne of the same article. So I need some kind of (possibly ip) check. Is this possible?

# Answer
> 2 votes
I doubt this is something Expresso supports as it's so project specific.

One option is to use jQuery Cookie to track this: http://plugins.jquery.com/cookie/

Set a cookie on the success page and have it expire after 24 hrs or whatever time limit you want... Then on the purchase page, write a conditional against the cookie to determine if you should let them purchase the article or not.

---

Or if you specifically want IP address, store the buyers IP in a hidden field on the product page and submit it to the database when an order is complete. Then write a conditional that checks the database before allowing the buyers to make a purchase.

Or if you specifically want IP, it is stored in the `exp_store_orders` table in the `ip_address` column. There is also an `order_completed_date` column. You can use the Query Module to build your query... then conditionally show the ability to purchase as needed.

# Answer
> 1 votes
You would most definitely need to develop something of your own. Asides from cross-checking IP you could also tie item purchases to an account, maybe even billing/shipping address, etc. depending on the nature of the product and to what extent you're willing to prevent purchases (you'd be blocking more or other than you intended).

# Answer
> 1 votes
You can certainly try and prevent this, but given how the internet works, you're going to have a hard time. People can always sign up for a new account, or use a different internet connection (their phone/ipad on 3G) to get around your check.

Probably the best method is a manual one: just state clearly that it is strictly one item per customer, and follow up with/refund customers who try to break the rules.

---
Tags: expresso-store, expresso
---


# Question
Title: Possible to force unique SAEF-uploaded filenames?
I'm currently building a site right now that allows registered members to add their own logo to entries they create via a SAEF. I have Assets installed for this site but also have SafeCracker File available.

I'm perceiving an issue where multiple members try uploading files like `logo.jpg` thus overwriting other member logos.

Is there a way to keep upload destinations (subfolders?) separate where a member only sees their uploads (if browsing current uploaded items ala Assets) or possibly randomization of uploaded filenames if using a standard File field?

I found this answer on a different question that mentioned that Assets prevents filename collisions but I'm not sure if it allows browsing of existing images, which is not something I want.

Thoughts? Ideas?

# Answer
> 2 votes
I could be wrong, but I think Safecracker File automatically appends a number to the end of any duplicate filenames to avoid collisions. Have you verified that your perceived issue is actually an issue?

---
Tags: assets, file-uploads, image
---


title: Solspace Calendar: Year Header

text:
# Question
Title: Solspace Calendar: Year Header
I'm using the `exp:calendar:events` tag with Solspace Calendar. Is there a convenient way to output a year header, similar to `exp:channel:entries` in my events output?

Thanks!

# Answer
How about something similar to the method using PHP described here?: Solspace's Date Field Filter - can it do date headings?

I'll rehash the answer here with modifications:

Basically, display a heading when the first occurrence of a year is encountered, and store it in a PHP array to avoid displaying the same year again.

```
<?php $heading = array(); ?>
{exp:calendar:events /* your other parameters here */}

    <?php if( ! isset($heading['{event_start_date format="%Y"}']) ) :?>
        <h2>{event_start_date format="%Y"}</h2>
        <?php $heading['{event_start_date format="%Y"}'] = '{event_start_date format="%Y"}'; ?>
    <?php endif ?>

    // Your other code

{/exp:calendar:events}

```

Don't forget to enable PHP for your template.

By the way, if you're looking for a chronological list of events, you should use `{exp:calendar:cal}` instead of `{exp:calendar:events}`. {exp:calendar:cal} will order occurrences stemming from different event entries in the correct timeline order. In other words, occurrences that overlap on a timeline will be ordered correctly and chronologically (e.g. *AABABABBB* instead of *AAAABBBBB*). See this more detailed explanation page for more details: http://www.solspace.com/docs/calendar/getting\_started/
> 2 votes

---
Tags: solspace-calendar, calendar-events
---


title: Passing entire channel entry to plugin

text:
# Question
Title: Passing entire channel entry to plugin
I'm relatively new to ExpressionEngine, and apologise if this seems obtuse!

I have channel entries with a lot of fields associated with them (each channel entry will typically have 20+ channel fields), and I wanted to know if there was a way to pass all those fields to my plugin somehow by just sending through the entire entry itself as a parameter?

Currently, I'm trying to avoid something like this:

```
{exp:channel:entries channel="my_news" limit="10"}
    {exp:my_plugin:process_something field1="" field2="" field3="" ... field40=""}
{/exp:channel:entries}

```

Is there an easy and efficient way to send through all those field values to my plugin? Or alternatively, get the entry itself in the plugin and just pass the entry ID as the parameter, something like:

```
{exp:channel:entries channel="my_news" limit="10"}
    {exp:my_plugin:process_something entry_id="{entry_id}"}
{/exp:channel:entries}

```

...and then in the plugin:

```
public function process_something()
{
    $entry_id = ee()->TMPL->fetch_param('entry_id');
    $entry = < some function / method to get the entry and its details > ;
}

```

Is there something to make this possible? I hope this makes sense, and thank you for any help!

# Answer
> 1 votes
For anyone interested, I eventually went with the following. It provides the essential functionality I was looking for. If anyone has any pointers, suggestions or alternative solutions, please don't hesitate to provide them as I'm still fairly new to EE and will consider them as applicable answers!

First off, in my template:

```
{exp:channel:entries channel="my_news" limit="10"}
    {exp:my_plugin:process entry_id="{entry_id}"}
{/exp:channel:entries}

```

Next, my plugin, located in `\system\expressionengine\third_party\my_plugin\pi.my_plugin.php`:

```
<?php

    if (!defined('BASEPATH')) exit('Page not found.');

    class My_plugin {

        public $return_data;
        public function __construct() {
            $this->return_data = '';
        }

        public function process() {

            // get the entry data...
            $entry_id = ee()->TMPL->fetch_param('entry_id');
            $sql = 'select * from ' . ee()->db->dbprefix('channel_data') .
                ' where entry_id = "'. $entry_id .'"';
            $select = ee()->db->query($sql);

            if ($select->num_rows() > 0) {
                $row = $select->row();
                // do something with the data...
            }
        }
    }

```

# Answer
> 1 votes
By default plugin tags inside modules is executed before parent module. To change the order you need to add parse="inward" parameter to exp:channel:entries tag

```
{exp:channel:entries channel="my_news" limit="10" parse="inward"}
    {exp:my_plugin:process_something entry_id="{entry_id}"}
{/exp:channel:entries}

```

---
Tags: ee2, channel-entries, plugin
---


# Question
Title: Is there a character limit on passwords for Expression Engine?
I've run into an issue I've never seen before regarding a password that appears to be too long. Is there a character limit to passwords?

The client has been using a simple password generator that creates passwords like 'RoadFrame21Bubbles', however a recent password seems to be causing issues, it's 33 characters long and not really different from the format above apart from it's length.

I've tried a shorter password and it works.

The client is reluctant to change this password for their user as they have sent out letters showing the password/user name already.

Any help is appreciated on this.

# Answer
> 1 votes
How were these users added to the system?

As far as I can tell there is no maximum length although the input fields both in the CP and the CP login specify 40 maximum characters. So if they were created the "normal way" in the CP then this shouldn't be an issue (just use the first 40 chars in the pwd to log in).

If they were created programatically then there might be issues though, not sure..

---
Tags: password
---


# Question
Title: search single channel, filter by categories, title and custom field
I want to search thru a channel's entries, they can filter by three different categories (that is fine in EE's advanced search form), as well as the entry title (another thing I can do with EE's advanced search form), but I also want to use one of the custom fields in that channel's field group to be filterable (which is not supported in EE's advanced search form.).

I noticed this add-on http://devot-ee.com/add-ons/search-fields that would allow me to filter by a custom field and entry title, but it looks like I'll have a problem filtering by multiple category groups.

To summarize, I need to search one channel, and search filters would be:

entry title custom field (just one specific field) category group (3 groups)

All filters (except the entry title field will be optional).

Before I go ahead and build a custom module to just search this specific channel (using those filters), I thought I'd see if anyone else dealt with this, thanks!

# Answer
I've not tried it, but have you considered Reefine?

http://devot-ee.com/add-ons/reefine
> 2 votes

# Answer
Reefine is awesome. Used it a couple of times. However, I have found (And it is mentioned in the docs) that if you are using it on a ton of entries, it can be a little slow.

You may also be able to harness dynamic parameters. You can filter a lot down with that. Or even perhaps the search:field\_name= Docs here and use segment variables to filer down.

Hope it helps.
> 2 votes

---
Tags: channel-entries, categories, search
---


title: Cartthrob - setting up hooks

text:
# Question
Title: Cartthrob - setting up hooks
May be a stupid question, but I just can't seem to find any documentation on it.

How do I set up a hook in cartthrob? I need to do some special calculations on the tax.

I tried

```
ee()->cartthrob->core->hooks->set_hook("cart_tax_end");
public function cart_tax_end($tax) {
    return 200;
}

```

But that didn't seem to do anything...

# Answer
CT's hooks work in the same way as native EE hooks. This means that you need to create an extension to use them: http://ellislab.com/expressionengine/user-guide/development/extensions.html

HOWEVER, depending on your exact requirements, it may be best to create a Cartthrob tax plugin: http://cartthrob.com/docs/developers/tax\_plugins/index.html
> 2 votes

---
Tags: cartthrob
---


# Question
Title: Upgrade from 2.6.1 -> 2.7.2 now generates grid field error
After I've upgraded EE from 2.6.1 to 2.7.2, on most of my pages I'm now getting the following error:

```
Error Number: 1054

Unknown column 'L0.grid_field_id' in 'field list'

SELECT DISTINCT `L0`.`field_id` as L0_field, `L0`.`grid_field_id` as L0_grid_field_id, `L0`.`grid_col_id` as L0_grid_col_id, `L0`.`grid_row_id` as L0_grid_row_id, `L0`.`parent_id` AS L0_parent, `L0`.`child_id` as L0_id FROM (`exp_relationships` as L0) LEFT JOIN `exp_relationships` as L1 ON `L0`.`child_id` = `L1`.`parent_id` OR L1.parent_id = NULL WHERE `L0`.`grid_field_id` = 0 AND `L0`.`parent_id` IN (1389) ORDER BY `L0`.`order` asc

Filename: models/relationship_model.php

Line Number: 178

```

I've seen another SE post about it being something to do with the 'setup' script - but it doesn't give any more information.

Anyone seen this before? Any solutions anywhere?

# Answer
Shortly after posting this - I *think* I found the problem. It appears the \_updates\_relationships\_for\_grid() function didn't fire in the ud\_270.php upgrade process... no idea why though since the upgrade didn't fail or error at any point.

Having manually executed the SQL necessary on this function, it looks like it's working now.
> 2 votes

---
Tags: relationships, upgrade, grid
---


# Question
Title: Dukt Videos - JS error on load: TypeError: Cannot read property 'length' of undefined
I've just installed Dukt Videos 1.2.1 (the latest) on EE 2.7.2 and connected it to Vimeo which worked fine. However, when trying to publish an entry to a channel which uses the video field (in Matrix) I get this

```
TypeError: Cannot read property 'length' of undefined
 at Function.b.extend.each (http://example.com/themes/javascript/compressed/jquery/jquery.js?v=1385992367:36:478)
    at Object.MainCtrl.$scope.providerRouting (http://example.com/themes/third_party/dukt_videos/components/videos-common/js/angular/controllers.js:225:5)
    at http://example.com/themes/third_party/dukt_videos/components/videos-common/js/angular/controllers.js:46:12
    at http://example.com/themes/third_party/dukt_videos/components/bower_components/angular-resource/angular-resource.js:413:30
    at wrappedCallback (http://example.com/themes/third_party/dukt_videos/components/bower_components/angular/angular.js:6995:59)
    at http://example.com/themes/third_party/dukt_videos/components/bower_components/angular/angular.js:7032:26
    at Object.Scope.$eval (http://example.com/themes/third_party/dukt_videos/components/bower_components/angular/angular.js:8218:28)
    at Object.Scope.$digest (http://example.com/themes/third_party/dukt_videos/components/bower_components/angular/angular.js:8077:25)
    at Object.Scope.$apply (http://example.com/themes/third_party/dukt_videos/components/bower_components/angular/angular.js:8304:24)
    at done (http://example.com/themes/third_party/dukt_videos/components/bower_components/angular/angular.js:9357:20)

```

Anyone know what might be going on?

# Answer
> 2 votes
Finally found the origin of the problem, which comes from an old bug with the Vimeo API.

Short version is that there is a bug happening when you have only one Vimeo album.

Long version is that the Vimeo API was requested for a list (array) of your albums, and if you had only one album created, was returning the album object, straight, instead of an array of albums (even if dealing with only one).

This particular situation was handled, but now that they have fixed the problem on their end, it's throwing bugs to people using Videos with only one album.

Will be fixed in the next update.

For now, you can whether create an additional album or comment the following lines in dukt\_videos/vendor/dukt/videos/src/Dukt/Videos/Vimeo/Service.php (~ line 553), to make it look like this :

```
private function extractCollections($r, $type='album')
{
    $responseCollections = $r;

    $collections = array();

    // if(count($responseCollections) == 1) {
    //     $responseCollections = array($responseCollections);
    // }

    foreach($responseCollections as $responseCollection)
    {
        $collection = new Collection();

        $collection->{'instantiate'.ucwords($type)}($responseCollection);

        array_push($collections, $collection);
    }

    return $collections;
}

```

Hope this helps !

---
Tags: video
---


title: How to include home path in template

text:
# Question
Title: How to include home path in template
I am wondering if there is a way to dynamically call an ExpressionEngine home path. For instance, in Wordpress they use `<?php echo home_url(); ?>`, is there an equivalent for ExpressionEngine? I am wanting to link to my stylesheets without putting the absolute static path into the href.

Thanks in advance!

# Answer
> 5 votes
Try using `{site_url}` which will return the site's homepage url such as http://www.mysite.com

---
Tags: css, path
---


title: dynamically displaying page titles

text:
# Question
Title: dynamically displaying page titles
I have always displayed a channel entry's title like so:

```
{exp:channel:entries channel="news"}{embed="partials/.header" page_title="{title}"}{/exp:channel:entries}
  Body
{embed="partials/.footer"}

```

What is the best way of including the entry's title in the header partial template of the html?

```
// .header
<head>
 <title>{embed:page_title}</title>
</head>

```

# Answer
> 5 votes
I recommend using **SEO Lite**. It will save you from having to open up a channel:entries tag just to grab the title.

Plus it can be used for a meta description tag (which is also useful for og:description and social share text). And it has a variety of useful parameters to help you pull the right title and to add prefixes or suffixes to your title.

Just install the module and it creates a tab in the publish form.

OR...if you want something even simpler and only care about *titles*, then the Low Title plugin works great for that.

# Answer
> 2 votes
The **Variables** plugin is a good option for passing data to the header embed.

> The variables plugin gives the possibility to create variables (either static or dynamic) and use them later on. This means that for example you can set certain data and use it in the head (if it's embedded) without having to re-create a tag pair for the specific channel.

Set a variable like this inside your template:

```
{exp:variables:set name="entry_id" value="{entry_id}"}
OR
{exp:variables:set name="entry_id" value="1"}

```

And get it like this in the header:

```
{exp:variables:get name='entry_id'}

```

---
Tags: channel-entries, channel, embeds, template-partials
---


# Question
Title: Need Help Troubleshooting Custom Cartthrob Plugin
I have a custom plugin that was made by a previous developer. The client has asked for it to be modified to display all items ordered, instead of just one, and for some reason, the item name field is only displaying for the first result.

Here is the code. I'm sure it's something simple I'm overlooking:

```
    class Purchased_items {

    public $return_data;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->EE =& get_instance();
        $this->date_id_field = 'field_id_84';
    }

    // ----------------------------------------------------------------

    public function order_count()
    {
        $member = $this->EE->session->userdata('member_id');
        $count = 0;
        if($member)
        {
            $query = $this->EE->db->get_where("channel_titles", array("author_id" => $member, "channel_id" => 7, "status" => "complete"));
            $count = $query->num_rows();
        }
        return $count;
    }

    public function items()
    {
        $id = $this->EE->input->post('search:purchased_id');
        $start = $this->EE->input->post('start_on');
        $end = $this->EE->input->post('stop_before');

        $this->EE->db->save_queries = TRUE;
        $this->EE->db->from('cartthrob_order_items AS oi');
        $this->EE->db->join('channel_titles AS o', 'oi.order_id = o.entry_id', 'inner');
        $this->EE->db->join('channel_data AS od', 'o.entry_id = od.entry_id', 'inner');
        $this->EE->db->join('delivery_dates AS d', 'od.'.$this->date_id_field.' = d.date_id', 'left');
        $this->EE->db->select('oi.*, o.entry_date, d.date');
        if($id !=""){
            $this->EE->db->where(array('oi.entry_id' => $id, 'o.entry_date >=' => strtotime($start), 'o.entry_date <=' => strtotime($end), 'o.status' => 'complete'));
        }else{
            $this->EE->db->where(array('o.entry_date >=' => strtotime($start), 'o.entry_date <=' => strtotime($end), 'o.status' => 'complete'));
        }
        $query = $this->EE->db->get();

        // print_r($this->EE->db->last_query());
        // exit(print_r($query->result_array()));

        $dates = array();

        $item_options = array("default" => array("option_name" => "", "count" => 0, "total" => 0, "total_plus_tax" => 0, "day_totals" => array()));
        $date_counts = array();

        if($query->num_rows() == 0)
        {
            return $this->EE->TMPL->no_results();
        }
        else
        {
            foreach( $query->result_array() as $item )
            {
                $vars[0]["title"] = $item["title"];

                if( $item['extra'] != "" ){
                    $options = unserialize(base64_decode($item["extra"]));
                    $product_option = $options['product_options_other'];
                }
                if( $item['extra'] == "" || $product_option == "" ){
                    $name = "default";
                    $item_options[$name]["count"] += $item['quantity'];
                    $item_options[$name]["total"] += $item['price'];
                    $item_options[$name]["total_plus_tax"] += $item['price_plus_tax'];
                }
                else {
                    $extra = unserialize(base64_decode($item["extra"]));
                    $name = $extra['product_options_other'];
                    if( !isset($item_options[$name]) ){
                        $item_options[$name] = array("option_name" => $name, "count" => 0, "cost" => 0, "total" => 0, "total_plus_tax" => 0, "day_totals" => array());
                    }
                    $item_options[$name]["count"] += $item['quantity'];
                    $item_options[$name]["total"] += $item['price'];
                    $item_options[$name]["total_plus_tax"] += $item['price_plus_tax'];
                }
                if( !isset($item_options[$name]["dates"]) ){
                    $item_options[$name]["dates"] = array();
                }
                if( $item['date'] != "" ){
                    if( !isset($item_options[$name]['day_totals'][$item['date']] )){
                        $item_options[$name]['day_totals'][$item['date']] = array("date"=>$item['date'], "total_for_day" => 0);
                    }
                    $item_options[$name]['day_totals'][$item['date']]['total_for_day'] += $item['quantity'];
                }

            }
            // $vars = array("item_options" => array());
            if( $item_options["default"]["count"] == 0 ){
                unset($item_options["default"]);
            }
            foreach( $item_options as $option )
            {
                $option["day_totals"] = array_values($option["day_totals"]);
                $option["total"] = "$".number_format($option["total"], 2);
                $option["total_plus_tax"] = "$".number_format($option["total_plus_tax"], 2);
                $vars[0]['item_options'][] = $option;
            }
            return $this->EE->TMPL->parse_variables($this->EE->TMPL->tagdata, $vars);
        }
    }

}

```

Any help is appreciated.

Thanks!

# Answer
> 2 votes
Your problem is here:

```
$vars[0]["title"] = $item["title"];

```

Since that's inside a `foreach` loop, your resulting data is always limited to a single row (row "0").

Try this, starting at the appropriate matching spot:

```
if($query->num_rows() == 0)
{
    return $this->EE->TMPL->no_results();
}
else
{
    $vars = array();
    $i = 0;
    foreach( $query->result_array() as $item )
    {
        $vars[$i]["title"] = $item["title"];

        if( $item['extra'] != "" ){
            $options = unserialize(base64_decode($item["extra"]));
            $product_option = $options['product_options_other'];
        }
        if( $item['extra'] == "" || $product_option == "" ){
            $name = "default";
            $item_options[$name]["count"] += $item['quantity'];
            $item_options[$name]["total"] += $item['price'];
            $item_options[$name]["total_plus_tax"] += $item['price_plus_tax'];
        }
        else {
            $extra = unserialize(base64_decode($item["extra"]));
            $name = $extra['product_options_other'];
            if( !isset($item_options[$name]) ){
                $item_options[$name] = array("option_name" => $name, "count" => 0, "cost" => 0, "total" => 0, "total_plus_tax" => 0, "day_totals" => array());
            }
            $item_options[$name]["count"] += $item['quantity'];
            $item_options[$name]["total"] += $item['price'];
            $item_options[$name]["total_plus_tax"] += $item['price_plus_tax'];
        }
        if( !isset($item_options[$name]["dates"]) ){
            $item_options[$name]["dates"] = array();
        }
        if( $item['date'] != "" ){
            if( !isset($item_options[$name]['day_totals'][$item['date']] )){
                $item_options[$name]['day_totals'][$item['date']] = array("date"=>$item['date'], "total_for_day" => 0);
            }
            $item_options[$name]['day_totals'][$item['date']]['total_for_day'] += $item['quantity'];
        }

        if( $item_options["default"]["count"] == 0 ){
            unset($item_options["default"]);
        }
        foreach( $item_options as $option )
        {
            $option["day_totals"] = array_values($option["day_totals"]);
            $option["total"] = "$".number_format($option["total"], 2);
            $option["total_plus_tax"] = "$".number_format($option["total_plus_tax"], 2);
            $vars[$i]['item_options'][] = $option;
        }
        $i++;
    }
    return $this->EE->TMPL->parse_variables($this->EE->TMPL->tagdata, $vars);
}

```

---
Tags: cartthrob, php, plugin
---


# Question
Title: Check if category is assigned in channel entry conditional
I am trying to use templates in embeds depending on the users' category selection but I don't know how to check if a category has been assigned or not.

```
{categories}
    {if category_url_title=="full-page-review"}
        {embed="temp-group/.full_page_review" entry_id="{entry_id}"}
    {if:elseif category_url_title=="standard"}
        {embed="temp-group/.standard" entry_id="{entry_id}"}
    {/if}
{/categories}

```

This works fine as long as a category has been assigned in the entry, but nothing happens if the author forgot to assign a category. Is there a way to see if there is a category assigned or not while using a conditional like this?

# Answer
> 9 votes
I was able to accomplish what I was after using the following...

```
{if "{categories}{category_url_title}{/categories}"!=""}
    CATEGORY EXISTS
{if:else}
    NO CATEGORY EXISTS
{/if}

```

# Answer
> 2 votes
I use Switchee to check for the length of a string (e.g. for a change in design if title is too long). I suppose it could be adapted to check if the string is empty or not:

```
      {exp:switchee parse="inward" variable="{categories}{category_url_title}{/categories}"}
        {case value="full-page-review"}
          {embed="temp-group/.full_page_review" entry_id="{entry_id}"}
        {/case}
        {case value="standard"}
          {!-- just here as an example --}
          {embed="temp-group/.standard" entry_id="{entry_id}"}
        {/case}
        {case value="#^.{1,}$#"}
        {!-- regex of ^.{1,}$ means match any character of 1 or more,
             I would have another number after the comma though.
             You could just try #^.+$# instead, don't see why that wouldn't work --}
          {!-- unaccounted for case, but category exists --}
          {embed="temp-group/.standard" entry_id="{entry_id}"}
        {/case}
        {case default="Yes"}
          {!-- unaccounted for case, category DNE --}
          {embed="temp-group/.standard" entry_id="{entry_id}"}
        {/case}
      {/exp:switchee}

```

The above assumes that `{category_url_title}` will not leave whitespace before/after it.

---
Tags: channel-entries, categories, conditionals
---


# Question
Title: Expresso Store - remember form fields if inline error
I wish to pre-populate my billing and shipping details for logged in members

VALUE="{exp:member:custom\_profile\_data}{firstName}{/exp:member:custom\_profile\_data}"

This correctly populates the form fields however when I submit the form when there is an error on the form such as a required field not being complete all the form fields are reset to blank.

So I basically need something along the lines of the following:

if inline error then use

```
VALUE="{firstName}"

```

otherwise use the following:

```
VALUE="{exp:member:custom_profile_data}{firstName}{/exp:member:custom_profile_data}"

```

Is this possible? If so anyone care to share the syntax?

Thanks

# Answer
> 3 votes
If you map the form fields by going to Store \> Settings \> Order Fields and map each of the order fields to your respected member profile fields as seen in the screenshot:

You can then use:

```
{field:first_name}

```

or

```
{field:billing_state}

```

to have the value populated automatically on return visits for that member but also will persist through page loads.

**EDIT:**

As Adrian mention in the comments you need to empty your cart anytime you make changes to your member data as it is only loaded once.

---
Tags: expresso-store
---


title: How to make Playa drop down wider?

text:
# Question
Title: How to make Playa drop down wider?
I have a Playa field associated with a channel of entries that have long names, often identical for much of the first 20/30 characters. My Playa field is configured to not allow multiple values and is thus a drop down.

When the drop down is clicked the entries are listed in full, with character wrapping. This allows me to find the entry that I want. But once selected the displayed choice is now truncated with ellipsis so I can't see the identity of the item that I selected.

How can I make this field wider on the CP screen? I have plenty of horizontal width - the Playa field is in a Matrix field that has two columns, each at 50% of the screen.

# Answer
In my

> themes/cp\_themes/default/css/override.css

file I added the following to control the horizontal sizing of the Playa single-select drop-down field to have up to 300px width. Would love to hear of a better method.

```
/* Make the Playa single select drop down fields wider.
 *
 * From http://expressionengine.stackexchange.com/a/17327/2436
 *
 * The fields have a restricted width despite the amount of screen
 * space that is available. This causes the selected item to be truncated
 * with ellipsis. When we use a long naming convention with our channel
 * entries and then use the single-select Playa drop down layout, the
 * string is truncated - not useful if it is the right hand end that
 * has the distinguishing information.
 *
 * The approach is to style the various fields at 100% to occupy the
 * available screen width, but then restrict the width to a reasonable
 * maximum value. Your definition of "reasonable maximum value" will
 * vary.
 *
 * Note that some elegance has been lost with the drop-down arrow
 * being pushed to the edge of the outer bordered box with no padding.
 * This works good enough for now.
 */

/*  The outer box that is drawn around the drop dwn field */
.playa-ss {width: 100% !important; max-width: 300px; }

/* The publish/edit screen is first drawn.
 *
 * This is the selected text when the screen is first drawn with an already
 * selected entry. We need to allow each level to be as wide as possible
 * but not be too wide.
 */
.playa-ss table td.playa-ss-input                        {width: 100% !important; max-width: 300px; }
.playa-ss table td.playa-ss-input li.playa-dp-selected   {width: 100% !important; max-width: 300px; }
.playa-ss table td.playa-ss-input li.playa-dp-selected a {width: 100% !important; max-width: 300px; }

/* The user clicks on the field to make a choice.
 *
 * When the drop-down field is expanded the available values
 * are contained within a <ul> list within a playa-ss-entries
 * division. Make sure that the drop down has the same width
 * so that we can see the choices without line wrapping.
 */
div.playa-ss-entries { width: 100%; max-width: 300px; }

/* A choice has been made (but not yet saved).
 *
 * When the item has been selected the DOM is changed to
 * have a playa-entry list item that contains the anchor
 * that has the label text of the item selected.
 */
.playa-ss table td.playa-ss-input                        {width: 100% !important; max-width: 300px; }
.playa-ss table td.playa-ss-input li.playa-entry         {width: 100% !important; max-width: 300px; }
.playa-ss table td.playa-ss-input li.playa-entry       a {width: 100% !important; max-width: 300px; }

```
> 2 votes

# Answer
EE allows you to override control panel styling by adding a override.css stylesheet to the themes folder. So you could just add this rule within that stylesheet:

```
.playa-ss {width: 100% !important}

```
> 3 votes

---
Tags: playa, publish-layout
---


# Question
Title: Wygwam - IE8 issue - editor doesn't load and throws javascript error
We're having an odd issue with several sites we run on ExpressionEngine for clients using IE8 and 9 in the control panel. I've seen similar problems here on the forum but nothing that fits the bill here exactly (or solves the problem)

When an edit entry screen loads, the WygWam editor starts to load and then disappears leaving an empty space and a javascript error. Screengrab attached. I've managed to replicate the problem in Browserstack, so i'm fairly confident it's not an issue with the end user's machines.

Error is:

'name' is null or not an object ckeditor.js line 804

Enabling IE compatability mode doesn't seem to help either. It seems to be working ok on one site which is running v 2.3.4.1 but fails on two other sites running 3.1.2

Any ideas on how we might fix this? As having the client ring me and make the changes myself every time is very quickly going to wear thin!

Cheers!

# Answer
> 2 votes
I just tested an IE8 page load using IE Tester with WYGWAM 3.2.1 installed and there wasn't an error. WYGWAM is at version 3.2.2 as of Nov 13, 2013 so I'd suggest an upgrade as the first step.

---
Tags: wygwam
---


# Question
Title: Has anyone had experience filtering products, based on the quantity at a retail location?
I am trying to set up a product filter where I can filter by: Store location, type of product, and price.

I have 36 retails locations in total, and only want to display products that have a greater quantity then 0. The only things that changes from location to location is the quantity.

I have used the module "reefine" before for something similar, but don't believe it would work in this case. As i am importing the information from a ".csv" file using the module "data grab", which needs its own channel field for each row in the .csv file.

I need to show the quantity of product X, at retail location Y.

I am thinking modules might not be the way to go for this project. Just wanted to ask and see if anyone has run into something similar.

# Answer
Sounds like **Numeric Matching** with the **search=""** parameter may help. This is a parameter for the `channel:entries` tag.

> If you have a field containing numeric data, you may use greater-than or less-than operators to search through them.
>
> search:numeric\_field="\<20"
> search:numeric\_field="\>20"
> search:numeric\_field="\<=20"
> search:numeric\_field="\>=20"

---

If you need complete search functionality these are the two search addons to check out:

http://gotolow.com/addons/low-search
http://www.solspace.com/software/detail/super\_search/

You'll need to read their docs to make sure they do exactly what you need.
> 2 votes

---
Tags: filter
---


title: Solspace User, unable to reset password

text:
# Question
Title: Solspace User, unable to reset password
I'm working on an EE 1.6.8 site with SolSpace User 3.0.1 . The password reset form does not seem to be working. When entering the new password in the Confirm New Password box, a message comes up straight away "Please enter the same value again". Both passwords are the same. Thanks.

```
{exp:user:edit return="account/index"}

<h1>Change Password</h1>

<p><label for="password">New Password</label> <input type="password" name="password" class="pass" /></p>
<p><label for="password_confirm">Confirm New Password</label> <input type="password" name="password_confirm" /></p>
<p><label for="current_password">Current Password </label><input type="password" name="current_password" /></p>

<p><input type="submit" value="Update" /></p>

{/exp:user:edit}

```

# Answer
At a glance your code looks fine to me.

If you look at the change log for User module you'll see many changes relating to passwords.

Some examples:

* Fixed a bug where edit\_profile was xss cleaning password\_confirm and current\_password, unintentionally disallowing ampersands and other special characters in passwords.
* Fixed a bug where the Register and Edit tags were messing up passwords containing ampersands.
* Fixed a bug where ampersands in passwords would cause issues from User

Perhaps you should update and see if the issue persists.
> 2 votes

---
Tags: ee1, solspace-user
---


title: Exclude entries from search results

text:
# Question
Title: Exclude entries from search results
Using EEs native Search, is there a way to exclude specific entries from the results?

Enabling, 'Is field searchable?' in the field settings tells EE which fields to use but these are global to the whole Channel.

I've got 4 entries I specifically don't want showing in the results. I'm manually excluding using if statements, hopefully there's a more elegant way of doing this?

# Answer
> 3 votes
There isn't really an elegant way to do this... All ways are "creative". Using the conditional to exclude is the easiest way IMO because it only affects that template.

# Answer
> 3 votes
I set up a status for "hide from search" or similar. This means that the results aren't shown as my search is only showing open entries.

Of course, it does mean that you need to set any entries tags that are meant to show these entries to include the status as well as just showing those with a status of "open".

# Answer
> 1 votes
I would go with conditional statement as well, this is probably the easiest/fastest and most effective (as @Anna\_MediaGirl mentioned above) way to do it.

---
Tags: search
---


title: Stash no_results problems

text:
# Question
Title: Stash no_results problems
I'm having two separate **no\_results** problems with Stash.

First, if I visit a page that doesn't have a corresponding last segment using the code below, the page displays stuff like `{2e1acf078c376a119e542c46883a119f33292409}` and nothing else:

```
{stash:embed name="layouts:global"}

{exp:channel:entries
    channel="site"
    url_title="{last_segment}"
    disable="categories|member_data|pagination|trackbacks"
    require_entry="yes"
}
    {if no_results}{redirect="404"}{/if}

    {exp:stash:set name="st_content" type="snippet"}
        {body}
    {/exp:stash:set}

{/exp:channel:entries}

```

Then in another template, the switchee\_no\_results doesn't redirect to the 404 template, it just displays a page with a blank content area. I've also tried just plain no\_results and also settings a prefix parameter on the get\_list tag.

```
{stash:embed name="layouts:global"}

{exp:stash:set_list
    name="project_list"
    parse_tags="yes"
}

    {exp:channel:entries
        channel="projects"
        disable="member_data|pagination|trackbacks"
        {if segment_2=="detail"}url_title="{last_segment}"{/if}
    }

        {stash:project_url_title}
            {url_title}
        {/stash:project_url_title}

        {stash:project_detail}
            <h2>{title}</h2>
            {project_text}
        {/stash:project_detail}

    {/exp:channel:entries}

{/exp:stash:set_list}

{exp:stash:set name="st_content" type="snippet"}

    {exp:switchee variable="{segment_2}" parse="inward"}

        {!-- Landing page --}
        {case value=""} … {/case}

        {!-- Detail page --}
        {case value="detail"}

        {exp:stash:get_list
            name="project_list"
            match="#{segment_3}#"
            against="project_url_title"
            parse_conditionals="yes"
            parse_tags="yes"
            process="end"
        }

        {if switchee_no_results}{redirect="404"}{/if}

        {project_detail}

        {/exp:stash:get_list}

        {/case}

    {/exp:switchee}

{/exp:stash:set}

```

Anyone know why that might be?

# Answer
The short answer is to use a full template\_group/template path to your 404, e.g.

```
{redirect="site/404"}

```

I explained the reason why here: Strange Stash & redirect issue

EDIT:

Since this post was made I have added a new tag `{exp:stash:not_found}` to help with situations where the no\_results condiotonals are nested inside other tags:

https://github.com/croxton/Stash/wiki/%7Bexp%3Astash%3Anot\_found%7D

Note that the best place to use `{if no_results}...` is on the tag that you are trying to capture data from.
> 2 votes

---
Tags: stash, no-results
---


title: Stash cache site navigation from nav:ee

text:
# Question
Title: Stash cache site navigation from nav:ee
So building on the answers from my previous question, I'm trying to cache the main navigation on my site.

As I understand it, the principle is to cache everything in one big chunk and then use the `stash:nocache` tag to except the conditionals used for the active state.

The relevant part of my code is:

```
{exp:stash:set name="full_nav_cache" parse_tags="yes" parse_conditionals="yes" output="yes" save="yes" refresh="180" replace="no" scope="site"}
    {exp:navee:custom nav_title="main-nav" wrap_type="none"}
        <li class="{stash:nocache}{if '{site_url}{segment_1}/' == {/stash:nocache}'{link}'{stash:nocache}}selected{/if}{/stash:nocache}">
    {/exp:navee:custom}
{/exp:stash:set}

```

However, it seems like the `{segment_1}` variable is still parsed when the cache is saved. In the database I'm seeing:

```
<li class="{if '{site_url}/products/' == 'http://mysite.com/products/'}selected{/if}">

```

But I was expecting:

```
<li class="{if '{site_url}{segment_1}/' == 'http://mysite.com/products/'}selected{/if}">

```

which would then get parsed on the page load. Is the the expected behavior?

# Answer
> 3 votes
If you use that code in an EE template (rather than a Stash embed) then EE will parse `{segment_1}` early, before tags are run and before Stash can escape it.

See step 1 here: http://loweblog.com/downloads/ee-parse-order.pdf

The good news is you can access any global variable or snippet as a tag like this:

```
{exp:stash:get name="segment_1" type="snippet"}

```

Thus:

```
{exp:stash:set name="full_nav_cache" parse_tags="yes" parse_conditionals="yes" output="yes" save="yes" refresh="180" replace="no" scope="site"}
    {exp:navee:custom nav_title="main-nav" wrap_type="none"}
        <li class="{stash:nocache}{if '{site_url}{exp:stash:get name="segment_1" type="snippet"}/' == {/stash:nocache}'{link}'{stash:nocache}}selected{/if}{/stash:nocache}">
    {/exp:navee:custom}
{/exp:stash:set}

```

---
Tags: stash, cache, navee
---


title: Uploading images

text:
# Question
Title: Uploading images
I am unable to upload images to my site. I haven't made any significant changes to it lately and was able to successfully do it before. How can this be fixed please?

# Answer
> 1 votes
The most likely reasons are:

* Upload path not valid - Fix under content \> upload preferences
* Cannot write to folder - Check folder exists and has 777 permissions

---
Tags: file-uploads
---


title: Nested list to show product options

text:
# Question
Title: Nested list to show product options
In the following code I'm using Expresso store to stash the current user's basket away.

Win it I'm setting a nested list so that I can loop through the options and display them as a definition list.

However that nested list doesn't seem to be returning.

Can anybody spot what's wrong here?

**Set List**

```
{exp:store:cart}
    {exp:stash:set name="basket-total"}{order_subtotal}{/exp:stash:set}
    {exp:stash:set_list name="basket-items" process_tags="yes"}
        {items}
            {stash:title}{title}{/stash:title}
            {stash:quantity}{item_qty}{/stash:quantity}
            {stash:entry-id}{entry_id}{/stash:entry-id}
            {stash:price}{exp:stash:embed:rcf:ecom_price stash:entry-id="{entry_id}"}{/stash:price}
            {stash:subtotal}{item_subtotal}{/stash:subtotal}

            {exp:stash:set_list:nested name="options"}
                {modifiers}
                    {stash:option}{modifier_name}{/stash:option}
                    {stash:value}{modifier_value}{/stash:value}
                {/modifiers}
            {/exp:stash:set_list:nested}
        {/items}
    {/exp:stash:set_list}
{/exp:store:cart}

```

---

**Get List**

```
    {exp:stash:get_list name="basket-items"}
        <tr>
            <td class="basket--image"><img src="http://placehold.it/90x90"></td>
            <td class="basket--item">
                <strong>{title}</strong>
                <ul class="basket--item--controls">
                    <li><a href="#">Remove</a></li>
                </ul>
            </td>
            <td class="basket--options">
                <dl>
                    {exp:stash:get_list:nested name="options"}
                        <dt>{option}</dt>
                        <dd>{value}</dd>
                    {/exp:stash:get_list:nested}
                    <dt>Quantity:</dt>
                    <dd>{quantity}</dd>
                </dl>
            </td>
            <td class="basket--item-sub-total">{subtotal}</td>
        </tr>
    {/exp:stash:get_list}

```

# Answer
I found the solution. I was using `process_tags` instead of the correct `parse_tags`.

For people who found this, this is the code that works so far.

**Setter**

```
{exp:store:cart}
{exp:stash:set name="basket-total"}{order_subtotal}{/exp:stash:set}

{!-- Set a list of all the products in the user's basket and save it for 2 hours unless the user updates it --}
{exp:stash:set_list name="basket-items" scope="user" save="yes" refresh="120" {if segment_2=="added"||segment_2=="updated"}replace="yes"{/if} parse_tags="yes"}
    {items}
        {stash:title}{title}{/stash:title}
        {stash:quantity}{item_qty}{/stash:quantity}
        {stash:entry-id}{entry_id}{/stash:entry-id}
        {stash:price}{exp:stash:embed:rcf:ecom_price stash:entry-id="{entry_id}"}{/stash:price}
        {stash:subtotal}{item_subtotal}{/stash:subtotal}
        {stash:key}{key}{/stash:key}

        {!-- Stash the modifiers for this option away --}
        {exp:stash:set_list:nested name="options-{key}"}
            {modifiers}
                {stash:option}{modifier_name}{/stash:option}
                {stash:value}{modifier_value}{/stash:value}
            {/modifiers}
        {/exp:stash:set_list:nested}

    {/items}

{/exp:stash:set_list}
{/exp:store:cart}

```

**Getter**

```
<table>
<thead>
    <tr>
        <th colspan="2">In stock available to buy today</th>
        <th>Your Options</th>
        <th>Price</th>
    </tr>
</thead>
<tfoot>
    <tr>
        <td colspan="3">Subtotal</td>
        <td>{stash:basket-total}</td>
    </tr>
</tfoot>
<tbody>
    {exp:stash:get_list name="basket-items"}
        <tr>
            <td class="basket--image"><img src="http://placehold.it/90x90"></td>
            <td class="basket--item">
                <strong>{title} - {key}</strong>
                <ul class="basket--item--controls">
                    <li><a href="#">Remove</a></li>
                </ul>
            </td>
            <td class="basket--options">
                <dl>
                    {exp:stash:get_list:nested name="options-{key}" parse="inward"}
                        <dt>{option}</dt>
                        <dd>{value}</dd>
                    {/exp:stash:get_list:nested}
                    <dt>Quantity:</dt>
                    <dd>{quantity}</dd>
                </dl>
            </td>
            <td class="basket--item-sub-total">{subtotal}</td>
        </tr>
    {/exp:stash:get_list}
</tbody>

```
> 2 votes

---
Tags: expresso-store, stash
---


# Question
Title: Javascript not working properly in template
I'm having a problem linking a javascript file to my template. I'm using the standard tag:

```
<script type="text/javascript" src="{template_root}site_script.js"></script>

```

Where {template\_root} is the location of my template files. I have tested this URL (stored as a global variable} for accuracy. For testing purposes, my site\_script.js file looks like this:

```
$( document ).ready(function() {
    alert( "ready!" );
});

```

However no dialogue is popping up. I took a look in the console log and it says "**ReferenceError: Can't find variable: $**". I'm really at a loss here and I would appreciate if someone can show me where I may have made an error?

I'm not sure if this is necessary or helpful, but here is my index template file for context:

```
<!doctype html>

<html>
    <head>
        <meta charset="UTF-8">

        <!-- Force proper sizing -->
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <!-- Styles that require EE Template Tag Parsing -->
        {exp:channel:entries channel="preferences"}<style type="text/css">
            body {background-image:url('{background_image}');}
            .color {color: #{primary_highlight_color};}
            .color_bg {background-color: #{primary_highlight_color};}
            .nav_circle {background-color:rgba(0,0,0,{nav_opacity_unselected});}
        </style>
        {/exp:channel:entries}

        <!-- TypeKit Scripts  -->
        <script type="text/javascript" src="//use.typekit.net/yjd5vpe.js"></script>
        <script type="text/javascript">try{Typekit.load();}catch(e){}</script>

        {exp:channel:entries channel="preferences"}
            <title>{title}</title>
        {/exp:channel:entries}

        <!-- Stylesheets -->
        <link rel="stylesheet" type="text/css" media="all" href="{stylesheet='website/global'}" />
        <link rel="stylesheet" type="text/css" media="all" href="{stylesheet='website/web'}" />
        <link rel="stylesheet" type="text/css" media="all" href="{stylesheet='website/mobile'}" />

        <!-- Bootstrap -->
        <link href="{template_root}bootstrap/css/bootstrap.min.css" rel="stylesheet">
        <!--[if lt IE 9]>
        <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
        <script src="https://oss.maxcdn.com/libs/respond.js/1.3.0/respond.min.js"></script>
        <![endif]-->

        {!--
        <!-- Development Stylesheets -->
        <link rel="stylesheet" type="text/css" media="all" href="global.css" />
        <link rel="stylesheet" type="text/css" media="all" href="web.css" />
        <link rel="stylesheet" type="text/css" media="all" href="mobile.css" />
        <!-- Development Javascript -->
        <script type="text/javascript" src="site_script.js"></script>
        --}

    </head>

    <body>
        <div id="wrapper">

            <!-- masthead Snippet-->
            <div class="masthead">
                {exp:channel:entries channel="preferences"}<div class="logo"><img src="{dandelion_logo}" /></div>{/exp:channel:entries}
                {exp:channel:entries channel="contact"}<div class="nav_social_icons" />test</div>{/exp:channel:entries}
                <div id="navigation">

                    <div class="nav_item">
                        <div class="nav_circle">
                            {exp:channel:entries channel="Cart"}<img src="{cart_icon}" class="nav_icon_cart" />
                        </div>
                        <div class="nav_title">
                            {title}
                        </div>{/exp:channel:entries}
                    </div> <!-- Cart .nav_item -->

                    <div class="nav_item">
                        <div class="nav_circle">
                            {exp:channel:entries channel="Shop"}<img src="{shop_icon}" class="nav_icon_shop" />
                        </div>
                        <div class="nav_title">
                            {title}
                        </div>{/exp:channel:entries}
                    </div> <!-- Shop .nav_item -->

                    <div class="nav_item">
                        <div class="nav_circle">
                            {exp:channel:entries channel="events"}<img src="{events_icon}" class="nav_icon_events" />
                        </div>
                        <div class="nav_title">
                            {title}
                        </div>{/exp:channel:entries}
                    </div> <!-- Events .nav_item -->

                    <div class="nav_item">
                        <div class="nav_circle">
                            {exp:channel:entries channel="contact"}<img src="{contact_icon}" class="nav_icon_contact" />
                        </div>
                        <div class="nav_title">
                            {title}
                        </div>{/exp:channel:entries}
                    </div> <!-- Contact .nav_item -->

                    <div class="nav_item">
                        <div class="nav_circle">
                            {exp:channel:entries channel="home"}<img src="{home_icon}" class="nav_icon_home" />
                        </div>
                        <div class="nav_title">
                            {title}
                        </div>{/exp:channel:entries}
                    </div> <!-- Home .nav_item -->

                </div> <!-- #navigation -->
            </div> <!-- .masthead -->

    WRAPPER BOTTOM<br />
        </div> <!-- .wrapper -->

    <!-- Javascript -->
    <script type="text/javascript" src="{template_root}site_script.js"></script>
    <!-- Bootstrap JQuery-->
    <script src="https://code.jquery.com/jquery.js"></script>
    <script src="{template_root}bootstrap/js/bootstrap.min.js"></script>

    </body>
</html>

```

# Answer
This is not actually EE-related - your scripts are in the wrong order. You're calling your `site_script` before you've loaded jQuery:

```
<script type="text/javascript" src="{template_root}site_script.js"></script>
<!-- Bootstrap JQuery-->
<script src="https://code.jquery.com/jquery.js"></script>

```

Reverse the order of those and you should be good.
> 4 votes

---
Tags: jquery
---