# Question
Title: Exp:resso Store - Using Datagrab to Import Excell File + Import Modifiers
Good Afternoon,

We're currently in a testing phase for a client who is looking to move to from xcart to a more developer friendly expressionengine / E-Commerce site with store preferably.

Does anyone have some best practices in mind?

Also, since the client is using FileMaker to sync stock levels on the site with their brick and motor locations POS, I was thinking that Datagrab would be a good solution, but realize that there would be issues with the "modifiers" and shipping weights.

Any thoughts on the best solution as well as any third-party developers that could assist if needed with the scripting for Datagrab?

Current client accounts and history are another bag... but really to get the initial test done I'll just need to get the initial test data to import correctly.

Hope this is detailed enough.

Best regards,

Troy

# Answer
I'm the author of DataGrab.

Support for 3rd party add-ons like Store is largely based on demand.

Initially I added basic support for Store because I needed it for one of my own projects, and then it got extended to add most of the extra fields (eg, stock and sale prices) when another developer needed it.

As you mention it does not currently support price modifiers, but I'd be happy to try and add support.
> 7 votes

# Answer
Andrew Weaver extended DataGrab in the forums to support this I believe. Have a look at his post for more info.

Like Justin said moving forward you'll need an extension to keep both databases synced.
> 5 votes

# Answer
DataGrab does indeed have support for importing data into Store but I have not used it before so I am not to sure exactly what its limitations might be in terms of more complex entry data.

If you are wanting to sync data on a regular basis you would probably be better off with an extension leveraging the store\_order\_complete\_end and store\_inventory\_datatable extension hooks to sync the data between the 2 systems.
> 2 votes

---
Tags: expresso-store, ecommerce, expresso, datagrab
---


title: How to add .html to URL's

text:
# Question
Title: How to add .html to URL's
I am building a reasonable size replacement site in EE and will be migrating content from an existing static-built site.

In order to maintain as many inbound and internal links as possible, what is the best way to add .html to URL's?

Due to the number of URL's involved I don't want to have to redirect each one individually in .htaccess. Using .htaccess to strip .html has been suggested. If this is the best method, what would I need to add to .htaccess to achieve this? Are there any drawbacks or negatives to this method?

# Answer
> 7 votes
I haven't tested this either, but I'm not sure @adrienne's htaccess will work. I'd do it like this:

```
RewriteEngine on

# 301 redirect path.html to just path
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.html$ $1 [R=301,L]

# the rest of your rewrite rules (e.g. removing index.php) go here
RewriteCond $1 !\.(gif|jpe?g|png)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

```

To explain the first few lines, first we make sure the requested html file doesn't exist (so we don't break anything), then we use a regular expression to redirect any \*.html to * using a 301 (permanent) redirect.

Feel free to edit either of these answers if we're not far off :)

# Answer
> 6 votes
You don't need to redirect them individually in .htaccess; you can do a rewrite to strip .html, as you were told.

Below is a set of directives that *should* both route whatever.html to /index.php/whatever/ (for EE) and then remove index.php from everything else. This is, however, not tested, so it might require refinement.

```
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.*)\.html$ /index.php/$1 [R=301,L]

RewriteCond $1 !\.(gif|jpe?g|png|webp|svgz?|tt.|eot|woff|otf|htc|mp.|m4.|og.|flv)$ [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php/$1 [L]

```

There shouldn't be any drawbacks or negatives -- it's a tiny amount of extra overhead, but nothing you would ever notice in the scheme of things.

# Answer
> 0 votes
Have you considered using the Pages module? That's another way of looking at it.

---
Tags: migration, url, .html, htaccess, static
---


title: License Management Process

text:
# Question
Title: License Management Process
I'm looking to put in place a more efficient license management process. I usually buy all EE and EE addon licenses for clients and have no process in place for managing them other than assigning the domain name to the purchase using the EE and Devotee notes fields.

What is your process for managing client licenses?

# Answer
We generally have clients purchase licenses themselves like Adam mentioned, however there are instances (past and present) where we do all the license purchases. For those clients, we use EE to store the data. We created a new channel with a matrix field that includes license number, purchase date, cost, receipt number. It's pretty easy to setup and maintain.
> 15 votes

# Answer
Anna,

In order to minimize any issues with client licenses we always ask them to make the purchase themselves.

We provide them with a detailed set of instructions for using both Devot-ee and any third party sites like Pixel & Tonic.

We find this is advantageous in two ways,

1. The administration process for us is vastly reduced, no invoices for 'materials', better cash flow.
2. The licenses are in their name, if we ever part company with them there is no issues with them getting support directly.

There is also a side effect of this, we quickly learn how willing the client is to participate in the process and their level of attention to detail. This historically has led to a better level of preparation for clients with a lower threshold for detail.

When we have the license numbers we keep them in a text file in a non-public accessible place in the site so that they are available for all who need them/have the right level of access.
> 9 votes

# Answer
With the size of businesses here in Santa Fe (clients are already overstretched in this economy), and the turnover at nonprofits, it's easier to purchase licenses here in the studio and manage them for clients. Otherwise I'd be spending (wasting) way too much time tracking down vital information.

There is the tendency for overkill in managing such information. Rather than use a system that is based on outside services in order to keep track of all info, I have a simple solution: **BBEdit**. Yojimbo, Evernote, Basecamp and other apps and services have been giving me fits - it's the old story, very familiar to old school webloggers who used the original blogging systems. "What you put in, you can't necessarily get out in any usable form."

