How do I query for entries, based on a value inside a table? I'm trying to query up some entries based on a value inside an editable table.

Here's two pictures on how it's set up:
http://i.imgur.com/lJFcO1C.png
http://i.imgur.com/Eqxg7Uh.png

My current template (stripped) looks like this:

{% set courses = craft.entries({
    section: 'course',
    search: 'participants:31'
}) %}

        Upcomming courses

    {% for course in courses %}
        {{course.title}}

    {% endfor %}

I've tried a couple of other parameters to the query, such as

participants['col4']: '31'

and

participants: '["col4"]:31'

but almost no dice. I get a result, but it matches with all the other values as well. I only want it to match with "userID" column, aka col4.

For example, I get the same results if I try '1' instead of '31'.

Craft saves all the table's data serialized to a single cell in the database, so there's not really a good way to set query conditions to match something in a table field.

What you could do is to use Andre Elvan's brand new plugin Preparse Field. With that you would add a new field to you entry type that does some predefined Twig logic on every entry save. So you could get that table cell's data you are interested in and write it to its own field that you could then use as a field parameter in your criteria model.

Another way, and this is the approach I would actually recommend, is to refactor the whole setup and use a separate channel to hold each table row as its own entry (without URL) and than have an Entries field to relate those to your week / event entry.

The third solution is a variant of the second one, but to use a Matrix field (or a SuperTable) instead of a separate channel. You would need to set up the query with Yi query builder from a custom little plugin. Let me know if you're interested in this solution and I can assist you in setting this up.


How can I set a persistent template variable to use across multiple pages in one site visit? I'm working on a site where the site background is chosen randomly from among the entries in an "artwork" channel. I'm using the following code in my _layout.html template to get the url for the chosen image:

{# choose a random entry for the site background #}
{% set randomArtwork = craft.entries.section('artwork').order('RAND()').first() %}

{# set the url for the background image #}
{% set backgroundImageUrl = randomArtwork.artImageBkg.first().url %}

The chosen image is then displayed by adding an inline style to the body tag like this:

<body{% if backgroundImage is defined %} style="background-image: url({{ backgroundImageUrl }});"{% endif %}>

Right now, this code runs on every page request and a different image is displayed on every page load on the site.

However, I'd like to be able to run this code only once per user, per site visit so that the background image will change on repeat visits to the site, but on a single visit, the user will see one persistent image.

How can I go about doing this in Craft?

As an alternative, I also thought to use Craft's {% cache %} tags to set my template variables on a timed basis so that visitors in a particular hour would only see one persistent image, but I couldn't figure out how to get this to work.

When I tried to use the {% cache %} tags on individual templates, I got a warning that a template that extends another (in this case, my _layout.html template) can't have a body.

And adding the {% cache %} tags to my _layout.html template wasn't affecting the persistence of the background image.

Any ideas?

Sounds like you need a good cookie solution to keep track of which background has been chosen for each visitor.

I'd recommend using the LJ Cookies plugin to easily set & retrieve the filename of the background image.

(I don't believe the cache tag will be useful to you in this case.)


Entry validation not working when Publish live changes permission is not checked when a user with no permission to publish is submitting a blank entry, the entry is saved anyway without any errors.

Here is the permissions set to the user group:

I have few required field as showed below:

And very sadly, the entry is saved as draft, entitled "New Entry":

This can't be a feature, is it?

As carlcs said, this is already working as expected. Craft only enforces content validation rules for enabled entries (not including drafts), and most people prefer that behavior.

If you want to change that behavior, you can write a plugin that provides its own entry validation logic, by latching onto the entries.onBeforeSaveEntry event. Just put this in your plugin’s primary class:

public function init()
{
    craft()->on('entries.beforeSaveEntry', function(Event, $event) {
        /** @var EntryModel $entry */
        $entry = $event->params['entry'];

        // If the entry is disabled, the content won't be validated automatically
        if (!$entry->enabled)
        {
            $validates = craft()->content->validateContent($entry);

            if (!$validates)
            {
                // Add the content validation errors
                $entry->addErrors($entry->getContent()->getErrors());

                // Prevent the entry from getting saved
                $event->performAction = false;
            }
        }
    });
}


Can't include relative JS file from layout I'm trying to include the videojs.thumbnails.js file in my layout.html:

<script src="./videojs.thumbnails.js"></script>

It's located at the same level.

I am getting the following error: http://localhost:3000/videojs.thumbnails.js 404 (Not Found)

Any ideas what I am missing?

It looks like this is all happening in Craft's template folder, where anything with an underscore—like your _layout directory and its contents—won't be accessible via URL.

You'll definitely want to adjust your project layout to keep Craft's templates together in /craft/templates, and any front-end resources (like your videojs.thumbnails.js, thumbnails.png, etc.) in the /public folder.

The Routing documentation fully explains what Craft does with any front-end URL it gets—it's a tad intense but should fully explain what happens with a request.


How do I publish entries with a specific category id? How do I publish a list of three most recent entries within a 'blog' section that feature the category id '42'?

I presently have this code:

{% for entry in craft.entries.section('blog').limit(3).find() %}

        {{ entry.title }}

{% endfor %}

However, I am having trouble properly implementing the .relatedTo() filter within this snippet, and all of the examples that I have read reference a category title rather than id.

You can pass in a CategoryModel to the relatedTo parameter, so its just a matter of getting the CategoryModel you're after. Something like:

{% set category = craft.categories.id(42).first %}
{% set entries = craft.entries.section('blog').limit(3).relatedTo(category) %}


Translate filter and nested vocabulary properties Is it possible to use the translate filter in order to get nested vocabulary entries? For example having a vocabulary file like this:

<?php

return [
    'login'             => 'Einloggen',
    'registration'      => 'Anmeldung',
    'forms'             => [
      'email'                => 'Email',
      'password'             => 'Passwort',
    ]
];

I would like to get the vocabulary properties in the template in the following way:

<p>{{ 'forms.email' | t }}</p>

Thanks

Not currently.  Might be worth a feature request, though?


Display notification if no entries exist for status criteria and logged in user I'm aiming to display disabled entries for a logged in user and a message if no entries with this criteria exist. I've tried two different ways without success.

Version 1 gets all entries - live and disabled, gets those by the logged in user, and then tests for the entry status of disabled (which doesn't work).

{% set entries = craft.entries
    .section('profileEntry')
    .status(null)
    .all() %}

     {% for entry in entries %}

        {% if currentUser.id == entry.author.id %}

            {% if entry.status == entry.status('disabled') %}

{{ entry.title }}

                {% else %}

No entries exist

            {% endif %}

        {% endif %}

    {% endfor %}

Version 2 only gets the disabled status entries, then the entries by the logged in user. Which doesn't work either.

{% set entries = craft.entries
    .section('profileEntry')
    .status('disabled')
    .all() %}

{% for entry in entries %}

        {% if currentUser.id == entry.author.id %}

{{ entry.title }}

        {% else %}

No entries exist

        {% endif %}

{% endfor %}

Why don't you just grab disabled entries from the author?

{% set entries = craft.entries
    .section('profileEntry')
    .status('disabled')
    .authorId(currentUser.id)
    .all() %}

Then you can loop those

{% for entry in entries %}
    {{ entry.title }}
{% else %}
    no entries found
{% endfor %}


Calling Sub Channel Entries How would you go about pulling a selected entry from one channel into another entry using Craft variables?

For example, I have a page with an author channel field that allows a user to select the author from entries in an author channel. Once selected, I am wanting the page to display the author content from the selected Author entry.

I have tried using the following but have gotten no output.

{% if entry.authorTeamMember|length %}
    {% set myEntry = entry.authorTeamMember.first() %}

    {{entry.authorName}}
    {{entry.authorDescription}}
{% else %}

No Author

{% endif %}

You're close!

You select the author correctly with and assign it to the myEntry variable:

{% set myEntry = entry.authorTeamMember.first() %}

Now you just need to output the data from myEntry instead of entry.  i.e.

{% if entry.authorTeamMember|length %}
    {% set myEntry = entry.authorTeamMember.first() %}

    {{ myEntry.authorName }}
    {{ myEntry.authorDescription }}
{% else %}

No Author

{% endif %}


Craft 3 best way/steps to create a login client area in frontend I have to make a website that needs an user area with login.

In that area users should be able to upload to admin area or download files from admin area.

Each user has its own account that is separate from other users.

I used to work with cake framework but in the several past weeks i made a few projects in craft cms 3 and liked it due to the easy and fast time to go up and running a full stack website.

Is it possible to make the users area in the frontoffice of craft cms 3?

If it is, there is a plugin available to do it (i searched and didn't find one), or can somebody point me the steps that are needed to do it?

Many thanks.

I don't know any plugins that do that for you since it's integrated in Craft by default. There are Registration forms as well as Login form examples and you can create Entry forms as well.

For gating content behind logins there is the requireLogin tag which will automatically redirect you to your login route and after a successful login return to the url you wanted to visit.
Not sure what else you might need since your question is really broad.

After a registration Craft will certain system messages (utilities -> systemmessages) with activation links for their account (double-opt-in). In case a user lost/forgot his/her password you can send them a new one automatically.

You can check certain config values such as loginPath or postLoginRedirects as well.


Database documentation / tips / resources Hope this question isn't too vague.

I was wondering if there was any documentation or guidance on the database(s) underpinning Craft?

I am going to be working on a website with a fair amount of data and, crucially, the need to pull quite a lot of pieces of data frequently.

You can see a version of it here: http://unlockinglovelocks.co.uk

At the moment, using the dropdowns, you can navigate to a large picture which is mapped, so that clicking on each padlock will bring up its details. Eventually, my friend who requested the site expects to catalog a large number of these (potentially several large images, each featuring dozens of locks, related to just one site --- multiple sites per area --- multiple areas)

Am looking for a setup that won't end up being slow or inefficient. Basically want to understand a bit more about how the data storage with Craft works, so I can try and do it right :p

Any recommended resources would be welcome - I have had a google, and a browse of the Craft docs, without much luck.

It's difficult to answer this without specifics on what you're looking for and what your plugin is trying to do, but I'd recommend following the plugin development docs, which includes working with databases.

I'd also recommend using somethign like https://pluginfactory.io to generate the plugin boilerplate code for the plugin components you might need.


Editing User Email Address I created a user group that has full permissions for User options in the CP, i.e. all the boxed ticked. However, they are not able to edit a user's email address.

When changing the email field and clicking Save it asks for password as usual, accepts it and closes the user form. However, the email does not change and there is no error message.

If I go in as Admin, it works fine, but not for any User Group, irrespective of the fact that their permissions include changing email addresses.

One possible clue is that these users were migrated from an older site and the email addresses have not yet been confirmed. Any thoughts would be appreciated!

The "verify user email" setting will keep anyone other than the user or an Admin from changing an email address


New security key for existing database I've been hunting through questions here, Discord, Craft docs for solutions for a boilerplate Craft CMS install. Because I want to include section & field configurations, I'm planning on importing an export of the boilerplate database into a new database for the project.
It's documented in a few places that you can run craft setup/security-key (or craft setup/app-id) to generate a new key and store it in .env, but nothing says how that impacts a database that's already established. They all seem to assume you'd run that step before creating the database.
If you clone a project & existing database that's already used that first project's security key, and you want to have a unique security key for the new project, are you breaking the ability to decrypt data that was in the initial project when you generate a new security key? I don't see any indication that Craft updates the database when you generate a new key. It just updates .env.

Not sure there is a definitive answer here. :) For the use-case you're concerned about, Craft uses the security key to encrypt/decrypt data in the database. In a stock Craft installation, that's for sensitive email settings.
Even then, with the advent of Project Config, that's not likely an issue anymore. Those settings will get stored in Project Config files, which hopefully are using environment variables to hide their values.
I'd guess that 99% of plugins aren't encrypting/decrypting sensitive info and the ones that are, are probably storing that info in Project Config, so it still wouldn't be a concern.


Is Craft a good fit for a project w/ social network features? I'm wondering if Craft would be a good fit for a project that would require social features like:

users being able to submit content to the site
users being able to 'like' content
users being able to create 'folders/collections' and add/save content in them
users being able to follow each other to keep up with each others content

It really depends on whether you consider Craft a platform, that you're willing to do some custom development on, or an off-the-shelf, finished product.

Even though I love Craft, I have to be honest. As an off-the-shelf product, and if the main goal of the project is building a social network, I think you're be better off choosing some other, more specialised, platform.

You can probably solve all the things you mention with Craft; user handling, posting content to different channels from the front-end, updating content with likes, updating users with followers, etc. But, you don't get any specific social network functionality "for free", you'll have to use the building blocks that exists in Craft to create this functionality.

But, if you're willing to do some custom plugin development, you could definitely use Craft as the platform. The plugin API is extremely powerful, and let's you build and integrate pretty much whatever you want into Craft.


Best Practice on how to build a Pricing Page on CraftCMS CraftCMS gives us so many ways/options on how to build pages that I'd love to see what people are doing with their pricing pages!
I'm planning on building something similar to Amilia.com or Slack.com.
My thoughts:

Create 1 single page for the pricing page.
Create 3 entries in a structure for the 3 plans? (Or I don't need this?)
Create a features structure for all features?
For each feature entry put a field for each pricing plan?
Or do I just make it using a matrix field with a super table field?

I'd love to hear the best practices and what would be the best way to build a pricing page and all of its content. Thanks!

I've done something similar to this recently, and I went through the same though process as you've done!
I initially added a new Channel for plans, and built each plan as an entry in that channel. These were then selected in an Entries field for the pricing page entry. However, after building this solution locally, I felt like it was overkill for my particular use case.
In the end, I asked myself 'Will I need to reuse any of the data that's shown for each pricing plan anywhere else?' and the answer was 'no'. I removed the plans channel and ended up using a Super Table field in my pricing page entry type, with fields for the plan details inside the Super Table.
This was specific to my use case though, where I knew I wouldn't need to surface the plan data on any other pages. If you do need to reuse plan data elsewhere - and you probably will - then I'd stick with my original solution of defining the plans in a Channel as entries that can then be selected in an Entries field in your pricing page entry type. This way, the data for each plan is held in a single place and you get all the standard entry functionality (like draft entries, date expiry etc.) for your plans, which can be helpful.


Using Typekit fonts in Redactor I need to use a Typekit font in Redactor, but I'm not quite sure if I've done something wrong, or if Redactor's made a breaking change.

I'm enabling the iframe = true parameter in a custom.json redactor config, and then loading Typekit with the initCallback parameter. However, Redactor isn't placing the iframe (as of Craft Pro 2.4.2691) that Typekit uses for selection purposes.

Any ideas? has Redactor recently made a breaking change?

TL;DR: What's the best-practice for using Typekit fonts in Redactor fields as of Craft Pro 2.4.2691?

I would try to add the fonts with the Craft plugins

Control Panel JS
Control Panel CSS


Get Craft working on HHVM? Has anyone successfully run craft on an HHVM server?  I tried it using Forge, I got a page loading, but no admin and no subpages.

According to the HHVM Frameworks page, it has 99.7 percent compatibility with yii and 100% compatible with twig? I guess that last 0.3% is a doozy.

I'd love to hear if anyone else had had more success with it?

I wouldn’t recommend it until Yii is 100% compatible. And I’m guessing there’s not a lot of motivation to do that, since Yii 2 is almost out and is pretty much a complete rewrite.


Post to Sprout Forms plugin from an app or another website Is it possible to post a form to Sprout Forms in Craft 2 from a desktop app or another website?

The AJAX example in the docs mentions this - sproutForms/entries/saveEntry
What would the full URL be?

I did try http://domainname.com/sproutForms/entries/saveEntry but it gives an 404 error.

Thank you for reading this.

Assuming you're using a hidden action input, then sproutForms/entries/saveEntry should be correct.  You can see that in the Craft docs here: https://docs.craftcms.com/v2/plugins/controllers.html#posting-to-controller-actions

If you're not using that input, or you're constructing the URL to post to manually, then it will likely be actions/sproutForms/entries/saveEntry instead, assuming you have set a custom actionTrigger in your general config.


How to support chained Element queries with Twig tags The craft variable allows you to chain queries for your Elements. For example, you can query the first Entry in a section with either of the following syntaxes:

{% set entry = craft.entries({ section: 'news' }).one() %}
{% set entry = craft.entries.section('news').one() %}

How do we support both of these syntaxes in a Custom Element type?

The Craft Variable defines the entries tag like so:

public function entries(array $criteria = []): EntryQuery
{
  $query = Entry::find();
  Craft::configure($query, $criteria);

  return $query;
}

And, within the EntryQuery class, a public section method is defined:

public function section($value)
{
  if ($value instanceof Section) {
    $this->structureId = ($value->structureId ?: false);
    $this->sectionId = $value->id;
  } else if ($value !== null) {
    $this->sectionId = (new Query())
      ->select(['id'])
      ->from([Table::SECTIONS])
      ->where(Db::parseParam('handle', $value))
      ->column();
  } else {
    $this->sectionId = null;
  }

  return $this;
}

And there appears to be a __set method on the EntryQuery that also references the section method:

public function __set($name, $value)
{
  switch ($name) {
    case 'section':
      $this->section($value);
      break;
    case 'type':
      $this->type($value);
      break;
    case 'authorGroup':
      $this->authorGroup($value);
      break;
    default:
      parent::__set($name, $value);
  }
}

I've experimented with all of those and still only seem to be able to support the first syntax:

{% set entry = craft.entries({ section: 'news' }).one() %}

But can't seem to find a way to support the second syntax:

{% set entry = craft.entries.section('news').one() %}

What am I overlooking? What does a custom Element Type need to add to support the chained syntax for an Element Query via a Twig variable?

You need to return the instance in every single set call. As you noticed correctly the last line in every function that changes properties of your query is return $this which allows you to chain another function after the call. Simple as that.

Always return the query until you execute it with all() or another function like that is enough


Can Craft be run on NearlyFreeSpeech.NET? Because of some restrictions, some popular software (even Wordpress is a challenge) can't be run on NearlyFreeSpeech.NET. Can Craft be run on NearlyFreeSpeech.NET?

Yes, it is possible to run Craft CMS NearlyFreeSpeech.NET. I did it as follows:

Place the Craft folder in /home/tmp.
Place the files in the public folder in /home/public.
Change the permissions of the craft folder and all subfolders and all files to 777.
Change craftPath in index.php to '../tmp/craft'.

Perhaps it would not be necessary to change all subdirectories and files in the craft folder to 777. But it is the easier way and it should hopefully not create a problem, because the folder is not accessible from the public. Even the update process is running if the folder (including subfolders and files) is 777.


Members' site in Craft possible out of the box? I built a site in another CMS with an add-on which allows entries to be converted to member bios, and another add-on which makes sure all files uploaded by different members are viewable to that member only. The site allows users to search bands and read band profiles/listen to demos (Mp3s), each Member (band) uses a front end publish page to create their profiles (bios), would this workflow be possible using Craft?

Yes:

In Craft, all Elements — including Users — can have custom fields of their own. (So, for example, each User could have a "Bio" field.) You can use a User Profile Form to allow Users to edit their own profiles.
You can restrict the upload directory for each Assets field. So, for example, you could create an Assets field that stores files in a directory based on each User's ID, which would effectively keep one User from viewing/disturbing another User's files.


Database Exception Column not found: 1054 Unknown column 'configVersion' in 'field list' I get this Error when i want to save a Field. Also when i want to create a new field. I can hit the goback button and strangely the field gets still saved.
I work local and have project config activated. At the moment i have no idea where to begin to eliminate that error.
I hope someone can help.

After executing: craft migrate/up --type=app it works again.


Running a console command produces an error mentioning sessions. How do I resolve? None of the craft core console commands to work.
For example: ./yiic querygen all My_MyRecord produces an error which includes mention of session?

How do I get craft console commands working again?

You probably have a plugin which is listening to the userSession.onLogin event and trying to access the current user from the session.

The solution is for the plugin developer to wrap the event listener to ignore console sessions like this:

    if(!craft()->isConsole())
    {
        craft()->on('userSession.onLogin',
            [
                craft()->market_customer,
                'loginHandler'
            ]
        );
    }


Use pure PHP and HTML instead of Templates This is probably a very naive question but I am brand new to Craft and as such, have no idea what to research and where...

I have a static website that is built with my own bespoke framework. We have recently decided to add a 'blog' page to this website and resultantly, I am exploring using Craft in order to save me time writing a bespoke solution from scratch.

From what I can see, Craft is extremely flexible and brilliant for professional developers like myself who refuse to work with the likes of WordPress. However, implementing into my framework may just be a step too far in regards to flexibility. Quite simply, I would like to know the following:

Does craft allow me to make calls to get the stored data and then I manually handle the inserting of this data? e.g. Something like: $blog_posts = $craft->getBlogPosts()
If not, is there a way to include certain files at the beginning and end of templates that are outside the craft directory?

Basically, one of the key features of my framework is to handle the generation of all of the JavaScript and CSS links, along with the head section of each of the pages throughout my site. Based on what I have tested, I have managed to get the header working by just adding a PHP 'include' above the craft code in my file, however, the footer (including javascript) does not work because the Craft obviously has some sort of 'exit' call to prevent the code from executing further.

This is what I currently have:

// Define any custom javascript files and css files to be included in the cache
//...

// Generate the document header
include($_PATHS['CURRENT'].'/_includes/_content/header.php');

/*
 * Craft CMS Code to load the blog template
 */

// Path to your craft/ folder
$craftPath = './_craft/';

// Do not edit below this line
$path = rtrim($craftPath, '/').'/app/index.php';

if (!is_file($path))
{
    if (function_exists('http_response_code'))
    {
        http_response_code(503);
    }

    exit('Could not find your craft/ folder. Please ensure that $craftPath is set correctly in '.__FILE__);
}

require_once $path;

/*
 * End of Craft CMS Code
 */

// THIS DOES NOT WORK
// Generate the document footer
include($_PATHS['CURRENT'].'/_includes/_content/footer.php');

You're really fighting against the way Craft CMS does things.

I'd start by having a good read through the Craft Docs first, there really isn't a shortcut. The docs are really great though, and contain everything you're likely to need.

Then, I'd set up a copy of Craft in isolation of your site/framework and just get a feel for how you do things the "Craft way". It is different to just doing HTML & PHP, but not so different that's it going to take you too long to figure it out.

Craft actually uses the Twig tempting language, which is really easy to get going with.

In answer to your specific question...

Does craft allow me to make calls to get the stored data and then I manually handle the inserting of this data?

Yes it does. To output your data, you'd likely use sections/entries in your Twig template. So take a look at the example at the top of this page to see how you'd go about it. You'd input your data via the Control Panel, so have a read here for that.


Get the related entry from an Entries field in a Matrix block within a plugin craft 3 So I've got this which accurately gives me the desired relation block within my matrix, but how do I actually get the Entry object from a relation field?

$project = Entry::find()->id($projectId)->one();

foreach ($project->location as $locations) {
        if ($locations->getType()->name === 'Locations') {
            // Grab a building from the block.
            // Right now this just returns the relation table ID, I'd like the actual Entry object with it's attributes.
            $buildings = $locations->buildings;
        }

    }

figured this one out on my own, so to get all of the related objects, I just needed to change the above query to $buildings = $location->buildings->all();


Starting a section with a number I have a section of type structure where I need the url to be /5minutes. I cannot make this work (note that I have changed the handle to fiveminutes. But everything I would like to be 5minutes. I even tried setting a route for 5minutes. My question then is this. Is is simply not possible to begin a route or section with a numerical value?

A section can't have a handle that starts with a number, but there is nothing stopping you from using fiveminutes for the section's handle and setting the section's URL Format to 5minutes/{slug}.


Searching a specific section by four different types of parameters? I'll do my best to explain this.

I have a Portfolio of companies, which I have as a structure, that I need to be able to filter/search through by using up to four different parameters.

Keyword - a basic search field that a user can type into
Industry - a category field
Company Status - a dropdown field
Board Members - a relation to a different structure

I know how to search these individually but I'm not quite sure how to use any combo of these all at once. Whether that be using a keyword and industry to search, all four items to search, maybe just by industry and board members, or maybe just by industry.

Below is what I have so far. Hoping someone will be able to point me in the right direction or help me piece this together.

This handles the search

{# What is being searched #}
{% set portfolio = craft.entries.section('portfolio') %}

{# Potential Query Strings #}
{% set query = craft.request.getParam('q') %}
{% set industryParam = craft.request.getParam('industry') %}
{% set statusParam = craft.request.getParam('status') %}
{% set boardMemberParam = craft.request.getParam('boardMember') %}

{# Related to Industry and/or Board Member #}
{% set industry = craft.categories.group('industries').slug(industryParam).first %}

{# Here's where I'm not sure how to combine the relatedTo for the industry, status, and/or board members #}
{% set relationParam = industryParam ? {targetElement: industry} : '' %}

{% set entries = portfolio.relatedTo(relationParam).search(query) %}

{# Probably best to not use search, as it's slower than relatedTo, so I commented this out. #}
{# .search('companyStatus::"' ~ statusParam ~ '"') #}

{# Spit out the entries #}
{% if entries|length %}

  {% for entry in entries %}

{{ entry.title }}

  {% endfor %}

{% else %} {# If nothing matches the search criteria #}

Sorry, no results.

{% endif %}

Stripped down version of where the user sets the parameters

<form action="{{ url('portfolio') }}">

Filter by Keyword

  <input type="search" name="q" placeholder="Search">

Filter by Industry

  <select class="fancy" name="industry">
    <option value="">All Industries</option>

    {# Only get categories that are being used. #}
    {# This will definitely need some cache tags. #}
    {% set categories = craft.categories.group('industries').order('title asc') %}
    {% set entriesWithCategories = craft.entries.relatedTo(categories) %}
    {% set categoriesInUse = craft.categories.relatedTo(entriesWithCategories) %}

    {% for category in categoriesInUse %}
      <option value="{{ category.slug }}">{{ category.title }}</option>
    {% endfor %}
  </select>

Filter by Status

  <select class="fancy" name="status">
    <option value="">All Statuses</option>
    <option value="active">Active</option>
    <option value="past">Past</option>
  </select>

Filter by Board Member

  <select class="fancy" name="boardMember">
    <option value="">All Board Memebers</option>
    {% set team = craft.entries.section('team') %}
    {% for member in team %}
      <option value="{{ member.slug }}">{{ member.title }}</option>
    {% endfor %}
  </select>

  <input type="submit" value="Go">
</form>

And if possible, how would I do this with AJAX? This can come later, initial search function is 100% okay. I know I could do the the AJAX filter completely on the Front-End but there's potential that the client will want to eventually add pagination if they start adding a bunch of companies to their portfolio.

Thanks in advance.

One method is to build your params before performing the search.

{# set base params #}
{% set params = {
    section: 'portfolio',
    limit: null
} %}
{% set relatedParams = ['and'] %}

{# status #}
{% if craft.request.getParam('status') %}
    {% set status = craft.request.getParam('status') %}
    {% set params = params|merge({'companyStatus':status}) %}
{% endif %}

{# industry #}
{% if craft.request.getParam('industry') %}
    {% set category = craft.categories.group('industries').slug(craft.request.getParam('industry')).first %}
    {% set relatedParams = relatedParams|merge([{ targetElement:category }]) %}
{% endif %}

{# board member #}
{% if craft.request.getParam('boardMember') %}
    {% set boardMember = craft.entries.section('team').slug(craft.request.getParam('boardMember')).first %}
    {% set relatedParams = relatedParams|merge([{ targetElement:boardMember }]) %}
{% endif %}

{# add relatedParams to params #}
{% if relatedParams|length > 1 %}
    {% set params = params|merge({'relatedTo':relatedParams}) %}
{% endif %}

{# perform search #}
{% set searchParams = craft.request.getParam('q') %}
{% set entries = craft.entries(params).search(searchParams|trim) %}

{# display results #}
{% for entry in entries %}
    {{ entry.title }}
    ...
{% endfor %}

To AJAX load results you would place this in another template and load it dynamically with jquery. See this answer for an example.

To paginate the results you will need to submit your form as "GET" and append the query to your nextPage and prevPage links. See this answer for an example.


How to pass variable to Redirect tag I have a fruit Link it field that I use to allow users to choose an entry and have that page redirect to the chosen entry.  Not sure of the syntax to use to pass that link it field to the redirect field.

This does not work:

{% redirect "{{ block.redirect.url }}"  %}

Thanks

Does this work?

{% redirect block.redirect.url %}

I don't know Linkit but this would be the correct twig syntax at least. For normal entry fields you would do

{% redirect block.redirect.one.url %}


How do I update the state of lightswitches reliably using checkboxes on a frontend user profile form? I've got a frontend user profile form that is successfully setting the values of custom fields in the backend except for some lightswitch fields I've added to my user profiles.

I have the following code which displays a checkbox on the frontend profile form and sets checked="checked" if that switch is "on" in the backend:

<div class="checkbox">
  <label>
    <input type="checkbox" id="memberShowEmailLink" name="fields[memberShowEmailLink]" value="1" {% if currentUser.memberShowEmailLink %}checked="checked"{% endif %}>
    Show a link to contact me via email in the member directory?
  </label>
</div>

If the lightswitch is set to "off" and I check the box on the frontend form and submit the form, the change is saved and the lightswitch flips to "on" in the backend.

However, if the lightswitch is already "on" and thus the box is already checked, if I uncheck it on the frontend form and submit the form, the change is not saved and there's no change in the backend.

What am I missing?

While both lightswitches and checkboxes represent an on/off state, they are quite different. Standard browser behavior is designed to only post checkbox data if the checkbox is checked, otherwise it is ignored. In PHP, when processing the form, you would want to check whether the post-data is present or not; if it's present then the value is checked; otherwise it's unchecked.

Although I haven't reviewed how craft processes checkbox form submissions I would assume that it also performs this check behind the scenes, and converts the value to a 1 or 0 to store the data. However, being a lightswitch, craft probably does not perform this check, so if the field is missing from the post-data (which it would be if unchecked), then craft simply ignores it, as not being part of the form to begin with.

There may be a simpler method built in that I'm not aware of, but one solution would be to create a hidden field with your lightswitch handle, and then set that field using javascript when the user checks or unchecks the checkbox, much the way that craft does.

Here is the standard lightswitch html for example so you can see how craft sets this up:

    <input type="hidden" name="fields[switchHandle]" value="">

You would want something like this:

        <input type="checkbox" class="js-checkbox" {% if currentUser.memberShowEmailLink %}checked="checked"{% endif %}>
        Show a link to contact me via email in the member directory?

    <input type="hidden" class="js-lightbox" name="fields[memberShowEmailLink]" value="{% if currentUser.memberShowEmailLink %}1{% endif %}">

Then in javascript:

$('.js-checkbox').on('change', function(event) {
    if($(this).prop('checked')) {
        $('.js-lightbox').val(1);
    } else {
        $('.js-lightbox').val(0);
    }
});

Note: if you leave off the 'name' attribute the dummy checkbox should not get submitted.


Get Groups from User in plugin Wondering if I can get user groups directly after retrieving the user via craft()->users->getUserById($id), or if i need to use craft()->userGroups->getGroupsByUserId($id) also?

As of right now, I'm looping through many users and want to check if they are in a specific group. A rough idea of what I'm looking at now:

// get user (necessary for rest of plugin)
$user = craft()->users->getUserById( $uid );

// get user groups
$user_groups = craft()->userGroups->getGroupsByUserId( $uid );

// check if user is in group
if( in_array("Group_Name", $user_groups) )
{
   // do something
}

This works, but when looping through a ton of users, I imagine it would be silly not to first check that I can already get this information from the $user variable I created. I can't seem to find the answer via documentation. Hoping to get a confirmation from someone!

Thanks

Your code to get a user returns a UserModel (as can be seen from the Full Class Reference docs):

$user = craft()->users->getUserById($id);

You can then get the user groups the $user is a member of usinggetGroups()(from the UserModel class):

$user_groups = $user->getGroups();


Switch entry type based on the category I'm trying to use different entry types for certain categories. My category group is called categories, and the slug for Features is features. I have the category group pointed to categories/_entry. As for as I can tell, I've got it set up right. I think their might just be something wrong with my switch code. This is my code in categories/_entry:

{% set categories = entry.categories.first %}
{% switch categories.slug %}
    {% case 'features' %}
        {% include 'categories/_feature.html' %}
    {% case 'news' %}
        {% include 'categories/_news.html' %}
    {% default %}
        {% include 'categories/_news.html' %}
{% endswitch %}

The above isn't too clear, but what I was trying to do is use different templates for  different category landing pages. It works with the following:

{% switch category.slug %}
    {% case 'features' %}
        {% include 'categories/_features.html' %}
    {% case 'news' %}
        {% include 'categories/_news.html' %}
    {% default %}
        {% include 'categories/_news.html' %}
{% endswitch %}


How to print all possible options of a dropdown field inside of a Matrix field? I'm asking this outside an entry context.

My starting point is

  {% set field = craft.app.fields.getFieldByHandle('matrixFieldHandle')
  %}

When I print the data of the field, I find nothing related to the fields that matrixFieldHandle contains.

matrixFieldHandle (Matrix field)

Block Log

Field logValue (Dropdown field)

I know how to print the options in a dropdown field:

How do I output a dropdown's values if I'm on a registration form not tied to an entry?
How do I print the options in a dropdown field?

But how can I print all these dropdown options when it is set inside a Matrix?

This can be done like so...

{% set matrix = craft.app.fields.getFieldByHandle('myMatrixField') %}
{% for field in matrix.blockTypeFields if field.handle=='myDropdownField'  %}
    <select>
    {% for option in field.options %}
        <option value="{{ option.value }}">{{ option.label }}</option>
    {% endfor %}
    </select>
{% endfor %}


Search query: grouping and merging multiple searches Is it possible to 'group' search logic in the craft.entries.search query? I need to do the following: [a OR b OR c]  AND  [d OR e]  AND  [x OR y OR z]

Thanks!

You can combine ORs within the same column but you can't easily combine multiple columns with an OR statement.

craft.entries.yourFieldHandle('OR, x, y, z').anotherFieldHandle('OR, d, e')


Config for devMode not showing when true I am using .env to set environment to local:

# .ENV The environment Craft is currently running in ('dev', 'staging',
'production', etc.)
 CRAFTENV_CRAFT_ENVIRONMENT="local"

My general config looks like:

 // Dev environment settings
'local' => [
    'devMode' => true,

    // Base site URL
    'siteUrl' => getenv('CRAFTENV_BASE_URL')

],

My staging site is :

 // Staging environment settings
'staging' => [
    // Base site URL
    'siteUrl' => getenv('CRAFTENV_BASE_URL'),

    // Dev Mode (see https://craftcms.com/support/dev-mode)
    'devMode' => true,

    'baseUrl'  => getenv('CRAFTENV_BASE_URL'),
    'basePath' => getenv('CRAFTENV_BASE_PATH'),
    'aliases' => [
        '@assetBaseUrl' => getenv('ASSET_BASE_URL'),
        '@assetBasePath' => getenv('ASSET_BASE_PATH'),
        '@baseUrl' => getenv('CRAFTENV_BASE_URL'),
        '@basePath' => getenv('CRAFTENV_BASE_PATH')
    ],
    // Custom site-specific config settings
    'custom' => [
        'craftEnv' => getenv('CRAFTENV_CRAFT_ENVIRONMENT'),
        'staticAssetsVersion' => 1,
    ]
],

Why wont my local site show the dev mode settings in CP ?

The solution was ENVIRONMENT="local" in .env
via andrew.welch


How to get corresponding Post in Craft request? I'm working on a Craft CMS plugin. I'm making a form that consists of multiple themes and questions. The structure is supposed to be as follows:

• Form
  • Theme
    • Question
    • Question
    • Question
  • Theme
    • Question
    • Question

Questions should be “attached” to the form with the formId, but also to their respective themeId. This kinda works when there’s just one theme, but as soon as I save a question in a second or third theme, all questions get the last theme id.

I’ve added a hidden field to each question which looks like this:

<input type="hidden" class="questionThemeId" name="questionThemeId" value="{{ themeId }}">

Then in my Service I do the following request and add the themeId to the question.

$themeIdForQuestion = craft()->request->getPost("questionThemeId");
$question->themeId = $themeIdForQuestion;

This does add the themeId to the question, but once there is a question in the second theme, all questions get the themeId of the last theme. That makes sense, because getPost always gets the last post (I think). How would I get post of the questionThemeId depending on the question?

I'm open to other solutions too, because this does feel slightly hacky.

Thanks!

That makes sense, because getPost always gets the last post (I think).

If you've got multiple form inputs with the same name, then the last one in is probably the value that will get sent over POST to the controller.

You could make sure your themeId name inputs are unique by appending a unique string or some such to them, then parsing through all of the submitted values on the PHP side, perhaps?


Installing happylager demo site on own server (not locally) I would like to install the happylager demo site on my server instead of installing it locally,
but all i get is 404 pages when i visit http://adamridovics.com/happylager.dev/admin
Is this possible at all, or i am doing something worong?

Thanks @BradBell , your comment made me recheck everything - i just forgot to take out the files from the public folder... now everything looks fine.


Pass params to transform function of Transformer class in split Transformer class I have transformer like down below in the element API.

'transformer' => 'MyTransformerClassName',

Or

'transformer' => new MyTransformerClassName(),

I am going to pass a param like $user through MyTransformerClassName to use in separate Class Like here.

class MyTransformerClassName extends TransformerAbstract
{
    public function transform(Entry $entry)
    {
        return [
            // ... here want to use $user coming from element api
        ];
    }
}

How can I pass the $user variable to the separate transformer class to use it in transform method?

Here's how you would do that...

Pass your parameter to the class:

'transformer' => new MyTransformerClassName($user),

Use a constructor to save it as a property:

class MyTransformerClassName extends TransformerAbstract
{
    private $user;

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

    public function transform(Entry $entry) ...
}

Use your property as needed:

class MyTransformerClassName extends TransformerAbstract
{
    private $user;

    public function __construct($user) ...

    public function transform(Entry $entry)
    {
        return [
            'user' => $this->user,
            ...
        ];
    }
}


Saving Asset field in FEEF ("Front-end entry form") using Plugin I'm having issues saving an Asset field in my FEEF using a Plugin. I have a channel with some fields added to it, one of these fields being an Asset field. When using the standard entries/saveEntry build in function in Craft the Asset gets saved.

When I try to run the same form (same channel, same field) through my Plugin everything saves except the Asset field asset. The code I'm using (below) is a slightly changed version of Pixel&Tonics own "Guest Entries" Plugin.

Can anyone help me to figure out whats going on?

/**
 * Populates an EntryModel with post data.
 *
 * @access private
 * @throws HttpException
 * @return EntryModel
 */
private function _populateEntryModel()
{
    $entry = new EntryModel();

    // Set section
    $entry->sectionId   = craft()->request->getRequiredPost('sectionId');
    $this->_section     = craft()->sections->getSectionById($entry->sectionId);
    $this->_entryTypeId = craft()->request->getPost('entryTypeId');

    // Default
    $entry->authorId    = 1;
    $entry->enabled     = true;

    // Set title
    $entry->getContent()->title = craft()->request->getPost('title');

    // Set Entry type
    if($this->_entryTypeId)
    {
        $entry->typeId = $this->_entryTypeId;
    }

    // Add dynamic fields
    $entry->setContentFromPost(craft()->request->getParam('fields'));

    // Return model
    return $entry;
}

This is how my form looks (I've removed some styling and keept the essentials)

<form method="post" action="" accept-charset="UTF-8" enctype="multipart/form-data">

<!-- Hidden -->
{{ getCsrfInput() }}
<input type="hidden" name="action" value="forms/saveEntry">
<input type="hidden" name="redirect" value="{{ craft.request.url }}?sent=1">
<input type="hidden" name="sectionId" value="13">
<input type="hidden" name="entryTypeId" value="18">
<input type="hidden" name="title" class="title" value=""/>

<input type="text" name="fields[formName]" value="{% if formEntry.formName is defined %}{{ formEntry.formName }}{% endif %}" class="default-field name" />
<input type="text" name="fields[formConfirmationNumber]" value="{% if formEntry.formConfirmationNumber is defined %}{{ formEntry.formConfirmationNumber }}{% endif %}" class="default-field" />
<input type="text" name="fields[formRoom]" value="{% if formEntry.formRoom is defined %}{{ formEntry.formRoom }}{% endif %}" class="default-field" />
<input type="file" name="fields[formFile]">

</form>

The name="title" field gets set dynamic...

Here's the issue:

// Add dynamic fields
$entry->setContentFromPost(craft()->request->getParam('fields'));

setContentFromPost requires that if you pass any uploaded files in, you need to pass the field name as a string, instead of the actual posted values.

Changing it to this and it should work:

$entry->setContentFromPost('fields');


How to store class variable inside a Craft controller namespace Craft;

class Test_FormsController extends BaseController
{

   protected $allowAnonymous = true;
   public $session_id;

    public function actionApply(){
        $appl_template = "1";
        $this->session_id = 15558145;
        return $this->renderTemplate("apply/step".$appl_template.".html");
    }

    public function actionSaveDataStruct(){
        echo 'session:'.$this->session_id.'<br />';
        exit();
    }
}

Hi guys i'm newbie on Craft and my question is:

acctionApply loads form which will send to actionSaveDataStruct, I set a class variable $session_id on actionApply but whenever the form submitted and goes to actionSaveDataStruct, $this->session_id become null again, how do I set variable that will never reset whenever the page load?

In addition to passing the value along through a cookie, you could also do it through PHP's session support.

Adding:

craft()->httpSession->add('sessionId', '123456');

Retrieving:

$sessionId = craft()->httpSession->get('sessionId');

Deleting:

craft()->httpSession->remove('sessionId');


How would you recommend integrating craft with Algolia Has anyone had experience integrating craft with algolia: https://www.algolia.com for realtime search of craft entries.

It seems like there are a few potential approaches with their Php and Js libraries. Does anyone recommend a particular approach or best practice for integrating a service like this with Craft.

Disclaimer : I'm the dev of the SearchPlus plugin

The SearchPlus plugin by SquareBit (currently in private beta) integrates directly with Algolia and handles all the index population and updates.

There's also a few helpers for integrating on the front-end.

All told - you should be able to just drop the plugin onto the site, configure your indexes and start a population action, drop a bit of js on the front-end and you're done.

Drop me a line and I'll get you on the beta.


Update Asset Index SQL Error I understand there's a lot of work being done on the Update Asset Indexes feature. I believe I've run into another issue related to MySQL, whereas other issues have been related to PHP's memory_limit.

Would appreciate some feedback on trying to address this issue.

Thanks!

2016/12/31 22:45:19 [error] [system.db.CDbCommand] CDbCommand::execute() failed: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`homeaidoc`.`craft_assetfolders`, CONSTRAINT `craft_assetfolders_parentId_fk` FOREIGN KEY (`parentId`) REFERENCES `craft_assetfolders` (`id`) ON DELETE CASCADE). The SQL statement executed was: INSERT INTO `craft_assetfolders` (`uid`, `parentId`, `sourceId`, `name`, `path`, `dateUpdated`, `dateCreated`) VALUES (:yp0, :yp1, :yp2, :yp3, :yp4, :yp5, :yp6).
2016/12/31 22:45:19 [error] [exception.CDbException] CDbException: CDbCommand failed to execute the SQL statement: SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails (`homeaidoc`.`craft_assetfolders`, CONSTRAINT `craft_assetfolders_parentId_fk` FOREIGN KEY (`parentId`) REFERENCES `craft_assetfolders` (`id`) ON DELETE CASCADE) in /var/www/craft/app/framework/db/CDbCommand.php:358
Stack trace:
#0 /var/www/craft/app/framework/db/ar/CActiveRecord.php(1081): CDbCommand->execute()
#1 /var/www/craft/app/framework/db/ar/CActiveRecord.php(810): CActiveRecord->insert(NULL)
#2 /var/www/craft/app/services/AssetsService.php(263): CActiveRecord->save()
#3 /var/www/craft/app/assetsourcetypes/BaseAssetSourceType.php(1022): Craft\AssetsService->storeFolder(Object(Craft\AssetFolderModel))
#4 /var/www/craft/app/assetsourcetypes/LocalAssetSourceType.php(121): Craft\BaseAssetSourceType->ensureFolderByFullPath('development/emm...')
#5 /var/www/craft/app/services/AssetIndexingService.php(40): Craft\LocalAssetSourceType->startIndex('cf59adea-fe2b-4...')
#6 /var/www/craft/app/tools/AssetIndexTool.php(94): Craft\AssetIndexingService->getIndexListForSource('cf59adea-fe2b-4...', '1')
#7 /var/www/craft/app/controllers/ToolsController.php(50): Craft\AssetIndexTool->performAction(Array)
#8 /var/www/craft/app/framework/web/actions/CInlineAction.php(49): Craft\ToolsController->actionPerformAction()
#9 /var/www/craft/app/framework/web/CController.php(308): CInlineAction->runWithParams(Array)
#10 /var/www/craft/app/framework/web/CController.php(286): CController->runAction(Object(CInlineAction))
#11 /var/www/craft/app/framework/web/CController.php(265): CController->runActionWithFilters(Object(CInlineAction), Array)
#12 /var/www/craft/app/framework/web/CWebApplication.php(282): CController->run('performAction')
#13 /var/www/craft/app/etc/web/WebApp.php(817): CWebApplication->runController('tools/performAc...')
#14 /var/www/craft/app/etc/web/WebApp.php(287): Craft\WebApp->_processActionRequest()
#15 /var/www/craft/app/framework/base/CApplication.php(185): Craft\WebApp->processRequest()
#16 /var/www/craft/app/index.php(62): CApplication->run()
#17 /var/www/public/index.php(19): require_once('/var/www/craft/...')
#18 {main}
REQUEST_URI=/index.php/admin/actions/tools/performAction
HTTP_REFERER=http://homeaidoc.craft.dev/admin/settings
---

That error indicates a problem with the data in your database.

The craft_assetfolders table has a parentId column that is a foreign key reference to its own id column.  For whatever reason, that parentId column has a value that doesn't exist in any of the id columns, hence your errors.

Some common causes include:

Someone manually editing database values.
A botched import/export script when backing up/restoring databases.
Having multiple Craft installs (maybe across environments) pointing to the same cloud based Asset source (S3, Google Cloud, etc.) and someone deletes/moves/etc. an Asset on one environment making the other one out of sync with reality.


How to process Matrix field in controller I am trying to process a text field inside a Matrix field.

In the controller I have this to get posted params:

$element->setFieldValuesFromRequest($fieldsLocation);

If I want to process a custom text field, I can do it easily with

$result=$element->getFieldValue('textFieldHandle')

which $result is exactly the text field value.

but if I have this text field in Matrix field, if I do this:

$result=$element->getFieldValue('matrixFieldHandle')
craft::dd($result)

I get a craft\elements\db\MatrixBlockQuery object which I don't know how I can fetch text value from this object.

You have to loop the Matrix field first, something like this:

foreach($entry->matrixHandle->all() as $block) {
   echo $block->fieldHandle;
}


Cannot install custom Twig extension plugin So I started building this plugin to add a twig extension to escape but leave &nbsp; intact. For some reason when I try install it or use it without the force argument on the import command in the plugin file set to true it does not work. If i set it to true, though, it installs fine and works fine.

My plugin Directory Structure:

craft
 - plugins
   - nbsp
     NbspPlugin.php
     - twigextensions
       NbspTwigExtension.php

Here is my NbspPlugin.php file:

<?php
namespace craft;

class NbspPlugin extends BasePlugin {

    function getName()
    {
        return Craft::t('&nbsp Twig Filter');
    }

    function getVersion()
    {
        return '1.0';
    }

    function getDeveloper()
    {
        return 'Rick';
    }

    function getDeveloperUrl()
    {
        return '';
    }

    public function addTwigExtension()
    {
        Craft::import('plugins.nbsp.twigextensions.NbspTwigExtension');

        return new NbspTwigExtension();
    }
}

Here is my NbspTwigExtension.php file:

<?php

namespace Craft;

class NbspTwigExtension extends \Twig_Extension
{

    public function getName()
    {
        return '&nbsp; filter';
    }

    public function getFilters()
    {
        $returnArray = array();
        $methods = array(
            'escapeNonNbsp',
        );

        foreach ($methods as $methodName) {
            $returnArray[$methodName] = new \Twig_Filter_Method($this, $methodName, ['pre_escape' => 'html', 'is_safe' => array('html')]);
        }

        return $returnArray;
    }

    public function escapeNonNbsp($content)
    {
        // perform filter operations
        return str_replace('&amp;nbsp;', '&nbsp;', $content);
    }

}

I cannot install the plugin. I get an exception
Can't find Craft\NbspTwigExtension referencing the return line of the addTwigExtension() Method. If I add the force = true argument to the import above it, it installs it, but then upon attempting to use the filter in the twig template it fails even with the import being forced.

What am I doing wrong?

EDIT - I found one bug in my set up where the name of my method in the extension class needs to match how I call the filter from twig. I changed it to:

<?php

namespace Craft;

class NbspTwigExtension extends \Twig_Extension
{

    public function getName()
    {
        return '&nbsp; filter';
    }

    public function getFilters()
    {
        $returnArray = array();
        $methods = array(
            'nbsp',
        );

        foreach ($methods as $methodName) {
            $returnArray[$methodName] = new \Twig_Filter_Method($this, $methodName, ['pre_escape' => 'html', 'is_safe' => array('html')]);
        }

        return $returnArray;
    }

    public function nbsp($content)
    {
        // perform filter operations
        return str_replace('&amp;nbsp;', '&nbsp;', $content);
    }

}

However it still requires "force" true on the import command to work or install. Why!!?

My guess is it's because your NbspPlugin class has the namespace of craft, when it should be namespace Craft.

FWIW, generating Craft plugin boilerplate code through something like https://pluginfactory.io/ is a great way to save sanity and avoid things like this. :)


How to display a collection for admins I'm creating a structure page for collections. What is the best way to display collections by year? Should I use tags? How can I implement that?

How do I create an “Archive” page for my entries? covers this.


Search only by Field instead of entire content I have a vacancy's website which has a couple of search forms spread around the website. The craft standard search form works great, the only problem is I need to search only by the title field instead of all the content in the entries.

So my question is..

Is it possible to search only by title field?

Give this a go:

{% set searchTerm = craft.request.getParam('q') %}
{% set query = craft.entries({
        search: 'title:*' ~ searchTerm ~ '*',
        limit: 5,
        locale: craft.locale,
        order: 'score'
    }) %}

You can leave out the * on both sides if you only want to search for full word matches. Also, this might help you take it further: https://craftcms.com/docs/searching


Error uploading .bmp file format - gets rejected I'm doing some testing on file uploads and discovered that the .bmp file format gets rejected even though defined in my config file as an allowed file extension.

I have added the following to my config file:

 'extraAllowedFileExtensions' => 'bmp, jpeg, tiff, pdf, cdr, gbr, gtl, dxf, dwg',
 'allowedFileExtensions' => 'bmp, jpeg, tiff, pdf, cdr, gbr, gtl, dxf, dwg',

This is the error I receive:

The file “/private/var/tmp/php7Md2bj” does not appear to be an image.

/shop/craft/app/etc/image/Image.php(138)

138    throw new Exception(Craft::t('The file “{path}” does not appear to be an image.', array('path' => $path)));

How do I fix this?

You're probably using GD, which doesn't support BMP files.

If you install  Imagick on your server, Craft will use it automatically and it supports a much wider range of file types, including BMP files.


How can I use Garnish to sort? I am working on a field type that is similar to the table field type. Is it possible to tap into Garnish for the sorting. I’ve tried a few things and have had no luck. Can anyone help me out?

Sure, I've had experience with two different types of sorting with SuperTable (check the link for associated JS).

If you're modelling the fieldtype after a table, you might like to use the Craft.DataTableSorter method. Its pretty restrictive to a table layout, and you'll need to give each tr element a data-id.

Craft.FieldType = Garnish.Base.extend({
    sorter: null,

    init: function() {
        var $table = $container.children('.table');

        this.sorter = new Craft.DataTableSorter($table, {
            helperClass: 'editabletablesorthelper',
            copyDraggeeInputValuesToHelper: true
        });
    },

    addRow: function() {
        var $tr = $('<tr/>');
        this.sorter.addItems($tr);
    }
});

Or, for more abstract sorting, you can have more control using Garnish.DragSort - essentially a general drag and sort function. This is what Matrix uses.

Craft.FieldType = Garnish.Base.extend({
    sorter: null,

    init: function() {
        var $rows = $container.children('.table-rows');

        this.sorter = new Garnish.DragSort($rows, {
            handle: 'tfoot .move',
            axis: 'y',
            collapseDraggees: true,
            magnetStrength: 4,
            helperLagBase: 1.5,
            helperOpacity: 0.9,
        });
    },

    addRow: function() {
        var $tr = $('<tr/>');
        this.sorter.addItems($tr);
    }
});


Updating Craft Produced Fatal Error.What now? Just tried updating craft from version 2.4.2669 to the latest version 2.4.2702 unfortunately it threw a fatal error with the following error message:

  Status: OK

  Response:  Fatal error: Out of memory (allocated
  33030144) (tried to allocate 41 bytes) in
  /homepages/3/d272256762/htdocs/crafttest/craft/app/framework/db/CDbCommand.php
  on line 518

So I then tried to manually install it by uploading the app folder. Clicked through on the update databases it started working, but again threw the same error.

The site is on a shared server so I can not do much regarding memory limits.

So now I have no CMS and no frontend what can I do to rectify this problem to either rollback to the previous version or update to the newer one?

How big is your database? It could be that Craft is failing to backup your database as part of the update process because it is running out of memory.

Try setting the backupDbOnUpdate config setting to false and running the update again.


Verbb Wishlist plugin see if item is in specific list Looking at the docs, it says to check if an item is in wishlist using the below code:
{% set compare = craft.wishlist.item(entry.id) %}
{% if compare.inList %}
    Remove from Compare
{% else %}
    Compare
{% endif %}

I want to do the above but tell it what list to look in i.e craft.wishlist.type('compare').item(entry.id)
I cannot see how on earth to do this. I have multiple lists that an entry could be in, so need to specify.
Any help would be very gratefully received!!

You can pass a list type handle in the query like this:
{% set compare = craft.wishlist.item(entry.id, null, 'compare') %}

I had to look at the source code for the craft.wishlist variable to confirm what that's doing, though! The Wishlist docs on checking if an item is in a list aren't super-clear on this, but passing the list type handle in the query will fetch the first list that matches that handle for the current user. If you have multiple lists for that list type, only the first one that the query returns will be checked for the item.


Does Craft Have a URL Rewrite Vulnerability? We could use some help tracking down a consistent error on our Craft installs according to Acunetix Security Audits.

URL Rewrite Vulnerability

  It was identified that this application supports the legacy headers
  X-Original-URL and/or X-Rewrite-URL.

  Support for these headers lets users override the path in the request
  URL via the X-Original-URL or X-Rewrite-URL HTTP request header and
  allows a user to access one URL but have web application return a
  different one which can bypass restrictions on higher level caches and
  web servers.

  Many web frameworks such as Symfony 2.7.0 to 2.7.48, 2.8.0 to 2.8.43,
  3.3.0 to 3.3.17, 3.4.0 to 3.4.13, 4.0.0 to 4.0.13 and 4.1.0 to 4.1.2 , zend-diactoros up to 1.8.4, zend-http up to 2.8.1, zend-feed up to
  2.10.3 are affected by this security issue.

https://symfony.com/blog/cve-2018-14773-remove-support-for-legacy-and-risky-http-headers

https://framework.zend.com/security/advisory/ZF2018-01

These sites are hosted on Forge / Linode servers.
Versions vary, but most are recent-ish Craft 2.X
A couple (though not all) use the Redirect Manager plugin

Both Yii 1 and Yii 2 will check for the X-Rewrite-URL header when determining the requested URI, however no known vulnerabilities exist related to that, because Craft is sure to use the same URI (whatever its source) for both routing and any other URI-related logic throughout the system. So it’s not possible to have Craft base its routing on one URI and template logic off of another URI, for example.


Twig "is defined" always returning true I am trying to code defensively and check whether a field exists before accessing it:

{% if e.someField is defined %} {{e.someField}} {% endif %}

And I get a CException

  Craft\EntryModel and its behaviors do not have a method or closure named "someField".

Because is defined is always returning true.

Any clue what's wrong?

I believe I have a workaround and can (roughly) explain what's going on here.

First, the workaround:

Use array syntax to test the existence of your custom fields instead of object syntax.

{# This works #}
{% if entry['someField'] is defined %} ... {% endif %}

Using array syntax for your conditional will result as true if your field does exist and false if it does not. Using object syntax results in false positives where the conditional always returns true even if a field doesn't exist:

{# FALSE POSITIVES: These return true if a field doesn't exist #}

{% if entry.someField is defined %} ... {% endif %}
{% if attribute(entry, 'someField') is defined %} ... {% endif %}

I believe the false positive occurs using object syntax when the object has or is extending another object that uses a __call() method. Twig will test to see if it can find an attribute or a method.  In the case it can't find an attribute on an object, it will look for a method.  And if it can't find a method on the object, it will check for the existence of a __call() method and if the _call() method exists it returns true, creating the undesired result of also returning true for any variable that doesn't exist on an object that uses a __call() method.

I haven't dug into the code, but it seems that using the array syntax doesn't trigger a search for a potential method associated with the __call() behavior.

A couple related articles can be found on Straight Up Craft:

How to check if a variable or value exists using Twig
Testing if something exists: is defined, length, is not null, is not empty


Can Craft handle thousands of entries and high traffic? We are going to start an online magazine. Registered users will be able to submit new entries (articles, places, etc...). Can Craft handle thousands of entries and high traffic (Of course with required server)?

Sure... we've seen Craft installs with several hundred thousands entries/users/assets/etc. running in the wild, but there really isn't a simple answer to this question.

As you pointed out, performance can be heavily dependent on the server and environment that Craft is running on, but that goes for any web application.

Performance on the front-end is also dependent on your templating architecture and code.  Craft does provide some {% cache %} tags that can help with some of the more database dependent parts of your templates.

If traffic to your site is significant enough, you can also consider putting something like Varnish in front of Craft as well as another layer of caching.


Apply different classes and styles when in 'live preview' pane Is there any way of adding a class onto a page body when it is viewed within the 'live preview' pane?

I can then use this to make things either show or not show.

I want to do this to highlight specific things to content editors that I don't feel are worth highlighting to regular users.

I think I can only do this by hanging rules off a special 'preview only' class.

Craft's Request service has a built-in method for this, isLivePreview.

Here's how to only display content in the live preview view:

{% if craft.request.isLivePreview %}

Only appears in live preview.

{% endif %}


Does the Craft config var "cache" exist? I'm reviewing the code on a project that has the following defined in the main config.php as a boolean:

cache => true

Looking at the docs this doesn't seem to be referenced anywhere. Does the config option exist in Craft 2? I'm not seeing any documentation that states it does.

I know others like cacheMethod and cacheDuration do.

I don't believe this is a valid configuration value. You will use the cache as a tag in your twig files:

{% cache %}
    {% for element in entry.hugeField %}
        {{ element.nestedAsset.first().url }}
    {% endfor %}
{% endcache %}

The cache is most effective at nested queries in matrix fields or asset fields or category fields. Do not use the cache for plain text fields or those that can be accessed in linear time.

I would just delete that line from your config.php


Update Order Status action missing Having an issue where the "Update Order Status..." menu option is not available on order list pages. This is true both for admins and for users who have permissions set to manage commerce orders. Any ideas as to what might cause this? Thanks!

This sounds like a bug. Please submit a issue at http://github.com/craftcms/commerce


Multi locale, multi-domain Live Preview failing I have a multi-locale site set up with the different locales in different domains

phoseon.craft.dev - English site
phoseon.it.craft.dev - Italian site

etc.

I am having problems getting Live Preview to work with a locale other than English.

The page I am trying to get this to work on, test-single, is a single, with a template that just displays the title (so no complexity there).

When I try to use Live Preview in a locale other than English, I get this error in the console:

  Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://phoseon.it.craft.dev/. This can be fixed by moving the resource to the same domain or enabling CORS.

And no Live Preview, just a white screen.

Based on this answer I added this to .htaccess for http://phoseon.it.craft.dev

Header add Access-Control-Allow-Origin "http://phoseon.craft.dev"

And now I see these requests, and still a white screen for the Live Preview:

POST http://phoseon.it/craft.dev/test-single 302 Found
  Request Headers:
    Accept  */*
    Accept-Encoding gzip, deflate
    Accept-Language en-US,en;q=0.5
    Content-Length  198
    Content-Type  application/x-www-form-urlencoded; charset=UTF-8
    Host  phoseon.it.craft.dev
    Origin  http://phoseon.craft.dev
    Referer http://phoseon.craft.dev/admin/entries/testSingle/1742-testsingle/it_it
    User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:35.0) Gecko/20100101 Firefox/35.0
  Response Headers:
    Access-Control-Allow-Orig...  http://phoseon.craft.dev
    Cache-Control no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Connection  Keep-Alive
    Content-Encoding  gzip
    Content-Length  2346
    Content-Type  text/html
    Date  Mon, 16 Feb 2015 20:38:14 GMT
    Expires Thu, 19 Nov 1981 08:52:00 GMT
    Keep-Alive  timeout=5, max=100
    Location  http://phoseon.it.craft.dev/login
    Pragma  no-cache
    Server  Apache/2.2.26 (Unix) DAV/2 PHP/5.4.30 mod_ssl/2.2.26 OpenSSL/0.9.8zc
    Set-Cookie  CraftSessionId=gtm75r2a9it49820uueam9hpe2; path=/; HttpOnly
    Vary  User-Agent,Accept-Encoding
    X-Powered-By  PHP/5.4.30

  And the response is the site's 404 page

GET http://phoseon.it.craft.dev/login 404 Not Found
  Request Headers:
    Accept  */*
    Accept-Encoding gzip, deflate
    Accept-Language en-US,en;q=0.5
    Content-Type  application/x-www-form-urlencoded; charset=UTF-8
    Host  phoseon.it.craft.dev
    Origin  http://phoseon.craft.dev
    Referer http://phoseon.craft.dev/admin/entries/testSingle/1742-testsingle/it_it
    User-Agent  Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:35.0) Gecko/20100101 Firefox/35.0
  Response Headers:
    Access-Control-Allow-Orig...  http://phoseon.craft.dev
    Cache-Control no-store, no-cache, must-revalidate, post-check=0, pre-check=0
    Connection  close
    Content-Encoding  gzip
    Content-Length  42163
    Content-Type  text/html; charset=utf-8
    Date  Mon, 16 Feb 2015 20:38:14 GMT
    Expires Thu, 19 Nov 1981 08:52:00 GMT
    Pragma  no-cache
    Server  Apache/2.2.26 (Unix) DAV/2 PHP/5.4.30 mod_ssl/2.2.26 OpenSSL/0.9.8zc
    Set-Cookie  CraftSessionId=isldd40afpu41mr9as659f6rs7; path=/; HttpOnly
    Vary  User-Agent,Accept-Encoding
    X-Powered-By  PHP/5.4.30
    charset utf-8

  And the response is agin the site's 404 page

Anyone else encountered this? Know what's going on? Recommended fixes?

Only setting headers in .htaccess doesn't fix the problem.
As Marion Newlevant points out in her answer the cross domain works with the headers set. But you still get a white page as a preview.

Looking further into the problem, I've found that the page tries to do a post request to the other domain.
It calls upon the action function actionPreviewEntry() in the EntriesController.php file (Location: /craft/app/controllers/ )

But because the user isn't logged in on the other domain and anonymous access isn't allowed for this action. You get redirected to /login to login on that domain.

I came up with a quick solution for the problem. It's a bit dirty for now, but the authors of Craft aren't coming with a solution either.

Solution

Delete (If you have set them) the headers for Access-Control-Allow in your .htaccess file. We don't need them.
Open the file EntriesController.php in the folder /craft/app/controllers/
Replace the code.

protected $allowAnonymous = array('actionViewSharedEntry');

With:

protected $allowAnonymous = array('actionViewSharedEntry','actionPreviewEntry');

Add the following code in the public function actionPreviewEntry():

// Set a boolean for logout admin user if cross-domain access
$crossDomainAccess = FALSE;

// Check if the user isn't logged in. Likely meaning that the action is called from another domain.
if ( !craft()->userSession->isLoggedIn() ) {

  // Get allowed origins
  $locales = array('en','nl');
  $allowedOrigins = array();
  foreach ( $locales as $locale ) {
    $allowedOrigins[] = craft()->config->getLocalized('siteUrl', $locale);
  }

  // Check origin and give access if allowed
  $httpOrigin = $_SERVER['HTTP_ORIGIN'];
  if ( in_array($httpOrigin, $allowedOrigins) ) {
    header('Access-Control-Allow-Origin: ' . $httpOrigin);
    header('Access-Control-Allow-Credentials: true');
    craft()->userSession->loginByUserId(1);
    $crossDomainAccess = TRUE;
  }
}

Explanation of the code:

As you can see I set the locales to en and nl. Because that's the only locales for my website.

$locales = array('en','nl');

The domains that are allowed to communicate with each other are set in the general config file under siteUrl. See step 4 of the localization guide for more information.
We will fetch them here and put them in an array for checking.

$allowedOrigins = array();
foreach ( $locales as $locale ) {
    $allowedOrigins[] = craft()->config->getLocalized('siteUrl', $locale);
}

We check the origin of the request and if it's allowed to communicate with this domain. If so, then set the header to allow cross-domain access.

And automatically login as the admin user to get full access for the preview page to load as if you are logged in on the other domain.

$httpOrigin = $_SERVER['HTTP_ORIGIN'];
if ( in_array($httpOrigin, $allowedOrigins) ) {
    header('Access-Control-Allow-Origin: ' . $httpOrigin);
    header('Access-Control-Allow-Credentials: true');
    craft()->userSession->loginByUserId(1);
    $crossDomainAccess = TRUE;
}

Next we need to logout the admin user on the other domain. Add the following code:

if ( $crossDomainAccess == TRUE ) {
  craft()->userSession->logout();
}

Before the line (In the same function, public function actionPreviewEntry()):

$this->_showEntry($entry);

And that's it. A quickfix for anyone that has come across this problem and wants to fix it quick but dirty for now.

Note: If you update your craft cms, then this code will get deleted, so you have to add it again after you updated.

If you're using baseCpUrl

Slight modification if you're using the baseCpUrl setting and/or have paths in your settings file:

if ( !craft()->userSession->isLoggedIn() ) {

  // Get allowed origins
  $allowedOrigins = array(
          parse_url(craft()->config->get('baseCpUrl'), PHP_URL_HOST),
          parse_url(craft()->config->getLocalized('siteUrl', 'en_us'), PHP_URL_HOST)
  );

  // Check origin and give access if allowed
  $httpOrigin = parse_url($_SERVER['HTTP_ORIGIN'], PHP_URL_HOST);
  if ( in_array($httpOrigin, $allowedOrigins) ) {
          header('Access-Control-Allow-Origin: ' . $_SERVER['HTTP_ORIGIN']);
          header('Access-Control-Allow-Credentials: true');
          craft()->userSession->loginByUserId(1);
          $crossDomainAccess = TRUE;
  }
}

Here I've hard-coded the language in, but it can be combined with the answer above instead.


Testing "if" against multiple segments Got myself into a seemingly simple dead-end block with twig syntax. I need to test against multiple items:

{% set segment1 = craft.request.firstSegment %}
{% if segment1 == 'one OR two OR three' %}
DO SOMETHING
{% endif %}

What's going wrong with this bit 'one OR two OR three'? brackets?

You've just got quotes wrapped around a simple string. Try something like this instead...

{% if segment1 in ['one','two','three'] %}

That will check to see if your segment1 value is in the array of possible matches.


Perform inclusive relatedTo query with multiple categories in Craft 2.5+ I'm trying to to display entries related to "all" the given categories instead of "any" using the updated relatedTo method provided in Craft 2.5.

In a related question, @BrandonKelly explains how to do this in the "Updated" portion of his answer. However, I still seem to be getting "any" behavior instead of entries matching "all" categories.

Here is an example URL if only one category in the Social Services group is selected

http://website.com/technologies/someSocialService

Here is an example URL if additional technology categories are also added:

http://website.com/technologies/someSocialService?type[]=88&type[]=117

So, ideally, I want to first filter the entries by the social service category, determined by segment 2 in the URL.

Then, I want to filter even further if there are types of technology in the URL.

Here is my code:

{% set slug = craft.request.getSegment(2) %}
{% set socialServiceCategory = craft.categories.group('socialServices').slug(slug).first() %}
{% set socialServiceCategoryId = socialServiceCategory.id %}

{% set technologyCategoryIds = [] %}
{% if craft.request.getParam('type') %}
{% set technologyCategoryIds = technologyCategoryIds|merge(craft.request.getParam('type')) %}
{% endif %}

{% set categoryIds = [socialServiceCategoryId]|merge(technologyCategoryIds) %}

{% set entries = craft.entries({
    section: 'solutions',
    relatedTo: {
        targetElement: ['and']|merge(categoryIds)
    }
}).order('listingType desc', 'title asc') %}

When the page loads with only the segment slug, and no query string, I get entries filtered by that category. However, once I add one or more technology IDs to the categoryIds array, I get all entries matching "any" categories in the categoryIds array.

Given a URL such as the 2nd example I displayed above, here is a dump of my categoryIds output:

array(3) { [0]=> string(2) "15" [1]=> string(2) "88" [2]=> string(3) "117" }

...which contains exactly the right categories I'd like to inclusively relate my entries to.

For the time being, I was able to get this working the way I need with pre-Craft 2.5 beta syntax for relatedTo using the following code:

{% set entries = entries.relatedTo(socialServiceCategoryId).order('listingType desc', 'title asc') %}

{% if technologyCategoryIds|length %}
{% set entries = entries.relatedTo(
    'and',
    { targetElement: socialServiceCategoryId },
    { targetElement: technologyCategoryIds|join(',') }
).order('listingType desc', 'title asc') %}
{% endif %}

Some of the unexpected behavior here ended up being due to a bug in the new 2.5 relatedTo syntax. It was fixed in Craft 2.5.2724 Beta.


Help with an Entries field to an array I can use elsewhere I have an Entries field so I can select a number of posts to feature in a "Hero" section on the home page, as well as a "most popular" section underneath it.
However, the Hero posts keep showing up in this section, so I'd like to exclude them from the query.
Is there a way I can get the array of entry id's from the Hero section and insert it into the popular query?
Am using the Trendin Posts plugin (https://github.com/madebyraygun/trending-posts) to get the popular posts.
{% set entries = craft.entries().section('news').limit('4').orderBy('popular').all() %}

and I would like...
{% set entries = craft.entries().section('news').limit('4').orderBy('popular').id('not', {array of IDs from Hero}).all() %}

At the same time as you are iterating over your Hero posts, you could populate an array that you could then use in your most popular query.
This is just sudo code but hopefully you get the idea:
{# This would go before your hero loop #}
{# Initiate a heroIds array starting with not #}
{% set heroIds = ['not'] %}

{% for entry in heroEntries %}
    {# Add  heroEntries id to your heroIds array #}
    {% set heroIds = heroIds | merge([entry.id]) %}

    {# the rest of your code... #}
{% endfor %}

{# Then you can use this array in your most popular query #}
{% set entries = craft
    .entries()
    .section('news')
    .limit('4')
    .orderBy('popular')
    .id(heroIds)
    .all() %}


Global-only fields adding columns to content table? I understand the rationale of adding one column per custom field to the craft_content table in the database; but why would this happen for fields that are only used once globally?

Is there a way to define global fields without adding to the entire content table?

Perhaps a better option would be to define a single "Options" matrix field which can be used anywhere, and then use that to store zero-or-more options?

A field is a field, no matter where you are using it. It doesn't matter to Craft whether you attach your field to a Global Set or a Section (or Users or Assets)... All fields are treated equally.

Your fields can be shared between Element Types, and often are.


Business Logic Controller for Validating Address in Commerce I am putting together my Business Logic plugin, as I want to validate the address fields throughout the checkout process of my Cart. I understand in order to do this I need to create a plugin and us the Craft Commerce commerce_addresses.onBeforeSaveAddress event.

I decided to try and use the https://github.com/lindseydiloreto/craft-businesslogic as a starting place.

My code is as follows;

public function init()
{
    craft()->on('commerce_addresses.onBeforeSaveAddress', function(Event $event){
        $address = $event->params['address'];

        if (empty($address->firstName))
        {
            $address->addError('firstName', Craft::t('Please enter your Name'));
             $event->performAction = false;
        }

        if (empty($address->address1))
        {
            $address->addError('address1', Craft::t('Please enter an Address'));
            $event->performAction = false;
        }

        if (empty($address->city))
        {
            $address->addError('city', Craft::t('Please enter your Town/City'));
            $event->performAction = false;
        }

        if (empty($address->zipCode))
        {
            $address->addError('zipCode', Craft::t('Please enter your Post Code'));
            $event->performAction = false;
        }

        if (empty($address->countryId))
        {
            $address->addError('countryId', Craft::t('Please select your Country'));
            $event->performAction = false;
        }
    });
}

If I have this code inside my to level plugin file named BusinessLogicPlugin.php it seems to work and it validates some of the fields as specified.

However, if I move this code into the controllers folder inside /controllers/BusinessLogicController.php it doesn't.

I am unsure what I need to do to move this out of the main/top level file, as I see this file getting very logon/messy if I need to add several 'business logics' to the site.

Can anyone shed light on this as to why it might not work within /controllers/

Thanks.

You can move it all into a Service and then call it from your main plugin file if you find it is getting unwieldy.

file: craft/plugins/businesslogic/BusinessLogicPlugin.php:

class BusinessLogicPlugin extends BasePlugin
{
    public function init()
    {
        craft()->on('commerce_addresses.onBeforeSaveAddress', function(Event $event)
        {
            craft()->businessLogic_events->onBeforeSaveAddress($event);
        });
    }
}

file: craft/plugins/businesslogic/services/BusinessLogic_EventsService.php:

class BusinessLogic_EventsService extends BaseApplicationComponent
{
    public function onBeforeSaveAddress(Event $event)
    {
        $address = $event->params['address'];

        if (empty($address->firstName))
        {
            $address->addError('firstName', Craft::t('Please enter your Name'));
            $event->performAction = false;

            // ...
        }
    }
}

Because $event is an object it will be passed by reference, and you don't need to return anything.


URL rewrite not working For some reason the CraftCMS URL rewrite is not working on GoDaddy shared hosting server.

Currently by .htaccess file looks like this

Options +FollowSymLinks -Multiviews
<IfModule mod_rewrite.c>
   RewriteEngine On
   # Send would-be 404 requests to Craft
   RewriteCond %{REQUEST_FILENAME} !-f
   RewriteCond %{REQUEST_FILENAME} !-d
   RewriteCond %{REQUEST_URI} !^/(favicon\.ico|apple-touch-icon.*\.png)$ [NC]
   RewriteRule (.+) index.php?p=$1 [QSA,L]
</IfModule>

Has anyone encountered this problem? Can someone help me solve this?

Update

I am not sure any more if this a url rewrite problem. As when I access an entry such as http://aspaceboydream.com/comic/so-this-is-me, it loads correctly. But when I use the function:

url('comic')

to construct the urls of the different channels, the URLs are being constructed as http://aspaceboydream.com/index.php?p=comic

I solved the problem and am writing it down for future people encountering the same problem.

Add the following configuration to the your craft/config/general.php config file:

'omitScriptNameInUrls' => true

URLs will start to work fine.


Getting session Id in twig template Is there a way to get the session id from craft.session in a twig template without needing to create a new filter?

Old post, I know, but we've recently published a plugin to achieve this for a similar problem we were facing.

SessionExposer plugin can help you achieve this. To get the Session ID in the template you use

{{ craft.sessionExposer.sessionId }}


Using setExpires on returnJson From a custom plugin controller, I am returning data as json using $this->returnJson($data). I need to be able to set the Cache-Control headers for my forward cache proxy to handle caching correctly.

I tried using HeaderHelper::setExpires(300), but JsonHelper::sendJsonHeaders(), which is called by $this->returnJson() from the controller, overrides setExpires by calling HeaderHelper::setNoCache().

Does anyone have any ideas for working around this or configuring returnJson? I can do the following in my controller (or create a helper of my own):

HeaderHelper::setExpires(300);
HeaderHelper::setContentTypeByExtension('json');
ob_start();
echo JsonHelper::encode($return);
craft()->end();

but I'd rather use the super convenient returnJson function.

If you're running Craft CMS 2.6.2783, you can pass in an 'expires' key to the optional $options 2nd parameter of returnJson with the value set to the time in seconds that will be passed to the cache control expiration headers.  If you ignore it, it will have the current behavior of not caching at all.


calculating average ratings from a series of review fields I've setup a section for reviews with several fields as numbers for a rating 0-5, I'm trying to figure out how to get the total of all reviews and sum of all reviews to provide a single average for an entry the reviews relate to.

What's the best approach to this.

Example of my fields:

Value
Condition
Reception
etc

all graded 0-5 (number fields).

So how to go through the foreach and get the sum of all fields from all reviews then divide by total reviews for the related entry to get the average for each field.

Something like this should work:

{% set reviews = craft.entries.section('reviews').relatedto(entry) %}
{% set value = 0 %}
{% set condition = 0 %}
{% set reception = 0 %}
{% set count = 0 %}
{% for review in reviews %}
    {% set value = value + review.value %}
    {% set condition = condition + review.condition %}
    {% set reception = reception + review.reception %}
    {% set count = loop.index %}
{% endfor %}
{% set averageValue = (value / count)|round(1, 'floor') %}
{% set averageCondition = (condition / count)|round(1, 'floor') %}
{% set averageReception = (reception / count)|round(1, 'floor') %}


Handling path to assets (css, js) between local and production environment How do you guys handle different paths between local and production environments regarding css and js files in your template twig files?

I am following the tutorials of nystudio107, which are simply awesome but can't see how this is be solved even in his pre-ready and configured craft3 download packages.

For example, in local dev I'd like to keep the css and js files separated from each other and unminified for better debugging. On production the files are combined and minified with gulp and moved to a /dist/css – /dist/js folder, which then does not matches the layout path I set in the twig files. Do you ran into similar problems and use a performant solution or do you hardcode the paths to the files on production environment?

If you are using Craft 3 Multi-Environment then you can add environment specific aliases to those assets in your general config file.

Eg:

// Live (production) environment
'live' => [
    // Craft defined config settings
    'allowUpdates' => false,
    'backupOnUpdate' => false,
    'devMode' => false,
    'enableTemplateCaching' => true,
    'isSystemOn' => true,
    // Aliases parsed in sites’ settings, volumes’ settings, and Local
    volumes’ settings
    'aliases' => [
      '@assetPath' => '/dist/'
    ],
    // Custom site-specific config settings
    'custom' => [

    ]
],

Then, in your templates you can use {{ alias('@assetPath/js/' }}.

Note, while I've called the alias assetPath, you can name it anything you like.


Apply inline styles to selected text in Redactor I'm aware, that this question is a little bit out of scope to Craft, but It relates, when redactor is part of Craft.

I was playing around and I must tell, that it's horrible to create a text with  redactor. Especially, if you need insert a htmlTag within paragraph.

In myredactor.json file all formatting features are set according to documentation, but I found out, that redactor by default, doesn't support highlighting text, only through API

Update

Example: Here at stackexchange, you can highlight text to code or bold or ...etc. in very lovely and clever way. To do it in redactor by highlighting text and selecting a type format from dropdown menu, imposible ... yet.

All of Redactor's default Formatting Styles are block elements. But you can add your own styles to it by making use of the newish formattingAdd setting. There's an example editor on the Imperavi website where they added multiple custom styles to it. Some of them are inline styles (try the style "Big Red" for example).

One thing to note here is that it adds the format to the existing ones. To prevent your style from doing so you have to add clear: true to your style settings.

formattingAdd: [
  {
    tag: 'span',
    title: 'Normal inline text',
    clear: true
  },
  {
    tag: 'span',
    title: 'Big Red',
    style: 'font-size: 20px; color: red;',
    class: 'span-big-red',
    clear: true
  },
]

Update: I just tried to remove inline styles by applying my "Normal inline text" style to it and it first seemed not to work. But then I did a new text selection that spanned a greater portion of text and it worked. That's a good sign, but still no real solution.

As Imperavi didn't respond to previous Email I wrote them (not sure if it's because we, Craft users, are not direct customers of them?), I am going to ask P&T to make them aware of this bug.


Impossible to invoke a method ("limit") on an array I recently upgraded a site from Craft 2 to Craft 3, so I'm trying to figure out what was deprecated and caused this error.

At the top of the page I have this

{% set solutions = craft.entries.section('solutions').level(1).all() %}

And I'm trying to invoke a dropdown menu like so

    {% nav solution in solutions.limit(1) %}
        solutions(current)
    {% endnav %}

        {% nav solution in solutions %}

                {{ solution.title }}

        {% endnav %}

Before I didn't have .all() at the end, but only the first menuitem was showing up.
When I added .all() in, I get the error "Impossible to invoke a method ("limit") on an array."

craft.entries now returns an ElementQuery. When you add the .all() you're telling Craft to execute the query, which returns an array of Elements.

That means that solutions is now a simple array, and won't have methods like .limit(1) that can be executed on it. It looks like you just want to use the first item in the solutions array, so try changing this:

      {% nav solution in solutions.limit(1) %}
           solutions(current)
      {% endnav %}

To this:

       solutions(current)

More here: {% nav %} Tags


How to make a sortable table in frontend? I need to display a sortable table of organization member records in frontend, preferably with pagination. Before I start coding this from scratch, I want to ask:
Does anyone have some ideas on how to do this, and what Craft/Yii/plugin functionality I could use to accomplish this?

I'm fairly new to Craft, so at the moment I don't know where to start looking.

Some more details
I'm writing a frontend customer portal plugin, that uses the built in Craft functionality for handling user registration/login/etc. On top of that I've added a MyPlugin_UserRecord and a MyPlugin_OrganizationRecord record, with some service functionality to handle those.

The MyPlugin_UserRecord can be either a private user by it self, or belong to an organization as a member, and it's the latter that I want to display in the table.

Below you can see the relations I have defined:

UserRecord (Craft)

MyPlugin_OrganizationRecord
    'craft_user' => array(static::BELONGS_TO, 'UserRecord', 'craft_user_id'),
    'members' => array(static::HAS_MANY, 'MyPlugin_UserRecord', 'organization_id'),

MyPlugin_UserRecord
    'craft_user' => array(static::BELONGS_TO, 'UserRecord', 'craft_user_id'),
    'organization' => array(static::BELONGS_TO, 'MyPlugin_OrganizationRecord', 'organization_id'),

I can think of a couple ways to pull this off but Craft has many of the pieces already in place.

I'd create a new Channel, name it Organizations. You can add whatever fields you want in there (like address, city, etc.)
To leverage Craft's relations,  create a new field (Organization) that relates back to the Organization channel you just created and add it to the user's profile.

That's the information architecture bit. It'd be up to you how you want to collect the information. Maybe when a user registers for their account for the first time, you'd ask for details.

Then in a custom plugin, you'd probably want to validate to make sure the organization entry didn't already exist before creating a new entry in Organizations channel. Then set the relationship of that newly created entry to the User.

The great thing about Craft is the UI is up to you. So you might use any number of table sorting plugins.

Craft can even handle the Pagination for you. I think DataTables does ajax pagination out of the box, so your Twig template could just need to feed it the data.