So ... I have an all-encompassing project set up in BBEdit, and all my information for a given client goes into folders within that project. This could be duplicated with E Text Editor or whatever such editor you use. All important login/configuration/email setup/etc. materials get added to this BBEdit project as individual .txt files. I carry mine on a protected thumb drive when out and about. Can be easily backed up to a secure (note I say *secure*) cloud service. \[Come to think of it, it could even be handled/extended through Git if one desired. Now *there's* a way to overdo it.\] I occasionally copy off a dated version of all clients and dump the project on an external backup system.

Bottom line: Text files mean I can open that information anywhere - on any system - with a text editor. Small footprint, easy to make backups and keep that information safe. Clients remain impressed I have all their configuration information at my fingertips, no matter where I am, or what gear I have with me.

So I find simple's better. Tip: your naming conventions will matter, when you get in a production rush. Be consistent with filenames and folders!
> 4 votes

# Answer
I've tried several times to come up with THE SOLUTION to managing licenses for EE and add-ons, but at the end of the day I keep coming back to the humble Google Docs spreadsheet. It's easily accessible, can be shared with our team, and puts all of the relevant info in the same place.
> 4 votes

# Answer
Using the "Notepad" in the sidebar works as a lo-fi solution too. I also use "Quick Links" to link to training videos I record for the client. You can keep them there too.
> 3 votes

# Answer
We didn't find any commercial products to achieve this, so we've created a simple internal web application to manage all the website information of a client.

Basically we can manage domains and IP info, hosting details, db details, email accounts and also the related licenses (EE+addons) plus the photos licenses, if there are any.

Some of these information are stored with dates expire so we have alerts for any renewal.

And we can easily searching and filtering for the data we need.

It's pretty a hard job of archiving when you set up a website but it worth it.

Our tools are:

* basecamp - for collaborate
* freeagent - to manage client detail, quote and invoices
* our "GestDomain" - to manage any related info to the websites

Usually we don't ask to client to buy themselves license because they don't have time or they don't know how to do that.... And we'll spend a lot of time to teach them how to do it.
> 3 votes

# Answer
We have started using Basecamp as a way to store these kinds of notes on a particular project. It allows the development team to build the site as is needed and then admin/finance to check out what we've been using to purchase the correct licenses and/or inform the client.

It's proven to be useful for us, and because Basecamp gives you unlimited free archived projects this works wonderfully for older projects.

On the flip side, if you were logging in to Devot-ee or EllisLab to see what license is used on what site, I would argue it's going to be naturally difficult and working 'project-upwards' will be easier to manage.
> 2 votes

# Answer
I've found it's a lot easier to buy and manage all licenses for clients as much as possible. This allows me to know for a fact that the client actually has a license allocated to the site. For long term customers, we just manage the licenses for them (and bill them for purchases).

I use an internal system based on Bilt to manage all client information. It allows you to create nested data types (really similar to EE's channels actually, but with nested relationships) to manage content. In my case I use a structure like this to manage project information:

* Projects

+ Project Name
    + Client Name (dropdown)
    + Category (dropdown)
    + Team
    + Active
    + Start Date
    + Due Date
    + Description
    + Systems (multiple records)

    - Description
        - Server / URL
        - Password
        - Type
        - Username
        - Database
        - License
        - Notes

I store the customer's License keys for each product used on the Systems tab. Each of these items can have comments added to it, when requesting a transfer to another account (which EllisLab will do for you with a email sent to their support addresses, and for which Devot:ee has a dedicated form), I note that on the System record so I know when requests were made and fullfilled.
> 2 votes

# Answer
I currently buy the addons for my clients and manage registration numbers by using ActiveCollab (similar to basecamp) I create a notebook that has pages for reg #s as well as ftp/domain info.

I find having the client purchase things is a bit of a pain in generally. I do however send them all the information they'll need to re-install the addon if needed (original zip file + number).
> 2 votes

# Answer
We're in the same situation as you right now. We purchase all licenses for our clients and log it in our Accounting software (which happens to be Quickbooks Online). We also store the domains in the notes field when we can. We use Salesforce for our CRM and it is extremely customizable. I think after reading this I'm going to create a 'Software Licenses' data type in Salesforce with the appropriate fields so we can store this info for our clients, mail merge on it, etc.

Thanks for bringing a great point to light!
> 2 votes

# Answer
I have actually been thinking about coding an add-on that holds the licensing and technical information for all our sites and at the same time check the status of site (is it still online?).

If I ever get the time I'll probably get to work on this, but I don't see that happening any time soon.
> 2 votes

# Answer
1Password with a folder for each client.
> 2 votes

# Answer
A text file kept with the local client folder detailing modules, ftp user/pass, Sql user/pass, logins & any poignant notes. So lo-fi but very effective.
> 1 votes

---
Tags: license
---


title: Conditional meltdown

text:
# Question
Title: Conditional meltdown
I have a conditional which is the following:

```
{if '{current_time format="%H%i"}' >= '0000' AND '{current_time format="%H%i"}' <= '1300'}
    <a href="{path="speisekarten"}#mittagskarte">{navi_speisekarten}</a>
{if:else}
    <a href="{path="speisekarten"}#abendkarte">{navi_speisekarten}</a>
{/if}

```

This works well. But I need an additional function: If there is no entry in the Channel "mittagskarte" show `<a href="{path="speisekarten"}#abendkarte">{navi_speisekarten}</a>` even if it's between `0000` and `1300`

How do I write this? This melts my brain. I tried a few things mostly ending up in a parsing errors.

The conditional is not inside a Channel Tag.

Thank you

# Answer
I am not sure if i got it right but couldn't you simply wrap the conditionals in a {exp:channel:entries} tag and use the no\_results to display your link?

Perhaps not the most optimal way but it should get you what you want.

Something like this would do...

```
{exp:channel:entries channel="mittagskarte" limit="1" dynamic="no" disable="categories|category_fields|custom_fields|member_data|pagination"}
    {if '{current_time format="%H%i"}' >= '0000' AND '{current_time format="%H%i"}' <= '1300'}
        <a href="{path="speisekarten"}#mittagskarte">{navi_speisekarten}</a>
    {if:else}
        <a href="{path="speisekarten"}#abendkarte">{navi_speisekarten}</a>
    {/if}
    {if no_results}
        <a href="{path="speisekarten"}#abendkarte">{navi_speisekarten}</a>
    {/if}
{/exp:channel:entries}

```

Update: @foamcow mentions switchee, the same developer also has a plugin called IfElse which enables you to parse advanced conditionals early.
But i don't think you would need to since {if no\_results} should be the only thing parsed in the channel-loop since the time-conditional, being an advanced conditional, is parsed later.
> 11 votes

# Answer
Put your channel check outside the time check.

In pseudo-code, something like..

```
If no entry in channel mittagskarte

    show link to abendkarte

else

    if time is between 0000 and 13000
        show first link
    else
        show second link
    end time check

end channel check

```

So you'll need a channel entries tagpair in there in order to test whether there are any entries in mittagskarte

```
{exp:channel:entries channel="mittagskarte" dynamic="off" limit="1"}
    {if no_results}
        <a href="{path="speisekarten"}#abendkarte">{navi_speisekarten}</a>
    {/if}

    {if '{current_time format="%H%i"}' >= '0000' AND '{current_time format="%H%i"}' <= '1300'}
        <a href="{path="speisekarten"}#mittagskarte">{navi_speisekarten}</a>
    {if:else}
        <a href="{path="speisekarten"}#abendkarte">{navi_speisekarten}</a>
    {/if}
{/exp:channel:entries}

```

I think you could probably use a couple of add-ons here if you really wanted to. I'm sure that Croxton's Switchee, or another "advanced conditionals" add on might help and you may even find another that will let you test the entry count in a channel without the tag pair. It should be simple enough write a plugin for that if one doesn't exist.

EDIT As pointed out by Kim, the no\_results tag would be better than checking count.
> 2 votes

---
Tags: conditionals
---


title: Freeway or Router?

text:
# Question
Title: Freeway or Router?
I have been recommended to try either Freeway or Router to handle some non-standard URLs that I solved with .htaccess rewrites on EE 1 but where those no longer work on EE 2.

In one case, I need to remove a non-default template group from URLs. In another case, I need to remove part of a Page URI.

Freeway, I am told, would handle both scenarios. Would Router?

It also appears that Router uses a config file instead of storing its settings within EE. Is there any non-subjective reason to prefer one method over the other, in terms of efficiency, for example?

# Answer
I've played with both, but not used either in production. Here's how I as an end user would sumarise the differences between Freeway and Router:

## Freeway:

* Free/Open Source (GPL) (+)
* You can still access the original URL segments in your template
* Friendlier/more "EE-like" routing syntax (+)
* Stores routes in CP rather than a file - this is a biggie for me personally as something as core as routing should not IMO be in the DB (-)
* Alpha/Beta state (- 0.0.1 release)

## Router:

* Commerical license (cost $ but hopefully better support)
* You can pass variables into your target template by setting params on hte `{exp:router}` tag (+)
* You can still access the original URL segments in your template
* Can automatically set category variables based on routes. (+)
* As it's loaded at the template stage, can easily be used with Structure or other addons that modify routing (+)
* Regex-based routing syntax, which has a steep learning curve if you come from the designer-front-ender segment of the EE userbase, but once you get your head around it you can basically do anything you want.
* Stores routes in a flat file, so easy to keep versioned. (+)
* Production ready/more mature (1.0 release) (+)

In terms of preference I think it depends on the task at hand. Router is probably more mature, and is very powerful but can be tricky to grok if you're not comfortable with regex. Freeway has an easier learning curve but for me isn't production ready (and keeping routes in the DB is a killer no-no for me personally).

If you're just starting out with custom routing, Freeway has a little brother called Freebie which can be super-useful for routing "tweaks", like triggering non-routing template behaviour by passing custom segments.

*PS Doug/Isaac: If I've misrepresented any features please do edit/comment and I'll be happy to fix*
> 11 votes

# Answer
I'm a fan of Freeway (started using it when Freebie, from the same author, didn't cut it in a project). Router is rather expensive, but on the other hand Freeway is still in "beta"-ish phase...
> 3 votes

# Answer
> It also appears that Router uses a config file instead of storing its settings within EE. Is there any non-subjective reason to prefer one method over the other, in terms of efficiency, for example?

Assuming you're using a code versioning system ideally you want your config settings to be versioned so that they can easily be tracked, forked or rolled back with ease. This is especially important with core functionality such as routing. Keeping track of settings stored within the database is either convoluted or impossible, whereas a flat-file makes this stuff simple.

Having said that, and completely contradicting myself, I have used Freeway before to create a few basic single-segment URLs and it's always worked nicely.
> 2 votes

---
Tags: add-on
---


title: Expire Template at specific time

text:
# Question
Title: Expire Template at specific time
I've been asked to have a specific template, contest form, expire at 5:30pm tonite. There are no channel entries on this page so I can't set an entry to expire. Is it possible to do this with conditionals and current time? There are no concerns about time zones as the contest is very localized to one city.

Basically I need to replace the contest form with a short message and it needs to happen at a specific time which I am unable to be in front of a computer.

# Answer
> 5 votes
Maybe something like this would work?

```
{if '{current_time format="%U"}' > '1354296600'}{redirect='somewhere/else'}{/if}

```

Generate the timestamp using something like http://www.onlineconversion.com/unix\_time.htm

# Answer
> 0 votes
You should be able to do this with current\_time

```
{if "{current_time format='%Y%m%d'}" ==  "20121130"}

show this

{/if}

```

You'll just need to update the format to include the hour/minute as well.

---
Tags: conditionals, how-to, expire
---


title: Fieldtype for 2 dependant fields

text:
# Question
Title: Fieldtype for 2 dependant fields
I have two channel\_fields that can be filled, and I need one of these values to be required (but not both).

Is there fieldtype that can solve this problem?

**NB** Only one of the fields needs to be filled. I don't want to set both fields as required.

# Answer
So the short answer is, I'm not aware of an existing fieldtype that would do this at the moment.

*However* if you know a little PHP and you're willing to get your hands dirty it would be pretty easy to create something custom, depending on your validation requirements.

The full in's and out's of doing so go beyond the scope of this answer, but here's a summary of the approach I'd take:

The easiest thing would be too start with an existing compound field fieldtype (ie a fieldtype that outputs a group of fields in the CP). I'd probably start with **VZ Address** as the source is pretty readable and it's CC Share-Alike licensed.

You'd essentially just need to take the VZ Address FT and:

* Rename the ft class/file as something else to avoid collisions.
* strip out the stuff you don't need so you've just got a FT with two text fields, and set names for these for use in your template output.
* hook up a simple `validate()` method that checks that at least one of the fields is not empty.

If you're feeling fancy you could add some javascript validation for extra sugar.

*PS If you need help with this hit me up on chat or Twitter, and I'll do my best to help you out.*
> 6 votes

---
Tags: custom-fields, fields
---


# Question
Title: template_fetch_template hook $row parameter
I'm considering writing an extension that greatly depends on hooks that are available before and during template parsing. I see in the ExpressionEngine hook documentation that there is a hook called 'template\_fetch\_template' and its parameter is an array of template data called $row. I can't tell from the documentation *exactly* what data is in that array. What are the array indexes and what kind of content do they possess?

# Answer
This is array\_keys($row):

```
Array
(
    [0] => template_id
    [1] => site_id
    [2] => group_id
    [3] => template_name
    [4] => save_template_file
    [5] => template_type
    [6] => template_data
    [7] => template_notes
    [8] => edit_date
    [9] => last_author_id
    [10] => cache
    [11] => refresh
    [12] => no_auth_bounce
    [13] => enable_http_auth
    [14] => allow_php
    [15] => php_parse_location
    [16] => hits
    [17] => group_name
)

```

`template_data` is probably the most interesting one. It contains the unparsed template code. Note that you cannot change the template code directly (because $row is a copy not a reference), but you can *prepend* to the $this-\>EE-\>config-\>\_global\_vars array with a key that consists of a substring from the template code (or indeed, the entire template code could be the key). As the globals array is replaced into the template later on this gives you a mechanism for manipulating the template code before it is parsed.
> 8 votes

---
Tags: templates, extension, hook
---


# Question
Title: Viewing an audit trail of channel entry edits/revisions
I'm building a basic CRM system based on channel entries and SafeCracker forms for a client extranet. The client is asking me if it's possible to view a 'system notes/audit trail' for each entry so they can keep track of who has edited a channel entry and what they edited.

I've told them we can enable channel entry versioning, but this only lets them see the date/time and author of changes at a glance, and you have to manually re-load a version and compare it to another to see what has changed.

So my question is, is there another way to show some sort of audit trail of edits made to specific fields within ExpressionEngine? If so, how?

Using the built-in versioning is my worse case scenario, but it seems limited in how you view them at a glance. A slightly better (albeit, hacky) idea is to have a custom script that would compare entry versions between two versions, in order to list out the exact changes between them, but I'm hoping that there's a better solution out there again that someone has implemented before.

# Answer
How about this: Because you are using Safecracker, you can have each new edit be actually submitted as a new entry, with the old `entry_id` saved in a field called `original_entry_id`. Then set the status of that entry to "Old" or "Audit" or something like that.

I certainly think it's not the most efficient way to store versioning data in EE, and your control panel edit screen will end up with, potentially, a LOT of entries. On the other hand, it's pretty easy to implement, it saves ALL the entries in a way that you can easily filter and compare, and you could periodically clean out the old audit entries by the "Audit" status, or move them out to a separate table if it got to be a big issue.

Meanwhile, the site would go on showing the live entries and the client would be happy.

Only catch I can immediately see is the `url_title`; you'd also have to change the `url_title` of the "Audit" versions, perhaps to something like `url_title_entry_id`. There'd also be an issue with any tracker data, comments, or other data attached to the entries -- but categories, tags, author, stuff like that would come through perfectly.
> 3 votes

---
Tags: channel-entries
---


# Question
Title: Compatibility / Performance Gains from using MariaDB?
My hosting company is now offering MariaDB as an alternative to MySQL. Does anybody know if EE is compatible with MariaDB and if it offers any performance benefits?

https://mariadb.org/

# Answer
> 8 votes
I use MariaDB on my home development environment and I love it. MariaDB is completely compatible; it's a fork of the MySQL project by the original creator of MySQL, in fact. (He left the company when it got bought by Sun some years back.) There should be zero issues

As to performance: you will *probably* see performance gains. It's always hard to say, with databases, without knowing about your specific application usage/traffic patterns/etc. However, MariaDB has made some significant improvements to the query plan optimizer, and the table storage engines are also significantly better in some ways.

As to table storage engines: I recommend using the ARIA engine *if you've also got MariaDB running on your local dev environment*; it is a good storage engine. If you do *not* have MariaDB running on all your servers, though, use XtraDB (the InnoDB replacement); exporting ARIA tables could cause headaches on import if you're not importing them to another MariaDB installation. (This is not a problem specific to MariaDB -- it would happen on any MySQL or clone installation that doesn't have the corresponding storage engine installed.)

# Answer
> 5 votes
MariaDB (and Percona MySQL) are drop-in replacements for MySQL, so it's 100% compatible. I would definitely switch to MariaDB, it has huge performance gains. We personally use it (Percona that is, but they are essentially the same thing) on our website (which runs EECMS) and exclusively use Percona MySQL on our hosting servers.

---
Tags: database, performance
---


# Question
Title: Is it possible to create an SAEF event entry form for Solspace Calendar that doesn't use the event widget?
I'm building a site that uses Solspace's Calendar module to manage bookings for rental properties.

The booking entries are all made on a single calendar and are related to one of the property entries by means of a relationship field.

The event entries need to be made on the front end of the site by the property owners so I have an SAEF to allow them to do this.

The problem I have is that it seems one *must* use the {exp:calendar:date\_widget} tag to get the date entry fields. Unfortunately this generates a "widget" that includes a lot of stuff that simply isn't needed for this application.

I *can* do stuff with javascript to customise the widget, such as ticking the "all day" box and hiding it, but it just seems like a horrible hack when I'm used to just building what I need. I really hate the fact I'm tied to using this nasty widget.

I have tried simply using the HTML and JS that the widget generates, although there are some custom id values generated that mean I'd need to work out what they're doing in order to get the right values going into the entry. Besides that, the datepicker doesn't work.

From browsing the Solspace support forums it seems the common answer to this type of question is "you have to use the widget... it does lots of other stuff behind the scenes".

Does anyone have experience of this problem and some kind of workable, non-hacky solution?

# Answer
Just got this one working on a similar project:

**Short answer:**

You have to make sure you are submitting all of the fields that the calendar module needs and that they are named correctly

**Long answer:**

At the end of the "save\_calendar\_data" var/function (starts on line 1191) of /themes/third\_party/calendar/js/calendar\_publish.js comment out "return success", and insert "return false":

```
1316   // TODO: We could check for errors at some point...
1317        success = true;
1318   // Comment out return success, and return false instead
1319        return false;
1320        //return success;
1321    };
1322    //END save_calendar_data

```

then if you run the {exp:calendar:date\_widget} on a page with {exp:calendar:datepicker\_js} included, you can then inspect the HTML results after attempting to post an entry, and you will find the following div appended to the end of your safecracker form:

```
<div id="calendar_data">
      <input type="hidden" name="calendar_id" value="1">
      <input type="hidden" name="rule_id[0]" value="">
      <input type="hidden" name="rule_type[0]" value="+">
      <input type="hidden" name="all_day[0]" value="y">
      <input type="hidden" name="start_time[0]" value="0001">
      <input type="hidden" name="end_time[0]" value="2359">
      <input type="hidden" name="start_date[0]" value="20121111">
      <input type="hidden" name="end_date[0]" value="20121113">
      <input type="hidden" name="repeat_years[0]" value="">
      <input type="hidden" name="repeat_months[0]" value="">
      <input type="hidden" name="repeat_weeks[0]" value="">
      <input type="hidden" name="repeat_days[0]" value="">
      <input type="hidden" name="days_of_week[0]" value="">
      <input type="hidden" name="relative_dow[0]" value="">
      <input type="hidden" name="days_of_month[0]" value="">
      <input type="hidden" name="months_of_year[0]" value="">
      <input type="hidden" name="end_by[0]" value="">
      <input type="hidden" name="end_after[0]" value="">
</div>

```

Copy these hidden fields and you can use them and whatever JS/CSS without the exp:calendar JS/CSS embeds to create a more typical safecracker entry form. In the following example I use JS to update the start and end date, and hard code all the other options in the hidden fields.

```
{exp:safecracker class="safecracker" channel="event" include_jquery="no" datepicker="no" preserve_checkboxes="yes" safecracker_head="no"}
<ul class="formRows">
      <div style="display:none;">
            <div id="calendar_data">
                  <input type="hidden" name="calendar_id" value="1">
                  <input type="hidden" name="rule_id[0]" value="">
                  <input type="hidden" name="rule_type[0]" value="+">
                  <input type="hidden" name="all_day[0]" value="y">
                  <input type="hidden" name="start_time[0]" value="0001">
                  <input type="hidden" name="end_time[0]" value="2359">
                  <input type="hidden" name="repeat_years[0]" value="">
                  <input type="hidden" name="repeat_months[0]" value="">
                  <input type="hidden" name="repeat_weeks[0]" value="">
                  <input type="hidden" name="repeat_days[0]" value="">
                  <input type="hidden" name="days_of_week[0]" value="">
                  <input type="hidden" name="relative_dow[0]" value="">
                  <input type="hidden" name="days_of_month[0]" value="">
                  <input type="hidden" name="months_of_year[0]" value="">
                  <input type="hidden" name="end_by[0]" value="">
                  <input type="hidden" name="end_after[0]" value="">
            </div>
      </div>
      <li>
            <label for="title">Title</label>
            <input type="text" name="title" id="title" value="{title}">
      </li>
      <li>
            <label for="start_date">Start Date</label>
            <input type="text" name="start_date[0]" id="start_date" class="datepicker">
      </li>
      <li>
            <label for="end_date">End Date</label>
            <input type="text" name="end_date[0]" id="end_date" value="" class="datepicker">
      </li>
      <li>
            <input type="submit" name="submit" value="Submit" id="formSubmit">
      </li>
</ul>
{/exp:safecracker}

```
> 6 votes

# Answer
We added a safecracker form with an extra field as a date field, and allowed the user to submit the date in this field. The entry went in under a 'pending' status, so it allowed the admin via the admin panel later to add it via the cal widget.

Not entirely a 'non-hack', but might help the workflow if it is an option.
> 2 votes

---
Tags: add-on, solspace-calendar, saef
---


title: How to import data in EE?

text:
# Question
Title: How to import data in EE?
I have a CSV that I'd like to import into EE. Looking at `exp_channel_fields`, I think I am able to connect them to the appropriate columns in `exp_channel_data`. Basically, it seems like the value in `exp_channel_fields.field_id` is used to make `exp_channel_data.field_id_x` (where x is the `field_id` value).

But there is also this `field_ft_x` column. What is that for?

Is doing an import as simple as just putting my data in the appropriate columns in `exp_channel_data`? Is there an easier way to do this?

# Answer
Generally the best option is to use DataGrab. It can import from CSV files, as well as XML and other formats.

The `field_ft_x` column stores the field "type". This is different from the fieldtypes you are probably thinking of though. For example, a "textarea" field has the option to choose which format it's in - things like None, Auto BR, HTML. You can also install new options in the list (and probably have already) such as Markdown.
> 6 votes

# Answer
To add an entry to EE, you need to enter data in a minimum of two places: an entry in `exp_channel_titles` and a matching one (by `entry_id`) in `exp_channel_data`.

The `entry_id` field is not auto-incremented, and so you're best to enter the data in a transaction, in case the (very rare) circumstance happens where the control panel is used to add an entry just as you're importing the data. Or, you can write a big batch of queries and just start it at an `entry_id` you know isn't taken already.

There are, of course, circumstances where you have to add data more places: if it's a new author, if your data uses categories, if it uses matrix data (a common third-part add-on), if it has comments...

Each field stores its data in the `exp_channel_data` column called `field_id_##`, and the matching `field_ft_##` column is used to describe how that content should be OUTPUT later by EE. (i.e. `field_ft` is not a description of how the data is being stored, just of how it should be displayed. Data is usually stored as unformatted as possible.)

Each field has a default format, but every instance (entry) of data for any field can be set within EE to output its content in a variety of ways, so that's why that's there.

It's true, you don't need to use the third-party add-ons suggested here for simple data import needs. But the moment your data gets more complicated, they do a wonderful job of navigating that complexity and resolving data conflicts. Datagrab tends to be updated more often.
> 10 votes

# Answer
There are 2 major add-ons for importing csv files (and other filetypes) into EE:

Both work similar, each has its own quirks and extras. A lot depends on properly formatted csv files, and both map to already defined channels/custom fields.
> 3 votes

# Answer
+1 DataGrab nice & simple.
> 3 votes

# Answer
I've used datagrab lot of time and it works well! It also imports in Playa fields. I only find some problems when I need to assign category/subcategories. I've never use solspace importer but it should be more expensive than datagrab.
> 0 votes

---
Tags: channel, database
---


# Question
Title: What's the Fastest Way to Download/Upload a Site During Updating?
Every time I have to update a site, I need to download it so I can back it up and to place it in a dev environment. But a site with a lot of add-ons/themes/images/media can take *forever* to download and subsequently re-upload when updates are complete.

What's the fastest way to handle this file transfer process? I've heard of "persistent connections" like with Git, but I don't know how to implement that on my computer, if that's even the best route to take.

Also, do you download the entire site before backup, or just the critical files like templates and config?

# Answer
> 12 votes
Having used Git to manage updates and deploys of a fairly major EE-based site since around June, I have to say that from my own experience, it is by far the best method I've found for handling this process.

The need to "download and back up" is essentially removed, since git handles versioning and archiving for you, and it speeds the process up immensely for both getting the latest production version onto a local/dev machine and pushing your changes from local/dev out to production because it only transmits the files that actually changed.

A big part of what makes this all work is utilizing Focus Labs' multi-environment configuration setup, which takes a tiny bit of time to set up, but will save you a massive headache in the long run. The same goes for git; it looks intimidating but is actually pretty easy to learn and use, especially since you only need to know a few basic command line codes to operate it. If you're not comfortable with the command line, Git is a great excuse to start using it; it's what forced me to finally start using it and getting familiar with it a few years back.

My vote/recommendation in this situation is definitely in favor of Git, provided your hosting provider supports it.

# Answer
> 8 votes
Take a look at Backup Pro from Eric Lamb (mithra62). It can backup an entire file system, making your job quite easy. Otherwise using command-line in terminal (shell access) is pretty easy as well. But not as easy as Eric's module.

http://devot-ee.com/add-ons/backup-pro

# Answer
> 3 votes
You can use Updater from DevDemon make the whole process automatic.

http://www.devdemon.com/updater

Brad

# Answer
> 3 votes
I haven't learned Git yet, so still do it the old fashioned way. I go into the hosting CP and create a zip file and then download that as well as export the database. Both CPanel and Plesk have the ability to create zip files on the server for you (I've done this with both)

I also like @Webodans suggestion for backup-pro for which I wrote a review here. If you have backup pro installed you can manually run the backup in addition to scheduling it. Then just download your zip and database backup.

# Answer
> 3 votes
If you want to keep things simple and you have SSH access, there's two things you need to do:

1. Dump the database
2. Archive the files

So if you were to SSH in to your box, and change directories to where your index.php file is, you'd first want to dump the database:

mysqldump -h DBHOST -u DBUSER -p DBNAME \> data.sql

Replace the DB\* variables accordingly. Your DBHOST is typically "localhost" (sans quotes). It will prompt you for the database user's password, so enter that.

Once that finishes, archive the files:

tar cvf backup.tar * .htaccess

Then you can download it:

http://yourdomain.com/backup.tar

To extract the data:

tar xvf backup.tar

And then import the database dump:

mysql -h DBHOST -u DBUSER -p DBNAME \< data.sql

You'll be prompted for the database user's password again, so enter that.

# Answer
> 2 votes
I find that working through SSH makes uploading and downloading much easier because you can remotely zip the file, download it, re-upload, and unzip even the most bulky sites much faster.

for instance if you wanted to zip the html directory on a remote machine. once you ssh into your site cd till you can see the whole site you would like to zip. once you are there the terminal ssh command would be:

```
> ls
bootstrap-master html
> zip -r html.zip html/

```

You can then download via what ever method you are comfortable, but instead of getting an entire site of files your just getting one zip.

# Answer
> 2 votes
When I can't use git on the prod server (new client or client doesn't use git and edits files on the seerver) I use rsync to grab things. Makes life much easier.

Be very careful with the --delete flag though. Use --exclude="path/or/file/or/\*.ext" to exclude things or put a list of excludes in a text file and use --exclude-from '/path/to/exclude.txt'

```
rsync -ravc --delete --verbose --progress --stats --compress --exclude="error_log" --exclude="cache/*" user@remote.server.tld:/path/to/docroot/ /local/path/to/your/dev/docroot/

```

# Answer
> 2 votes
Use git for version control.

Use capistrano to deploy your sites ('upload'). You can also write tasks to, for example:

* Download your DB (mysqldump, gzip, download, unzip and pipe into mysql)
* Sync the uploads directory with rsync

Checkout some advice on this here: How can I use capistrano deployment with ExpressionEngine?

---
Tags: updating, ftp
---


# Question
Title: How to force a shipping error if option is not selected in Expresso-Store
My Expresso-store shipping dropdown is coded like this:

```
<strong>Please select your delivery/collection preference:</strong> <br />
<span class="bluetext">(please note we do not deliver outside the zones listed here) </span>
<br />
<select name="shipping_method">
<option value="">Select collection or delivery preference...</option>
{shipping_method_options}
</select>
{if error:shipping_method}<p class="form_error">Please select either collection or delivery.</p>{/if}

```

I would like the buyer to see, by default in the dropdown, 'Select collection or delivery preference...' If they don't change the selection to something else, I'd like for them to get an error message.

If I remove that option and just leave {shipping\_method\_options} the buyer does not need to change the dropdown, so no error message again.

What would cause an error message to actually appear for shipping methods? Is there a way I can make selection of a method mandatory?

Thank you!

# Answer
Simply add `require="shipping_method"` to your template:

```
{exp:store:checkout require="shipping_method"}
    <select name="shipping_method">
        <option value="">Select collection or delivery preference...</option>
        {shipping_method_options}
    </select>
    {if error:shipping_method}<p class="form_error">Please select either collection or delivery.</p>{/if}
{/exp:store:checkout}

```
> 3 votes

# Answer
The easiest way to achieve what you are after would be to do it with a bit of javascript. Personally I like Validate jQuery plugin. So you could do it a few ways with that.

```
<select name="shipping_method" class="required">
<option value="">Select collection or delivery preference...</option>
{shipping_method_options}
</select>

```

Which should prevent the form from being submitted if they haven't selected an option. You could also prevent the first option from being selected by the user using the disable parameter.

```
<select name="shipping_method" class="required">
<option value=""  disabled="disabled">Select collection or delivery preference...</option>
{shipping_method_options}
</select>

```

The other option would be to write your own custom rule for the validation something along the lines of (as seen here):

```
 $.validator.addMethod("valueNotEquals", function(value, element, arg){
  return arg != value;
 }, "Value must not equal arg.");

 // configure your validation
 $("form").validate({
  rules: {
   SelectName: { valueNotEquals: "" }
  },
  messages: {
   SelectName: {
    valueNotEquals: "Please select either collection or delivery."
   }
  }
 });

```
> 1 votes

---
Tags: add-on, expresso-store, ecommerce, expresso
---


# Question
Title: EE conditionals within javascript snippet
I am trying to use EE conditional statement within Javascript. The Javascript is called through a EE snippet. Part of the problem is I am using js conditionals right below my EE conditional. Is this even possible with a EE if statement? Do I need to escape my if statement some how? Any suggestions would be greatly appreciated. Here is a simplification of my snippet:

```
<script type="text/javascript">
...

{if add_option_on=="On"}
if (thisForm.os2.value == "") {
 alert('Please choose a {exp:channel:entries channel="products" disable="member_data|pagination" limit="1"}{customize_option_label}{/exp:channel:entries}');
 return false;
}
{/if}

...

</script>

```

# Answer
Try turning off javascript protection to allow the conditionals to parse: `$config['protect_javascript'] = 'n';`

Also, I would wrap the channel entries tag around the conditional like so:

```
<script type="text/javascript">
...
{exp:channel:entries channel="products" disable="member_data|pagination" limit="1"}
{if add_option_on=="On"}
if (thisForm.os2.value == "") {
 alert('Please choose a {customize_option_label}');
 return false;
}
{/if}
{/exp:channel:entries}
...

</script>

```
> 9 votes

---
Tags: conditionals, snippets, javascript
---


title: Limit Total Results with Pagination

text:
# Question
Title: Limit Total Results with Pagination
Easy question. How do I set a limit on the *total* results for a page that has pagination? I have a site that displays 16 entries per-page, but would like to limit the total results to 200. Is this possible?

# Answer
> 10 votes
Pretty easy to do using Stash.

First, make a list of the 200 entries you want to be shown in pages. This line should have no white-space or line returns in it to prevent parsing errors.

```
{exp:stash:set name="entry_ids" parse_tags="yes"}{exp:channel:entries channel="pages" limit="200" disable="categories|category_fields|custom_fields|member_data|pagination" dynamic="off"}{entry_id}|{/exp:channel:entries}{/exp:stash:set}

```

Then load the entries for each 16 entry page as normal:

```
{exp:channel:entries entry_id="{exp:stash:get name='entry_ids' backspace='1'}"
    parse="inward" paginate="bottom" limit="16" dynamic="off"}
    {title}<br/>
{/exp:channel:entries}

```

# Answer
> 1 votes
I'm not sure on how to "cap" it at 200, but you could always wrap the `{paginate}` contents with a conditional to only show to a certain point (ie. 200/16 = 12.5 pages).

```
{exp:channel:entries
    channel="name"
    disable="categories|category_fields|member_data|trackbacks"
    limit="16"
}
...
{paginate}
{if {current_page} < 13}
  {first_page}
          <li><a href="{pagination_url}" class="page-first">First Page</a></li>
  {/first_page}

  {previous_page}
          <li><a href="{pagination_url}" class="page-previous">Previous Page</a></li>
  {/previous_page}

  {next_page}
          <li><a href="{pagination_url}" class="page-next">Next Page</a></li>
  {/next_page}

  {last_page}
          <li><a href="url/P192" class="page-last">Last Page</a></li>
  {/last_page}
{/if}
{/paginate}
{/exp:channel:entries}

```

You may need to tweak the `{last_page}` hard coded url.

---
Tags: channel-entries, pagination
---


# Question
Title: Email worked on dev server, not on live server
Have just moved a site live. But no emails are coming through.

No CartThrob order confirmations. I have tried sendmail and phpmail. I have also tried both sendmail and phpmail and just sending from the CP with the 'communicate' feature.

With email debugging on the CP says everything is fine:

`Your email has been sent. Your message has been successfully sent using the following protocol: sendmail`

CartThrob on the front end throws an error at the point it wants to send an order confirmation and says to turn email debug off.

Where do I start looking? This client doesn't use email with there webhost, they use Google apps - not sure if that matters?

# Answer
> 1 votes
Just wanted to say thank you to everyone for their help and advice on this issue.

As some of you suspected, after all the trial and error the issue was hosting related.

According to the hosting provider the Parallels/Linux server hosting the site required a patch to be applied that allowed PHP Mail to communicate with with a mail server that is using IPv6 - which the Google mail servers now are. Which is why emails were going to all the trial email addresses except for this Google Apps/Gmail addresses.

Now that the patch has been applied to the server, "Admin \> Email Configuration \> Email Protocol \> PHP Mail" is working just fine.

# Answer
> 7 votes
A couple of things to check:

1. Make sure that you're not sending confirmations to and from the same address with a Google-hosted email address. It will often discard such messages automatically.
2. CartThrob just recently added a "Reply-to" field for notifications - use that for the customer's email (`{email}`), and use a different address on the same domain in the "From" field (for example, if your admin order confirmations are being sent to **orders@mywebsite.com**, set the "From" field to **noreply@mywebsite.com**). Google is getting very strict about messages sent with a "From" header that is a Google-hosted email domain but that does not go through their SMTP. Using this "Reply-to" trick seems to help.

Failing that, you may want to look at using a service like Postmark, which has an SMTP option that should work with EE (set it up in your Email Configuration preferences).

# Answer
> 2 votes
I agree with @Derek Hogue, start with making sure the send and receive email addresses are different. I'd also look at what might be different via the two servers. I've had to switch to SMTP mail for a few ISP.

If the SMTP option is available, give that a try, using the Google Apps login details.

# Answer
> 1 votes
Sending email from web servers is often fraught with problems, especially if you're on a shared IP. Many times IPs get blacklisted by spam filters and prevent emails from going. Of course, it could also just be a configuration issue on the server.

Generally, to avoid all of this mess, I create an email account for the website and set the SMTP settings in ExpressionEngine to use that account to send, thus avoiding any local mail delivery issues.

# Answer
> 1 votes
If EE is consistently failing to send emails it's worth checking whether or not you can trigger emails via direct calls to `mail()`. Add the code snippet below to a test PHP file or PHP-enabled EE template and see if you receive anything:

```
<?php

if (mail('you@yourdomain.com', 'Quick email test', 'Is this on?'))
{
    echo 'Mail sent successfully.';
}
else
{
    echo 'Mail was not sent.';
}

```

If that doesn't generate anything then try entering a secondary email address. If *that* doesn't generate anything then it's likely your server configuration is the issue. If the second test works then you know that your email provider is the culprit (maybe it's bouncing the emails back as spam).

# Answer
> 1 votes
If all of the following are true:

* emails come through fine when sent to addresses that do not use the same domain as your site
* emails are never delivered to any user@example.com (where example.com is the site domain name)
* you are not using your web host's nameservers, but are setting an MX Record for Google Apps with your domain registrar.

...then I'd recommend checking with your web host and letting them know you are not using their nameservers and for them to make sure there isn't anything that would attempt to pick up mail sent by the server to addresses at your domain (when that mail should really be routed to Google Apps).

A bit of a shot in the dark, but I seem to have encountered this issue a couple of times and it was resolved by contacting the web host.

# Answer
> 0 votes
I used to have this problem fairly consistently until I figured out the issue:

If your email is hosted *separately* from your primary web hosting, make sure you have the webhost's email service turned **OFF** for that domain. There are usually tools within their control panel or Plesk to allow you to do this.

It's solved the issue for me in nearly all cases where the email stopped working after moving to the live domain. Hope that helps.

# Answer
> 0 votes
I know I'm late to the party but I've got Gmail working with CartThrob. Do you possibly have the wrong settings configured for Gmail/GoogleApps?

This works for me:

```
$config['mail_protocol']    = 'smtp';
$config['smtp_server']      = 'ssl://smtp.gmail.com:465';    // Use :XXX to set the port number.
$config['smtp_username']    = 'username@gmail.com'; // GA - username@customdomain.com
$config['smtp_password']    = 'password';
$config['email_newline']    = "\r\n";
$config['email_crlf']       = "\r\n";

```

---
Tags: ee2, email
---


title: Getting JS Template Files on HTTPS

text:
# Question
Title: Getting JS Template Files on HTTPS
This bit of code supplied with CartThrob does some fancy stuff on the checkout page.

```
<script type="text/javascript" src="{path='store/cart.js'}"></script>

```

However, we go to HTTPS on this page and the JS doesn't get served up. We get this error:

> The page at https://domain.com.au/store/checkout ran insecure content from http://domain.com.au/store/cart.js.

The JS file has template variables and all sorts in it, so I guess they why the CT people have it a template file? Either way, can I get it with HTTPS?

Thanks.

# Answer
> 1 votes
To get around the issue I place the JS in a "Low Variables" with early parsing turned on. Which got around the HTTPs issue and also allowed the variables in the JS to grab the required EE data.

# Answer
> 5 votes
One potential solution would be to switch your site URL to a protocol relative URL, i.e. instead of your Site URL being defined as `http://mysite.com` you could change it to simply `//mysite.com`. This way, when your browser requests cart.js it will request the `https` variant if you're on a secure page and the `http` one if you're not.

If you take this approach and you're using either the `{path}` or `{stylesheet}` variables to link to your CSS then there is (naturally) a corresponding Internet Explorer bug to be aware of.

**Update**

Deeper down the rabbit hole we go... it turns out EE's currently pretty buggy with respect to protocol relative URLs. On top of that, the buggy code is replicated at least three times within EE's codebase. It's not pretty. I've posted a bug report which is replicated below:

> **Protocol relative URLs break path variables**
>
> The remove\_double\_slashes method currently converts absolute URLs like ‘//mysite.com/about’ into relative (and broken) URLs like ‘/mysite.com/about’. The attached regex tweak fixes the problem for me, but I haven’t tested it extensively.
>
> It appears that this fix needs to be applied in at least three (!?) different places, all of which replicate the same function more or less identically:
>
> * remove\_double\_slashes() in EE/libraries/Functions.php
> * reduce\_double\_slashes() in CI/system/helpers/string\_helper.php
> * \_remove\_double\_slashes in CI/system/libraries/Pagination.php

A small tweak to the regex seems to have solved the problem for me, but I haven't tested it extensively.

Find this:

```
return preg_replace("#(^|[^:])//+#", "\\1/", $str);

```

Replace it with this:

```
return preg_replace("#([^/:])/+#", "\\1/", $str);

```

# Answer
> 2 votes
It might just be an issue of making your `{path}` URIs get served via HTTPS when the page you're viewing is being accessed via HTTPS. We have some logic in our config.php that handles it; the important bit being `if($_SERVER['HTTPS'])`

```
/*************************************************************************************************************************
Paths & URLs
**************************************************************************************************************************/

$root_path = '/home/project/';
$private_path = $root_path . 'private_ee/';
$public_path = $root_path . 'public_html/';

if($_SERVER['HTTPS']){
    $public_url_component_0 = 'https';
}else{
    $public_url_component_0 = 'http';
}

if($_SERVER["SERVER_NAME"] == 'www.example.com'){
    $public_url_component_1 = $public_url_component_0 . '://www.example.com';
    $public_url_component_2 = '/';
}else{
    $public_url_component_1 = $public_url_component_0 . '://staging.example.com';
    $public_url_component_2 = '/~project/';
}

$public_url = $public_url_component_1 . $public_url_component_2;

$config['base_url'] = $public_url;
$config['site_url'] = $public_url;
$config['cp_url'] = $public_url . 'admin.php';
$config['theme_folder_path']   = $public_path . 'themes/';
$config['theme_folder_url']    = $public_url . 'themes/';
$config['third_party_path'] = $private_path . 'third_party/';
$config['tmpl_file_basepath'] = $private_path . 'templates/';
$config['snippet_file_basepath'] = $private_path . 'snippets/';

```

---
Tags: ee2, cartthrob
---


# Question
Title: 500 internal server error using Master Config
I've been using Focus Lab's Master Config for most of this year and have never run into this issue before.

So here's what's happening, going to the domain (example: mysite.com/index.php or mysite.com) brings up a 500 internal server error. Going to mysite.com/admin.php does too. The .htaccess file is blank for the time being, but will eventually contain rules for removing index.php, expires, etc.

Going to www.mysite.com/index.php, www.mysite.com or www.mysite.com/admin.php all work. Going to subpages with www in front also seems to work fine.

My config.env.php file looks a little like this: http://pastie.org/5461257

If I change the first case to include the www, I get the 500 internal server error, AND the site shows correctly, including subpages.

If I throw the following into .htaccess (www to no www redirect) and keep the first case statement in config.env.php to **include** the www, the site **works**. If I change the case statement to just be mysite.com, the site does not work.

```
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.(.+)$ [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,L]

```

Then, if I force www in .htaccess and keep www in config.env.php, the site doesn't work. If leave off www in config.env.php, the site **works**.

For now, just to get the site up and running, I've forced removal of www, left www in the config.env.php file, and added other rules to .htaccess (such as removing index.php, expires, etc.) and it's working fine.

I'm wondering if anyone has any insight as to why something like this would happen? I don't know **that** much about servers, but something tells me there's something funky with this client's host.

# Answer
In cases like these it's likely that there is something unique about how the host sets certain environment variables within PHP.

A few questions:

* Who is the host?
* Do you have access to server error logs?
* If so, what's in the error log?

If you have a 500 error you should have a log of the reason somewhere on the server. If there isn't, as your host where you can access that information. That will really help drill down to the source of the problem.
> 7 votes

# Answer
In your index.php & admin.php are you pointing your system path to the correct spot?

I keep my system above root:

```
$system_path = '../system';

```

On a related note, can you turn on debugging in your index/admin files?

Earlier this week I had the same issue until I enabled debugging and got:

```
Your system folder path does not appear to be set correctly. Please open the following file and correct this: index.php

```

Then I promptly fixed the path and it worked.
> 4 votes

---
Tags: config, htaccess, focus-lab-master-config
---


title: Category WYSIWYG

text:
# Question
Title: Category WYSIWYG
I\`m currently working with categories in ExpressionEngine and facing the problem that i missing some kind of WYSIWYG editor.

An search on Devot:ee gives me no result.

Is there an solution or an fieldtype that add an WYSIWYG editor to an category description field?

Cheers, Rein

# Answer
> 20 votes
DevDemon's Editor add-on does this. Editor on devot:ee.

# Answer
> 1 votes
There are also some hacks to shoehorn wygwam (and possibly others) into the category description field. http://ellislab.com/forums/viewthread/219408/

---
Tags: categories, wysiwyg
---


# Question
Title: How does including MIT Licensed code in an EE Addon work?
Things I'd like to admit and apologize for in advance:

* I am very new to StackExchange and have a feeling this may be too subjective, but I'm not sure.
* My understanding of the different types of software licenses is poor at best.

So here is my actual question. I am considering using a jQuery plugin in one of my commercial ExpressionEngine Addons. I know that the MIT license allows me to sell my addon, so long as I include a copy of the MIT license. Does it matter WHERE in my addon this license is kept? What would happen if down the road I needed to include another piece of code also released under the MIT license? Do I then need to include two copies of the license?

Is there a standard convention as to where these licenses should be stored within an EE addon?

I understand in advance if this needs to get closed for being off-topic, or too subjective. But figured I'd give it a shot. What are my other options? The EE forums? :)

MW

# Answer
So given the proportion of EE addons that are sold commercially I think this is a relevant question, I also don't think this is a subjective question because the MIT license is actually pretty clear. The relevant section being:

> The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

"The software" being **the MIT licensed code** rather than *your* addon. Therefore if you include multiple pieces of MIT licensed code, include a copy of the license with each of them. If it's a single file like a jQuery plugin the easiest thing is to put the license at the top of that file (where it probably already is). If it's a library that spans multiple files include the license in the location in which it is provided and reference it from your (distributed) documentation.

**NB** if you're *really* worried about this stuff do consult an actual lawyer rather than taking the word of some guy from the internet. That said, the MIT license was designed to be both easy to read and explicitly non-prohibitive to including MIT licensed code in commercial software. To be well covered I suggest you:

* Leave a full copy of the license at the top of the jQuery plugin file that you distribute with your addon.
* Also include a reference to your README file to the fact that the addon uses said plugin/libraries and that these elements are MIT licensed, and the license is included in the relevant files.

In general developers use the MIT license because of it's permissive nature (vs something like the GPL), so if you do make an error the worst that is likely to happen is that the plugin's author asks you to amend it.

There are a large number of similar questions on Stack Overflow on this topic (eg this one so that would be a good place to conduct further research if you feel the need to gain more clarity.
> 12 votes

---
Tags: add-on, add-on-development, license
---


# Question
Title: PHP error logging: force to always log errors to an error file
My ideal situation would be to always log errors to file, but only display errors to logged in Super Admins. This way I'll be able to tell if my users are triggering PHP errors even if they aren't logged in.

However, it appears as if displaying errors on screen is related to logging errors to the php error log (which I have at `/var/log/apache2/php_errors.log`).

For example, if I have `$config['debug'] = 2;` it displays errors on screen and they get recorded in the error log.

If I have `$config['debug'] = 0;`, nothing gets displayed on screen, and nothing gets recorded in the error logs, etc.

Is there a way I can always have PHP errors logged to file, while still maintaining ExpressionEngine's PHP error display preferences?

# Answer
> 8 votes
You need to find and remove some calls to the `error_reporting()` PHP function. This is set by the main index.php file in EE, and is often changed by extensions and other add-ons. You'll need to search through your whole codebase to make sure to remove all of these calls.

The main culprit is the following section of index.php. When you have `$config['debug'] = 1;` or `$config['debug'] = 2;` set, the `DEBUG` constant here will be set to `1`. If you have `$config['debug'] = 0;`, `DEBUG` will be `0`.

Old block:

```
/*
 * --------------------------------------------------------------------
 *  Set the error reporting level
 * --------------------------------------------------------------------
 */
if (DEBUG == 1)
{
    error_reporting(E_ALL);
    @ini_set('display_errors', 1);
}
else
{
    error_reporting(0);
}

```

New block:

```
/*
 * --------------------------------------------------------------------
 *  Set the error reporting level
 * --------------------------------------------------------------------
 */
error_reporting(E_ALL);
if (DEBUG == 1)
{
    @ini_set('display_errors', 1);
}
else
{
    @ini_set('display_errors', 0);
}

```

This new block ensures that `error_reporting()` is always on, but disables showing the errors if the user does not match the requirement set by your `$config['debug']` value.

You may want to search your installed add-ons for `ini_set()` calls that override the `error_log` and more importantly `display_errors` values, since this would cause the errors to not be logged properly and/or to be shown even when the user is not an admin.

---
Tags: php, debugging
---


# Question
Title: Add-on Development: Variable pairs with parameters
I can't seem to find any documentation or examples of how to give variable pairs parameters in EE add-ons. I have a module working like a charm. Inside the main module tagpair there's a variable pairs like this:

```
{exp:mod:method}

    <h1>{top_level_var}</h1>
    {var_pair}
        <p>{var_pair_variable}</p>
    {/var_pair}

{/exp:mod:method}

```

Boom, that's awesome. But sometimes I want to limit the output of the {var\_pair} tag via params like this:

```
{exp:mod:method}

    <h1>{top_level_var}</h1>
    {var_pair limit="7" number="42"}
        <p>{var_pair_variable}</p>
    {/var_pair}

{/exp:mod:method}

```

What's the best way to accomplish this? Does EE natively support such params?

# Answer
This is not natively supported in ExpressionEngine. The "official" was to do something similar to this would be to simply use additional module tags. Is there a reason you would not want to do that?

```
{exp:mod:method}

    <h1>{top_level_var}</h1>
    {exp:mod:var_pair limit="7" number="42"}
        <p>{var_pair_variable}</p>
    {/exp:mod:var_pair}

{/exp:mod:method}

```

You can use the session cache trick to keep track of shared values between the two module tags when doing this. Place this in your module's constructor:

```
$this->EE = &get_instance();
if(!isset($this->EE->session->cache[__CLASS__]))
{
    $this->EE->session->cache[__CLASS__] = array();
}
$this->cache = &$this->EE->session->cache[__CLASS__];

```

You can then use **$this-\>cache** as an array anywhere in your tags to keep track of shared data, such as the recordset initially loaded by the outer {exp:mod:method} module tag.
> 12 votes

# Answer
You can also take a look in the EE source code or a module like Playa to see how they are doing it...

Apart from having a separate adding a tag to your module, you can manually search and parse those tags yourself. If you check the sourcecode for the channel module, you can find the following snippet of code used for the categories tag:

```
if (strpos($this->EE->TMPL->tagdata, LD.'/categories'.RD) !== FALSE)
{
  if (preg_match_all("/".LD."categories(.*?)".RD."(.*?)".LD.'\/'.'categories'.RD."/s", $this->EE->TMPL->tagdata, $matches))
  {
    for ($j = 0; $j < count($matches[0]); $j++)
    {
      $cat_chunk[] = array($matches[2][$j], $this->EE->functions->assign_parameters($matches[1][$j]), $matches[0][$j]);
    }
  }
}

```

Instead of assigning the result to `$cat_chunk` you can do you own parsing and replacement of that tag.

This does however add a lot of extra code because you wouldn't be able to use the `$this->EE->TMPL->parse_variables` method anymore since you will have to parse everything manually (not just the var\_pairs).

Something like this:

```
//  Parse single variables
foreach ($this->EE->TMPL->var_single as $key => $val)
{
  $value = isset($data[$key]) ? isset($data[$key]) : '';
  $tagdata = $this->EE->TMPL->swap_var_single($key, $data[$key], $tagdata);
}

//  Parse variable pairs
foreach ($this->EE->TMPL->var_pairs as $key => $val)
{
  //  parse categories
  if (strpos($key, 'your_var_pair') !== FALSE)
  {
    // do something with the tag pair
  }
}

```

In this case the `$val` variable should hold your custom parameters.

That being said... the question you should be asking: "Is it all worth the trouble?". Will people (or you) ever use those parameters, because it does add a lot of overhead in the code. There are other tags you will need to parse manually like `{switch=''}`, `{count}` and `{total_results}`.

My answer got a bit longer than I intended, but it **IS** a complex matter.

– Wouter
> 1 votes

---
Tags: add-on, module, parameters
---


# Question
Title: Is it possible to output exp:channel:category_archive listings to match the Low Reorder order of the entries?
Before I start adding multiple Channel Entries tags to a template, and getting my hands dirty with custom SQL, I wanted to see if this was possible. I'm using exp:channel:category\_archive in the sidebar of a page and would love the output to respect the Low Reorder order on the list of entries it outputs.

Category Sorted Entries doesn't seem to support this yet http://rog.ee/category\_sorted\_entries and according to LR support this doesn't seem possible https://getsatisfaction.com/low/topics/category\_archives\_wont\_reorder

Has anyone solved this?

# Answer
> 3 votes
It looks like you've answered your own question—and the answer is no, not without custom SQL / PHP.

According to EE documentation for the exp:channel:category\_archive tag there is no attribute to sort the *returned entries*—you're only able to sort the categories. And, as you state in your question, official support for Low Reorder add-on (and now, Low's comment to your question) indicates that sorting is not possible without custom scripting. So unless you want to rephrase your question to ask for the custom SQL / PHP to accomplish your sorted category archive, the answer is, simply, "No."

*That said*, I believe that this would accomplish the same function, utilizing the {exp:channel:categories} tag:

```
{exp:channel:categories}
    <h1>Category: {category_name}</h1>
    <ul>
    {exp:channel:entries category='{category_id}' orderby='low_reorder_field'}
        <li>{title}</li>
    {/exp:channel:entries}
    </ul>
{/exp:channel:categories}

```

I would guess that this method would be much less efficient than utilizing the {exp:channel:category\_archive} tag (and it runs contrary to your stated desire to avoid adding multiple channel entries tags), but technically it would accomplish what you're after.

And, at the risk of making this sound like *every single other answer on this site*, I suppose you could also get creative with Stash to accomplish this more efficiently without getting your hands dirty with custom SQL / PHP.

---
Tags: categories, category-archive, low-reorder
---


# Question
Title: Plugin help; Cannot redeclare fatal error
I'm writing my first plugin in attempt to learn more about the backend of EE and Codeigniter. My PHP is enough to get by, but I'm no expert.

This plugin is as follows:

```
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

$plugin_info = array(
    'pi_name'       => 'YouTube ID from URL',
    'pi_version'        => '0.1',
    'pi_author'     => 'Dan Grebb',
    'pi_author_url'     => 'http://dgrebb.com/',
    'pi_description'    => 'Returns a YouTube ID from a variety of youtube share link types.'
);

class Youtube_id_from_url {

    public $return_data = "";

    public function __construct($urltag = NULL)
    {
        $this->EE =& get_instance();

        if (empty($urltag))
        {
            $urltag = $this->EE->TMPL->tagdata;
        }

        function sliceurl($url) {
            $pattern =
                '%^# Match any youtube URL
                (?:https?://)?  # Optional scheme. Either http or https
                (?:www\.)?      # Optional www subdomain
                (?:             # Group host alternatives
                  youtu\.be/    # Either youtu.be,
                | youtube\.com  # or youtube.com
                  (?:           # Group path alternatives
                    /embed/     # Either /embed/
                  | /v/         # or /v/
                  | /watch\?v=  # or /watch\?v=
                  )             # End path alternatives.
                )               # End host alternatives.
                ([\w-]{10,12})  # Allow 10-12 for 11 char youtube id.
                $%x'
                ;
            $result = preg_match($pattern, $url, $matches);
            if (false !== $result) {
                return $matches[1];
            }
            return false;
        }

        $youtubeid = sliceurl($urltag);

        $this->return_data = $youtubeid;
    }
}

/* End of file pi.plugin_name.php */
/* Location: ./system/expressionengine/third_party/plugin_name/pi.plugin_name.php */

```

Then I have this template code

```
{exp:stash:set name="video-gallery"}
    {exp:query sql="SELECT cat_id FROM exp_categories WHERE cat_url_title = '{segment_2}'"}
        {exp:channel:entries
            channel="videos"
            disable="category_fields|member_data|pagination|trackbacks"
            dynamic="no"
            category="{cat_id}"
        }
            <div class = "video_El even {switch='|last'}">
                {exp:youtube_id_from_url}{video-url}{/exp:youtube_id_from_url}
                <h3>{title}</h3>
            </div>
        {/exp:channel:entries}
    {/exp:query}
{/exp:stash:set}

```

The error message is as follows:

```
Fatal error: Cannot redeclare sliceurl() (previously declared in /local.dev/system/expressionengine/third_party/youtube_id_from_url/pi.youtube_id_from_url.php:24) in /local.dev/system/expressionengine/third_party/youtube_id_from_url/pi.youtube_id_from_url.php on line 24

```

I really appreciate any help I can get. Thanks to all for such a great community!

# Answer
> 8 votes
You shouldn't be declaring functions inside your `__construct()` method.

Move `sliceurl` a bit further down, and call it using `$this->sliceurl` (since it's part of your class):

```
class Youtube_id_from_url {

    public $return_data = "";

    public function __construct($urltag = NULL)
    {
        $this->EE =& get_instance();

        if (empty($urltag))
        {
            $urltag = $this->EE->TMPL->tagdata;
        }

        $youtubeid = $this->sliceurl($urltag);

        $this->return_data = $youtubeid;
    }

    function sliceurl($url) {
        // etc
    }
}

```

# Answer
> 2 votes
**Update:**

Ah, heh. Yes. What @AdrianMacneil says above. Didn't see the forest for the trees on that one.

---

I've tested your plugin locally, and the only error I'm seeing is on line 43, where you're only testing for the preg\_replace to return false on error, where you should also be looking for it to return "0" for no matches:

```
if ( $return !== FALSE && $return !== 0 ) {
    return $matches[1];
}
return FALSE;

```

However, based upon your comment above, it doesn't look like the actual plugin file is the problem. I'd recommend that when you test add-ons that you're developing, that you make the test as simple as possible (as opposed to testing it while it's wrapped within 3 other tags).

Regarding the error you're seeing (the redeclaration of the sliceurl() function)—are you using another plugin that also declares this function? To get around this for the present, you could wrap the sliceurl() declaration like this:

```
if ( ! function_exists('sliceurl') ) {
    function sliceurl($url) {
         ...
    }
}

```

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


# Question
Title: Removing index.php with the official method when running old-style multiple sites?
I am currently using a non-official .htaccess rewrite to deal with index.php and a few other bits and pieces. Since it looks like I am going to try and take care of the other bits and pieces with Router, I want to get the .htaccess back to something closer to the official setup to make future support easier.

However, I don't think the straight-up official version will do since I have one index.php in my main directory and additional index.php files in five subdirectories. Basically, I am running multiple sites with the old method, but they're neither domains or subdomains, just folders. So I need those index.php files removed as well and if possible I would prefer to do it from a single .htaccess file instead of adding a new one in each subdirectory.

This is what I use right now (with "GoT" being one of the subdirectories with its own index.php):

```
RewriteRule ^/?((ASoIaF|Digest|Images|Login|Store|Updates|member)(/.*)?)$ /index.php/$1 [NC,L]
RewriteRule ^/?GoT/((Characters|Episodes|Features|Gallery|News)(/.*)?)$ /GoT/index.php/$1 [NC,L]

```

Can that be brought closer in line with the official method while still using a single .htaccess? Or is that just making things unnecessarily complicated?

# Answer
> 1 votes
Some important points to keep in mind.

Ellislab doesn't support server configurations (rewrites in the case.) They don't have the expertise for this. While they do have a preferred rewrite scheme that they will support, the more your situation deviates from that simple scenario, the less likely they will be able to support you.

With the introduction of the Multi Site Manager, this is the supported method for running multiple sites. If you aren't using MSM, then you may need to pick that up for your setup to be supported by Ellislab.

Rewrites can be tricky and there are many ways to do them. If your rewrite scheme is working, then you are doing it right. I would also suggest that you stick with one .htaccess file per site as you are currently doing. This will reduce the likelihood (less complex.)

This question is also good for https://serverfault.com/ as Apache rewrites aren't CMS specific.

---
Tags: htaccess
---


# Question
Title: How can I use capistrano deployment with ExpressionEngine?
Any good resources/advice on using Capistrano to deploy EE sites?

# Answer
> 9 votes
I've previously used Capistrano to deploy EE sites, though I've recently moved to using the web based DeployHQ as it doesn't require SSH access or for Git to be installed on the server, while still allowing rollbacks (based on SHAs/commits).

That said, here is a Gist of the last version of my cap recipe for deploying E via Git+SSH. This was based an amalgam the HiveLogic post linked in @Janvi's answer as well as This ShapeShed post and some bits from This GitHub repo too, all updated for EE2.

As such it also has a bunch of extra tasks for doing things like getting a SQL dump from the remote server, and importing it locally which you may or may not want. Feel free to make use of it if you can, but as I'm no longer using it I can't really help support it.

**Link to Gist of Capistrano Recipe**

*NB This recipe assumes that you are bootstrapping your config and making full use of config vars to move all paths (inc uploads) out of the DB. I have an extended version somewhere which runs the SQL dump through a migration script to fix any missed paths and empty tables that aren't needed across imports, such as `exp_sessions` etc*

**EDIT:** There's also this article on deploying EE 2 with Capistrano

# Answer
> 5 votes
FWIW, I wrote a blog post (and made a video) on the topic relatively recently. The resources already mentioned are really great, but perhaps my write-up will help too.

http://matthewfordham.com/blog/deploying-expressionengine

# Answer
> 1 votes
A quick google search lead me to this:

**DEPLOYING EXPRESSIONENGINE FROM GITHUB WITH CAPISTRANO** http://hivelogic.com/articles/deploying-expressionengine-github-capistrano

Seems like this should cover most of it.

---
Tags: deployment
---


# Question
Title: How to export/import channel entries between EE sites
Are there any add-ons (or tricks) that allow the exporting/importing of channel entries between EE installs? I know there are a couple options for exporting/importing channel settings and fields, but what about the data?

Maybe using a pair of add-on to export/import XML/JSON is the best choice? Any success here?

# Answer
> 10 votes
The way I generally go about it is to create one RSS template per channel exporting the entries I want with all their custom fields (remember to specify a hight limit parameter if you have more than 100 entries). I then use DataGrab and point to that template to import these entries into my new site.

You might have small MySQL tasks to perform after that, like mapping the old upload locations to the new ones, etc but the import process is quite smooth.

# Answer
> 4 votes
I recently had the task of bringing over a thousand or so entries into a complete redesign. It was a lot of writing custom queries for MySQL, exporting them out as either CSV or XML (we needed to keep some HTML in entries with a WYSIWYG field type), then using Datagrab to import everything into the new site

# Answer
> 2 votes
I recently used Solspace's Importer add-on as part of my upgrade from EE 1 to EE 2 in order to bring over my EE 1 Galleries. For the exporting, I setup a template formatted to output each entry as a csv entry.

It took a good deal of trial and error to make sure all the elements were being both exported and imported correctly, but its definitely a viable approach. This included handling Tags, though I don't believe the Importer handles any data stored outside of EE's standard tables.

---
Tags: import, export
---


# Question
Title: Need help cutting back on embeds when using Tags from Solspace
I have a channel listing characters in a TV show. On the index page of that channel, I display a visual index to all characters. The index looks like this and it uses Solspace's Tags module to pick out the image for each character:

```
<ul>
{exp:channel:entries channel="{current_channel}" limit="500" orderby="title" sort="asc" disable="member_data|pagination"}
<li>
<div class="CharIndexItem">
<div class="CharIndexImage">
{embed="Characters/Snippet_Image_index_GoT" character="{title}" byname="{{current_channel_id}_byname}" actor="{{current_channel_id}_actor_name}"}
</div>
<div class="CharIndexText"><a href="{comment_url_title_auto_path}">{title}</a></div>
</div>
</li>
{/exp:channel:entries}
</ul>

```

And the embed like this:

```
{exp:tag:entries channel="channel42" limit="1" tag="{embed:character} Index"}
<a href="{comment_entry_id_auto_path}"><img src="{42_image:small}" border="0" title="{embed:character}{if embed:byname != ""}, {embed:byname}{/if}{if embed:actor != ""}, played by {embed:actor}{/if}" /></a>
{/exp:tag:entries}

```

Now, since the show has a lot of characters, that index ends up with a lot of embeds. Right now it isn't a problem, but the site gets hit with very heavy traffic when the show is on air, so I am thinking it may cause an issue then. Is there any way to cut back on these embeds? I do need to stay with Tags as the method of marking the images that get used for each character, it is the only workflow that really makes sense.

# Answer
If performance is only a problem when the site gets hit by a lot of traffic, you might want to turn on caching for that particular tag (I'm not really a fan of full page caching). That is what it is meant for...

```
{exp:channel:entries cache='yes' refresh='60' ...}

```

Might I ask why you have at all? You shouldn't need it since you are not nesting the same tags... if it is because you use this snippet in multiple places, might I suggest using a snippet?

– Wouter
> 7 votes

# Answer
There's also a few other, more effective ways to cache code chunks like that such as CE Cache or Template Morsels.
> 1 votes

# Answer
The easiest thing to do in this case I would recommend simply turning on caching for the embed templates. You will need to specify how long cached versions of the embeds should be saved.

You could also make sure on my CacheCracker add-on to help manage and expire the cached template's data automatically when publishing new entries in the associated channels.
> 1 votes

---
Tags: add-on, embeds, solspace-tag
---


# Question
Title: Does preload_replace not work in stash:embed templates?
This is a fairly straight forward question... Does preload\_replace not work in stash:embed templates? In my embed templates, I tend to set a bunch of preload replace variables for things like channel name and custom field prefix so that if i ever have to change something, one change in the first couple of lines runs through the template and replaces al such instances. But when i try that in a stash:embed template, the preload replace items just render as plain text in the template. Is there a way to get them to work, or is this simply an unavoidable parse order issue?

# Answer
> 7 votes
Stash doesn't parse preload\_replace. But they will work if you use process="start" with the stash embed, since that effectively includes the sub template code in the host template prior to preload\_replace being parsed by EE. However, be aware that if you need to access stash vars captured in the host template then you need to use process="end" (the default) due to parse order; also process="start" templates cannot be pre-rendered (parse\_stage="set") since the EE parser is not initialised at the point the template is included.

This is off-topic but addresses your comment about performance above:

By default a Stash embed works in a similar way to an EE template, and you will not see a performance gain if you are just including one or two templates in a host template. If you nest your stash templates or use them multiple times then you will notice a gain. And if you 'tune' your embeds - by which I mean choose to pre-render and cache parts or the whole of your template and experiment with parse\_depth, parse\_vars etc - then you will see significant gains. You should also disable file sync ('stash\_file\_sync'=false) on your production environment.

The other significant advantage of a stash embed is that you can have multiple cached instances of the *same* template. That is possible because you can specify a file name separately from the variable name for the embed. This can be helpful for caching things like submenus which might share the same generation code but have different output for the various sections of your site.

---
Tags: add-on, stash, parse-order, preload-replace
---


# Question
Title: What do you put in your .gitignore for ExpressionEngine sites?
I'd like to keep my git repo as clean as possible without cache files and content image files. Also I'd like to preserve the ExpressionEngine images directory structure. What are you gitignore directives to achieve this?

# Answer
If you want the directories to still get created, you need to have something in them, so I make sure there is an index.html file in each of the EE image directories that says "Directory Access not allowed" (or similar). Then, for each of the directories you can add rules like the following (your paths may vary):

```
/assets/images/captchas/*
!/assets/images/captchas/index.html

/assets/images/member_photos/*
!/assets/images/member_photos/index.html

# and so on...

```

That will ignore all the items in those directories except the index.html, so when you clone the site, at least the directory structure will be preserved, but none of the images will come with.
> 18 votes

# Answer
The github/gitignore repo is usually a good starting place for gitignore defaults, and I think it is in this case as well:

```
.DS_Store

# Images
images/avatars/
images/captchas/
images/smileys/
images/member_photos/
images/signature_attachments/
images/pm_attachments/

# Caches
sized/
thumbs/
_thumbs/
*/expressionengine/cache/*

```
> 5 votes

# Answer
```
*.DS_Store
.gitignore
.htaccess
.ftpquota

/expressionengine/cache/*
/assets/cache/*
/uploads/avatars/*
/uploads/member_photos/*
/uploads/pm_attachments/*
/uploads/signature_attachments/*

```

The path to some of your folders will obviously be different.
> 4 votes

# Answer
Your paths may vary:

```
# Global Files
!.gitignore
.htaccess
.sass-cache
# .svn
.DS_Store
config.local.php
config.dev.php
[Tt]humbs.db

# Images
src/www/public_html/assets/ee_images/*
# src/www/public_html/assets/ee_images/avatars/
# src/www/public_html/assets/ee_images/captchas/
# src/www/public_html/assets/ee_images/smileys/
# src/www/public_html/assets/ee_images/member_photos/
# src/www/public_html/assets/ee_images/signature_attachments/
# src/www/public_html/assets/ee_images/pm_attachments/

# UGC
src/www/public_html/assets/uploads/*

# Caches
sized/
thumbs/
_thumbs/
cache/

```
> 3 votes

# Answer
Lately I have been using this as the default gitignore for non-EE projects and I was thinking of adapting it for EE. i'm open for suggestions.

```
#ignore everything apart from php, css, xml, htaccess, sql, js
*
!*/
!*.php
!*.css
!*.xml
!*.htaccess
!*.sql
!*.js
!*.shtml

```
> 2 votes

---
Tags: git, repo, .gitignore
---


# Question
Title: Authenticate is returning to a different page than the return param
I have two forms on a page, the first one is generated by exp:autheticate, and the second is a normal handwritten form. Both are triggered by javascript submits. The authenticate form seems to be sending me to the action of the second form on success, rather than the return param.

```
    <div class="panel front">
    {exp:authenticate:login_form
        auth_type="email"
        username_field="email"
        secure_return="yes"
        class="cf"
        id="login-form"
        return="/welcome"}
          <input type="text" name="email" value="" placeholder="Email" id="email" class="i2"/>
          <input type="password" name="password" value="" placeholder="Password" id="password" class="i2"/>
          <a href="#" id="login-submit" data-submit="login-form">></a>
          <div class="divider"></div>
          <a href="#" id="login-join" data-toggle="Join">></a>
      {/exp:authenticate:login_form}
    </div>

    <div class="panel back">
      <form action="https://whatever.com/apply" accept-charset="utf-8" method="post" class="cf" id="apply-quick-form" name="">
          <input type="text" name="newemail" value="" placeholder="Email" id="newemail" class="i2"/>
          <div class="invite-code" data-script="InviteCode" class="i2">
            <a href="#/invite">Have an invite code?</a>
            <input type="text" name="invcode" value="" placeholder="Invite code (optional)" id="invcode" class="i2"/>
          </div>
          <a href="#" id="login-submit" data-toggle="Login">></a>
          <div class="divider"></div>
          <a href="#" id="login-join" data-submit="apply-quick-form">></a>
      </form>
    </div>

```

EDIT: Seems it was an interaction with twomile\_login\_redirect that was the issue. That plugin tracks a previous requested URL in a session variable, and forces you to redirect to THAT url once logged in. I haven't solved the problem yet, but have tracked it down to that interaction.

# Answer
> 4 votes
Since you fixed the redirect issue, I thought I would tell you how I handle the redirect stuff.

On restricted templates I will add the following tag. The tag will vary based on the size of the page URL. I like this approach because it avoid Cookies and local session vars, which are restricted in some parts of the world.

```
{if logged_out}{redirect="/login/return/{segment_1}/{segment_2}/{segment_3}"}{/if}

```

Then you would make your Authenticate tag like so:

```
{exp:authenticate:login_form return_var="return"}

```

This will tell Authenticate to return to the URI after the "return" segment. There are a number of other ways to this, but I have been able to use some technique pretty much across the board with much success. Definitely not the only way to solve the problem though, nor the solution for everyone.

---
Tags: forms, authenticate
---