From beca8fb63d02ef8a56a8ae158e2897950beffaf6 Mon Sep 17 00:00:00 2001 From: Jacob Parnell Date: Tue, 2 May 2023 18:27:52 -0500 Subject: [PATCH 01/30] Change namespace in sample Atom feed to HTTP Feed parsers expect the namespace to use HTTP and will not read the feed if the namespace uses HTTPS. --- docs/_downloads/sample-atom.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/_downloads/sample-atom.txt b/docs/_downloads/sample-atom.txt index 28eb2c882..7539c8380 100755 --- a/docs/_downloads/sample-atom.txt +++ b/docs/_downloads/sample-atom.txt @@ -4,7 +4,7 @@ {exp:rss:feed channel="{master_channel_name}"} - + <![CDATA[{channel_name}]]> @@ -39,4 +39,4 @@ -{/exp:rss:feed} \ No newline at end of file +{/exp:rss:feed} From ec674068c703128f7b71b21a31945755df720d32 Mon Sep 17 00:00:00 2001 From: Yuri Salimovskiy Date: Wed, 11 Oct 2023 11:45:58 +0300 Subject: [PATCH 02/30] {exp:channel:field} tag --- docs/channels/fields.md | 79 +++++++++++++++++++++ docs/toc_sections/_the_fundamentals_toc.yml | 3 +- 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 docs/channels/fields.md diff --git a/docs/channels/fields.md b/docs/channels/fields.md new file mode 100644 index 000000000..a1c41e397 --- /dev/null +++ b/docs/channels/fields.md @@ -0,0 +1,79 @@ + + +# Channel Field Tag + +[TOC] + +## Overview + +`{exp:channel:field}` tag allows displaying properties of [channel field](control-panel/field-manager/edit-field.md) irrespective of the context. + + {exp:channel:field field_name="department"} +

Choose {field_label}:

+ {field_options} +

{value}: {label}

+ {/field_options} + + {/exp:channel:field} + +## Parameters + +### `field_id=` + + field_id="2" + +Specify field ID. It is required to have either field_id or field_name parameter. If both are specified, field_id will be used. + +### `field_name=` + + field_name="body" + +Specify field name. It is required to have either field_id or field_name parameter. + +### `site_id=` + + site_id="2" + +By default, the tag is looking for fields that are set up for current MSM site. If you need to display properties of field that belongs to other MSM site, you need to specify site_id parameter. + + +## Variables + +[TOC=3] + +### `{field_id}` + +Field ID + +### `{field_name}` + +Field name + +### `{field_label}` + +Field label + +### `{field_instructions}` + +Field instructions for the CP + +### `{field_type}` + +Field type + +### `{field_options}` + +Tag pair that contains possible field options. It is used for fields like Radio Buttons, Checkboxes, Select Dropdown, etc. + +Inside the tag pair you can use `{value}` and `{label}` variables: + + {field_options} + {value} / {label} + {/field_options} \ No newline at end of file diff --git a/docs/toc_sections/_the_fundamentals_toc.yml b/docs/toc_sections/_the_fundamentals_toc.yml index 18effcaef..80f7dad36 100644 --- a/docs/toc_sections/_the_fundamentals_toc.yml +++ b/docs/toc_sections/_the_fundamentals_toc.yml @@ -211,6 +211,8 @@ href: channels/channel-form/categories.md - name: Development href: channels/channel-form/development.md + - name: Channel Field Properties + href: channels/fields.md #If you update fieldtypes besure to update listing on fieldtypes/overview page. - name: Fieldtypes @@ -313,4 +315,3 @@ href: comment/subscriptions.md - name: Control Panel href: comment/control-panel.md - From 71d482c0482a6b9cb8d6d454bb393996274e7d21 Mon Sep 17 00:00:00 2001 From: Yuri Salimovskiy Date: Tue, 5 Dec 2023 16:00:03 +0200 Subject: [PATCH 03/30] Fix Fluid Field hooks info coloses https://github.com/ExpressionEngine/ExpressionEngine/issues/1643 --- .../extension-hooks/model/fluid-field.md | 23 +++++++------------ docs/development/models/fluid-field.md | 6 ++++- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/docs/development/extension-hooks/model/fluid-field.md b/docs/development/extension-hooks/model/fluid-field.md index a477b612c..dd98b1f60 100644 --- a/docs/development/extension-hooks/model/fluid-field.md +++ b/docs/development/extension-hooks/model/fluid-field.md @@ -19,9 +19,9 @@ lang: php | Parameter | Type | Description | | ---------------- | ------------ | ----------------------------------------------------------------------- | -| \$data | `FluidField` | Current instance of ExpressionEngine\Addons\FluidField\Model\FluidField | -| \$fluid_field_id | `Array` | The MemberField model object data as an array | -| Returns | `FluidField` | Current instance of ExpressionEngine\Addons\FluidField\Model\FluidField | +| \$data | `FieldData` | Instance of ExpressionEngine\Model\Content\FieldData for fluid field | +| \$fluid_field_id | `Int` | The ID of Fluid field being fetched | +| Returns | `FieldData` | Current instance of ExpressionEngine\Model\Content\FieldData | Called before the fluid field field object is returned. @@ -29,29 +29,26 @@ How it's called: ee()->extensions->call('fluid_field_get_all_data', $data, $fluid_field_id); -TIP: **New in version 6.1.0.** - -### `fluid_field_add_field($field_table_name, $values)` +### `fluid_field_add_field($field_table_name, $values, $fluid_field)` | Parameter | Type | Description | | ------------------ | ------------ | ----------------------------- | | \$field_table_name | `String` | Name of Fluid field table | | \$values | `Array` | The current field values | +| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | | Returns | `Array` | Adjusted field values | Called before the fluid field is inserted. Changes made to the object will be saved automatically. How it's called: - ee()->extensions->call('fluid_field_add_field', $field_table_name, $values); - -TIP: **New in version 6.1.0.** + ee()->extensions->call('fluid_field_add_field', $field_table_name, $values, $fluid_field); ### `fluid_field_update_field($fluid_field, $field_table_name, $values)` | Parameter | Type | Description | | ------------------ | ------------ | ----------------------------------------------------------------------- | -| \$fluid_field | `FluidField` | Current instance of ExpressionEngine\Addons\FluidField\Model\FluidField | +| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | | \$field_table_name | `String` | Name of table being changed | | \$values | `Array` | The current field values | | Returns | `Array` | Adjusted field values | @@ -62,13 +59,11 @@ How it's called: ee()->extensions->call('fluid_field_add_field', $field_table_name, $values); -TIP: **New in version 6.1.0.** - ### `fluid_field_remove_field($fluid_field)` | Parameter | Type | Description | | ------------------ | ------------ | ----------------------------------------------------------------------- | -| \$fluid_field | `FluidField` | Current instance of ExpressionEngine\Addons\FluidField\Model\FluidField | +| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | | Returns | `null` | | Called before the fluid field is deleted. Field will be deleted after hook is called @@ -76,5 +71,3 @@ Called before the fluid field is deleted. Field will be deleted after hook is ca How it's called: ee()->extensions->call('fluid_field_remove_field', $fluid_field); - -TIP: **New in version 6.1.0.** \ No newline at end of file diff --git a/docs/development/models/fluid-field.md b/docs/development/models/fluid-field.md index 0430bb459..81f91e35a 100644 --- a/docs/development/models/fluid-field.md +++ b/docs/development/models/fluid-field.md @@ -15,6 +15,8 @@ lang: php **class `ExpressionEngine\Addons\FluidField\Model\FluidField`** +This model is used to manipulate custom field which is being used inside a Fluid Field for certain Channel Entry. + [TOC] ## Properties @@ -22,6 +24,7 @@ lang: php - `id` Key - `fluid_field_id` - `entry_id` +- `field_group_id` - `field_id` - `field_data_id` - `order` @@ -29,7 +32,8 @@ lang: php ## Relationships - `ChannelEntry` -- `ChannelFields` +- `ChannelField` +- `ChannelFieldGroup` - `FieldField` ## Methods From 69c8bf5625a420e96765960adbfefb8901f566e5 Mon Sep 17 00:00:00 2001 From: Yuri Salimovskiy Date: Tue, 12 Dec 2023 11:58:38 +0200 Subject: [PATCH 04/30] further modifications suggested by @litzinger --- .../extension-hooks/model/fluid-field.md | 80 +++++++++++++++---- 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/docs/development/extension-hooks/model/fluid-field.md b/docs/development/extension-hooks/model/fluid-field.md index dd98b1f60..00fd6c7c5 100644 --- a/docs/development/extension-hooks/model/fluid-field.md +++ b/docs/development/extension-hooks/model/fluid-field.md @@ -15,19 +15,36 @@ lang: php [TOC=3] -### `fluid_field_get_all_data($data, $fluid_field_id)` +### `fluid_field_get_all_data($data, $fluid_field_id, $fluid_field)` -| Parameter | Type | Description | -| ---------------- | ------------ | ----------------------------------------------------------------------- | -| \$data | `FieldData` | Instance of ExpressionEngine\Model\Content\FieldData for fluid field | -| \$fluid_field_id | `Int` | The ID of Fluid field being fetched | -| Returns | `FieldData` | Current instance of ExpressionEngine\Model\Content\FieldData | +| Parameter | Type | Description | +| ---------------- | ------------ | ------------------------------------------------------------------------- | +| \$data | `FieldData` | Instance of ExpressionEngine\Model\Content\FieldData for fluid field | +| \$fluid_field_id | `Int` | The ID of Fluid field being fetched | +| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | +| Returns | `FieldData` | Current instance of ExpressionEngine\Model\Content\FieldData | -Called before the fluid field field object is returned. +Called after field data has been fetched and before the fluid field field object is returned. How it's called: - ee()->extensions->call('fluid_field_get_all_data', $data, $fluid_field_id); + ee()->extensions->call('fluid_field_get_all_data', $data, $fluid_field_id, $fluid_field); + +### `fluid_field_get_field_data($data, $fluid_field_id, $field_data_id, $fluid_field)` + +| Parameter | Type | Description | +| ---------------- | ------------ | ------------------------------------------------------------------------- | +| \$data | `FieldData` | Instance of ExpressionEngine\Model\Content\FieldData for fluid field | +| \$fluid_field_id | `Int` | The ID of Fluid field being fetched | +| \$field_data_id | `Int` | The ID of row of field data racord | +| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | +| Returns | `Array` | Data for the field in Fluid that's currently fetched | + +Called before field data is fetched. When hook is present, the field data will not be fetched from the database. + +How it's called: + + ee()->extensions->call('fluid_field_get_all_data', $data, $fluid_field_id, $field_data_id, $fluid_field); ### `fluid_field_add_field($field_table_name, $values, $fluid_field)` @@ -44,14 +61,30 @@ How it's called: ee()->extensions->call('fluid_field_add_field', $field_table_name, $values, $fluid_field); +### `fluid_field_after_add_field($fluid_field, $field_table_name, $values, $id)` + +| Parameter | Type | Description | +| ------------------ | ------------ | ----------------------------- | +| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | +| \$field_table_name | `String` | Name of table being changed | +| \$values | `Array` | The current field values | +| \$id | `Int` | The ID of field that was added | +| Returns | `Void` | Does not return any data | + +Called after the fluid field is inserted. + +How it's called: + + ee()->extensions->call('fluid_field_after_add_field', $fluid_field, $field_table_name, $values, $id); + ### `fluid_field_update_field($fluid_field, $field_table_name, $values)` -| Parameter | Type | Description | -| ------------------ | ------------ | ----------------------------------------------------------------------- | +| Parameter | Type | Description | +| ------------------ | ------------ | ------------------------------------------------------------------------- | | \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | -| \$field_table_name | `String` | Name of table being changed | -| \$values | `Array` | The current field values | -| Returns | `Array` | Adjusted field values | +| \$field_table_name | `String` | Name of table being changed | +| \$values | `Array` | The current field values | +| Returns | `Array` | Adjusted field values | Called before the fluid field is updated. Changes made to the object will be saved automatically. @@ -59,12 +92,27 @@ How it's called: ee()->extensions->call('fluid_field_add_field', $field_table_name, $values); +### `fluid_field_after_update_field($fluid_field, $field_table_name, $values)` + +| Parameter | Type | Description | +| ------------------ | ------------ | ------------------------------------------------------------------------- | +| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | +| \$field_table_name | `String` | Name of table being changed | +| \$values | `Array` | The current field values | +| Returns | `Void` | Does not return any data | + +Called after the fluid field has been updated. + +How it's called: + + ee()->extensions->call('fluid_field_add_field', $fluid_field, $field_table_name, $values); + ### `fluid_field_remove_field($fluid_field)` -| Parameter | Type | Description | -| ------------------ | ------------ | ----------------------------------------------------------------------- | +| Parameter | Type | Description | +| ------------------ | ------------ | ------------------------------------------------------------------------- | | \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | -| Returns | `null` | | +| Returns | `null` | | Called before the fluid field is deleted. Field will be deleted after hook is called From 125ed73d24fbb645959b3a9c9ade7d463988215e Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Tue, 18 Jun 2024 11:02:34 -0400 Subject: [PATCH 05/30] Document fluid field group changes from EE PR 4030 --- docs/fieldtypes/fluid.md | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/docs/fieldtypes/fluid.md b/docs/fieldtypes/fluid.md index e6d7c885b..d03d72c83 100755 --- a/docs/fieldtypes/fluid.md +++ b/docs/fieldtypes/fluid.md @@ -61,8 +61,8 @@ For example, if you have a Fluid field `fluid_content` with a text field `fluid_ The prefixed tag pair is a looping tag pair. You can have more than one `fluid_text` field for the entry, it's entirely at the entry author's discretion. The author also determines the order of the field output. -Displaying field groups from within Fluid field is slightly different, as it requires additions `{fields}` tag pair. -So given that `blog` is the short name of custom field group and `fluid_header` and `fluid_text` are fields in that group, the template might look like: +Displaying field groups from within Fluid field is slightly different, as it uses a `{fields}` tag pair to loop through fields within the field group. The order of fields within the loop defaults to the same order of the fields within the field group. You may reverse this order by using `{fields order="desc"}` or specify a different order with `{fields fixed_order="field_2|field_1"}`. +So given that `blog` is the short name of our custom field group and `fluid_header` and `fluid_text` are fields in that group, the template might look like: {fluid_content} @@ -79,6 +79,18 @@ So given that `blog` is the short name of custom field group and `fluid_header` {/fluid_content} +ExpressionEngine 7.5 introduces the ability to access fields from a field group without the use of a `{fields}` loop. +The field name must be prefixed by the group's short_name and placed within the group tag like this: + + {fluid_content} + + {fluid_content:blog} +

{blog:fluid_header}

+
{blog:fluid_text}
+ {/fluid_content:blog} + + {/fluid_content} + ## Variables TIP: **Tip:** When using any of these [tags with a parameter in a conditional](templates/conditionals.md#embedding-tags) you will have to wrap them in braces (`{}`), like so: `{if {fluid_content:first name="text_body"}}` @@ -181,13 +193,13 @@ Additionally, the following variable are available **when using custom field gro {fluid_content:count_in_group} -The "count" out of the fields being displayed in a field group. If five fields are in a group, then for the fourth field the `count` variable would have a value of "4". +The "count" out of the fields being displayed in a field group. If five fields are in a group, then for the fourth field the `count` variable would have a value of "4". ### `first_in_group` {fluid_content:first_in_group} -True, if the current field is the first one in the current field group. +True, if the current field is the first one in the current field group. ### `index_in_group` @@ -441,7 +453,7 @@ Radio and single select fields use single variables: {/my_fluid_field:my_relationship} {/my_fluid_field} -### RTF Text and Textare Fields +### RTF Text and Textarea Fields {my_fluid_field} {my_fluid_field:my_textarea} From 7e19d0e090099dfb0be40a3080b7dbf1bedc9465 Mon Sep 17 00:00:00 2001 From: robinsowell Date: Wed, 3 Jul 2024 16:14:59 -0400 Subject: [PATCH 06/30] Added docs for cp menu cloning --- docs/control-panel/settings/menu-manager.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/control-panel/settings/menu-manager.md b/docs/control-panel/settings/menu-manager.md index c27ea16c2..30c6070b5 100755 --- a/docs/control-panel/settings/menu-manager.md +++ b/docs/control-panel/settings/menu-manager.md @@ -19,7 +19,7 @@ You may create multiple menu sets and assign them to show for specific member ro **Control Panel Location: `Settings > Menu Sets`** -This section of the Control Panel allows you to define your menu sets and assign them to member roles. +This section of the Control Panel allows you to define your menu sets and assign them to member roles. Existing menus can be duplicated by choosing "Clone to New Menu Set" from an existing menu's "Save" dropdown. ### Fields From bccfc7202302c24e09000bf9ede95252cf0467a0 Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Mon, 8 Jul 2024 11:49:59 -0400 Subject: [PATCH 07/30] Add missing div to exp:channel:field example --- docs/channels/fields.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/channels/fields.md b/docs/channels/fields.md index a1c41e397..8849d0417 100644 --- a/docs/channels/fields.md +++ b/docs/channels/fields.md @@ -16,7 +16,8 @@ `{exp:channel:field}` tag allows displaying properties of [channel field](control-panel/field-manager/edit-field.md) irrespective of the context. {exp:channel:field field_name="department"} -

Choose {field_label}:

+
+

Choose {field_label}:

{field_options}

{value}: {label}

{/field_options} From faa84fefd2c4e7b5847a9c07598c40f7ec2245d7 Mon Sep 17 00:00:00 2001 From: Matt Johnson Date: Fri, 23 Aug 2024 14:30:55 -0500 Subject: [PATCH 08/30] Add a note about it being supported in the channel entries loop as a single tag, no params. --- docs/fieldtypes/notes.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/fieldtypes/notes.md b/docs/fieldtypes/notes.md index 854c9eaad..7c3731b56 100644 --- a/docs/fieldtypes/notes.md +++ b/docs/fieldtypes/notes.md @@ -9,7 +9,7 @@ # Notes Fieldtype -Notes is a fieldtype that contains text used to give context to content editors. It cannot be edited in a channel entry and is only there for informational purposes. +Notes is a fieldtype that contains text used to give context to content editors. It cannot be edited in a channel entry and is only there for informational purposes. ![notes field](_images/notes.png) @@ -28,4 +28,5 @@ This is the content that will appear as a note on the publish form. Markdown for ## Template Tag -Usage of notes is not supported in templates. +The note contents can be displayed in a channel:entries loop using a single variable. + From 01caa1a091a21bf6192ebc993520ce713624d97f Mon Sep 17 00:00:00 2001 From: Travis Smith Date: Fri, 30 Aug 2024 16:28:20 -0500 Subject: [PATCH 09/30] Update email.md ee()->email->set_wordwrap and ee()->email->set_mailtype --- docs/development/legacy/libraries/email.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/docs/development/legacy/libraries/email.md b/docs/development/legacy/libraries/email.md index 5cac2e05c..4916ce120 100755 --- a/docs/development/legacy/libraries/email.md +++ b/docs/development/legacy/libraries/email.md @@ -30,8 +30,9 @@ The Email class will automatically create all email headers and will process the ee()->load->library('email'); ee()->load->helper('text'); - ee()->email->wordwrap = true; - ee()->email->mailtype = 'text'; + ee()->email->set_wordwrap(TRUE); + ee()->email->set_mailtype('html'); + ee()->email->from($from); ee()->email->to($recipient); ee()->email->subject($email_subject); @@ -212,7 +213,7 @@ Returns a string containing any server messages, the email headers, and the emai | \$clear_attachments | `Boolean` | If set to `TRUE` attachments will be cleared out, otherwise they're left alone. | | Returns | `Object` | Email class object | -Clears out all parameters set either by property or method: +Clears out all the message-specific parameters set either by property or method (text, recipient, subject, etc.), but not including the overall parameters like the charset, wordwrap, mailtype, and the sending method (smtp, etc.): ee()->email->clear(); @@ -223,8 +224,8 @@ If you are sending multiple emails in a method either for notifications or becau ee()->load->library('email'); ee()->load->helper('text'); - ee()->email->wordwrap = true; - ee()->email->mailtype = 'text'; + ee()->email->set_wordwrap(TRUE); + ee()->email->set_mailtype('html'); $errors = array(); foreach($member_emails as $username => $from) From 023d09a084504363ee3fffef09a9a26b9f3f60ac Mon Sep 17 00:00:00 2001 From: Travis Smith Date: Wed, 4 Sep 2024 17:40:37 -0500 Subject: [PATCH 10/30] Update date-variable-formatting.md A little text tweaking about singular usage --- docs/templates/date-variable-formatting.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/templates/date-variable-formatting.md b/docs/templates/date-variable-formatting.md index ea6acf29d..9f1308a1d 100755 --- a/docs/templates/date-variable-formatting.md +++ b/docs/templates/date-variable-formatting.md @@ -228,7 +228,7 @@ Would be rendered like this: #### singular= -The `singular=` parameter determines what text to display when the value of a given unit is 1. The default is "one". For example, assuming a date 1 day in the past this: +The `singular=` parameter determines what text to display when the value of a given unit is 1. The default is "one", as in, "one hour ago", and notice that all singular units have the plural "s" removed automatically. For example, assuming a date 1 day in the past this: {entry_date:relative singular="1"} @@ -248,7 +248,7 @@ Or perhaps you would rather show relative dates until midnight: {entry_date:relative stop="tomorrow" format="%F %d %Y" timezone="Pacific/Tahiti"} -If an invalid value is used for `stop=` a relative date will be displayed. +If an invalid value is used for `stop=` a relative date will be displayed in all cases. #### units= @@ -270,6 +270,8 @@ Would be rendered like this: one week ago +Note that the plural "s" is automatically removed because it's a single week. + But this: {entry_date:relative units="days"} From 60b7253eba3bc955c010d9db786ee70dcaa788ab Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Tue, 10 Sep 2024 13:03:00 -0400 Subject: [PATCH 11/30] Add documentation for form validation in templates --- docs/_tips/form-validation.md | 1 + docs/add-ons/email.md | 4 +- docs/comment/form.md | 8 +- docs/development/legacy/libraries/output.md | 75 ++++++++++++++++ docs/member/edit-profile.md | 21 +++++ docs/member/forgot-password.md | 48 ++++------- docs/member/forgot-username.md | 45 +++------- docs/member/login.md | 28 +++++- docs/member/memberlist.md | 36 ++------ docs/member/registration.md | 10 ++- docs/member/reset-password.md | 49 ++++------- docs/templates/form-validation.md | 96 +++++++++++++++++++++ docs/templates/globals/single-variables.md | 31 ++++++- docs/toc_sections/_the_fundamentals_toc.yml | 4 +- 14 files changed, 320 insertions(+), 136 deletions(-) create mode 100644 docs/_tips/form-validation.md create mode 100644 docs/templates/form-validation.md diff --git a/docs/_tips/form-validation.md b/docs/_tips/form-validation.md new file mode 100644 index 000000000..b6936d17c --- /dev/null +++ b/docs/_tips/form-validation.md @@ -0,0 +1 @@ +TIP: **Tip:** This form utilizes template [form validation and error handling](/templates/form-validation.md). Refer to the documentation for additional parameters and variables that are available to this tag. \ No newline at end of file diff --git a/docs/add-ons/email.md b/docs/add-ons/email.md index 3afec336c..63f28efe4 100755 --- a/docs/add-ons/email.md +++ b/docs/add-ons/email.md @@ -52,6 +52,8 @@ The contact form is created similar to a standard web form, only you **do not**

{/exp:email:contact_form} +{{embed:_tips/form-validation.md}} + ## Parameters [TOC=3] @@ -330,7 +332,7 @@ In the above example, the Template "friend" contains the Tell-a-Friend form. [TOC=3] ### `allow_attachments=` - + allow_attachments="yes" This allows you to add a file input field to your form, make sure to give your file input field the name of `attachment`. Adding this parameter automatically gives the form the `enctype='multipart/form-data'` attribute. diff --git a/docs/comment/form.md b/docs/comment/form.md index 6b7c13751..5c4ea7098 100755 --- a/docs/comment/form.md +++ b/docs/comment/form.md @@ -35,7 +35,7 @@ The comment submission form is created very similar to a standard web form, only - + {!-- required to prevent EE from outputting form if commenting is disabled or expired --} {if comments_disabled}Comments on this entry are currently disabled.{/if} {if comments_expired}Commenting on this entry has expired.{/if} @@ -46,6 +46,8 @@ This form should be placed on a "single-entry" type page such as a comments page TIP: **Tip:** Notice the variables in the "value" form fields? These allow us to show the user's information in the form automatically if they click the "remember personal info" option. +{{embed:_tips/form-validation.md}} + ## Comment Form Tag ### Parameters @@ -227,11 +229,11 @@ A request for an edit will return a response array. In the case of an error, an ### Editing Permissions -By using the [{if editable}](/comment/entries.html#if-editable) conditional in the Comment Entries tag, you can output a link, instructions or a form if the viewing member has permission to edit the comment, and by using the {if can_moderate_comment} you can display whatever is appropriate if the viewing member has permission to moderate (close) the comment. +By using the [{if editable}](/comment/entries.md#if-editable) conditional in the Comment Entries tag, you can output a link, instructions or a form if the viewing member has permission to edit the comment, and by using the {if can_moderate_comment} you can display whatever is appropriate if the viewing member has permission to moderate (close) the comment. For members without administrative access, in order to edit a comment they must be logged in, the author of the comment, and the editing time limit must not have expired. If a member has a role with permission to edit the comments of any entry, that member will have edit permissions regardless of the editing time limit. -Comment moderators may close the comment. The edit time limit does not apply to moderators. +Comment moderators may close the comment. The edit time limit does not apply to moderators. Superadmins will always have {editable} and {can_moderate_comment} permissions on any comment. diff --git a/docs/development/legacy/libraries/output.md b/docs/development/legacy/libraries/output.md index b34f7f88c..f2b5e5aac 100755 --- a/docs/development/legacy/libraries/output.md +++ b/docs/development/legacy/libraries/output.md @@ -195,3 +195,78 @@ $output = array( 'message' => 'not allowed', ); ee()->output->send_ajax_response($output, true); + +### `show_message($data, $xhtml = true, $redirect_url = false, $template_name = 'generic')` + +| Parameter | Type | Description | +| --------------- | -------- | ------------------------------------------------------------------------------------------ | +| \$data | `Array` | Data to be sent to the view. Explained below | +| \$xhtml | `Bool` | Parse the content as HTML | +| \$redirect_url | `String` | URL to redirect to instead of showing the message | +| \$template_name | `String` | Specialty template to use. Defaults to `generic` which is equivalent of `message_template` | +| Returns | `Void` | void | + +Show user message using [system message template](control-panel/template-manager.md#system-message-templates) or [custom template](control-panel/template-manager.md#custom-system-messages). This is used on front-end, for instance, when we need to inform the user about successful form submission. + +When `$redirect_url` is provided, the user will be redirected to that URL instead of showing the message. + +The `$data` parameter is an associative array with the following keys: + - `title` - HTML titles of message page + - `heading` - heading text + - `content` - main content + - `redirect` - URL to automatically redirect to after showing message + - `rate` - time in seconds after which the redirect happens + - `link` - the link to include in the message. Should be in the format of `array($link_url, $link_text)` + +Example: + + $data = array( + 'title' => 'Title', + 'heading' => 'Heading', + 'content' => 'Content', + 'redirect' => 'http://example.com', + 'rate' => 5, + 'link' => array('http://example.com', 'Link Text') + ); + ee()->output->show_message($data); + +### `show_user_error($type = 'submission', $errors = '', $heading = '', $redirect_url = '')` + +| Parameter | Type | Description | +| --------------- | -------- | ------------------------------------------------------------------------------------------ | +| \$type | `String` | Type of error. Defaults to `submission`, can also be `general` or `off` | +| \$errors | `Mixed` | Error message or array of messages to display. | +| \$heading | `String` | Heading text. Legacy, not used, set automatically based on type. | +| \$redirect_url | `String` | URL to redirect to instead of showing the message | +| Returns | `Void` | void | + +Show user an error message using [system message template](control-panel/template-manager.md#system-message-templates) or [custom template](control-panel/template-manager.md#custom-system-messages). This is used on front-end, for instance, when a form is submitted without the required info. + +When `$redirect_url` is provided, the user will be redirected to that URL instead of showing the message. Useful when the form is set to [handle errors inline](templates/globals/single-variables.md#error-variables). + + $return_error_link = ee()->functions->determine_error_return(); + ee()->output->show_user_error('submission', $errors, '', $return_error_link); + +### `show_form_error($errors, $type = 'general')` + +| Parameter | Type | Description | +| --------------- | -------- | ------------------------------------------------------------------------------------------ | +| \$errors | `Mixed` | Array of error messages or instance of \ExpressionEngine\Service\Validation\Result | +| \$type | `String` | Type of error. Defaults to `general`, can also be `submission` or `off` | +| Returns | `Void` | void | + +Handle displaying errors for a form either passed as a Validation Result or an array of errors. If the form is using +inline error handling the errors and old input will be flashed to the session otherwise they will be displayed with the +appropriate template. + +### `show_form_error_aliases($errors = '', $aliases = [], $type = 'general')` + +| Parameter | Type | Description | +| --------------- | -------- | --------------------------------------------------------------------------------------------- | +| \$errors | `Mixed` | Array of error messages or instance of \ExpressionEngine\Service\Validation\Result | +| \$aliases | `Array` | Array of aliases to use, i.e. ['input_id_1' => ['field' => 'input_name', 'label' => 'Input']] | +| \$type | `String` | Type of error. Defaults to `general`, can also be `submission` or `off` | +| Returns | `Void` | void | + +This function builds upon `show_form_error()` with the additional ability to provide aliases for input names so +that variable names used in inline error handling can be more meaningful i.e. `field_name` instead of `field_id_1`. \ No newline at end of file diff --git a/docs/member/edit-profile.md b/docs/member/edit-profile.md index 194018434..11996ac8c 100644 --- a/docs/member/edit-profile.md +++ b/docs/member/edit-profile.md @@ -17,6 +17,8 @@ This template tag allows editing a member's profile using the form that is similar to [Channel Form](channels/channel-form/overview.md). Please note however that not all Channel Form parameters and template tags are available in the Member Profile form, so make sure to consult the documentation below. The form can only be used to update profile of the member that is currently logged in. +{{embed:_tips/form-validation.md}} + ## Parameters {{embed:_tips/form-attributes.md}} @@ -194,6 +196,7 @@ Short name of the fieldtype used for field {exp:member:edit_profile return="member/registration/success" include_assets="yes" + inline_errors="yes" datepicker="yes" } @@ -204,27 +207,42 @@ Short name of the fieldtype used for field



+ {if error:username} + {error:username} + {/if}



+ {if error:email} + {error:email} + {/if}


+ {if error:password} + {error:password} + {/if}


+ {if error:password_confirm} + {error:password_confirm} + {/if}


You must enter your current password to change your password, username or email. + {if error:current_password} + {error:current_password} + {/if}

@@ -235,6 +253,9 @@ Short name of the fieldtype used for field {form:custom_profile_field} + {if has_error} + {error} + {/if}

{/custom_profile_fields} diff --git a/docs/member/forgot-password.md b/docs/member/forgot-password.md index be0bfe65e..707162e26 100644 --- a/docs/member/forgot-password.md +++ b/docs/member/forgot-password.md @@ -24,16 +24,18 @@ Output a forgotten password form that sends an email with instructions for reset {/exp:member:forgot_password_form} - + NOTE: **Note:** This form will only email the user if the user requesting the password reset is not currently logged in. +{{embed:_tips/form-validation.md}} + ## Parameters ### `email_template=` email_template="member/email-password-reset" -Template to use for email which is sent to user. +Template to use for email which is sent to user. NOTE: **Note:** If no template is defined, the default [Member Profile Template](control-panel/template-manager.md#member-profile-templates) for a forgotten password will be used. @@ -66,47 +68,27 @@ Member email address. This is a **required** field: - - -## Variable Pairs - -### `{errors}` - -Form submission errors are displayed using a "looping pair" as there can be more than 1 error in a form submission. - - {errors} -

{error}

- {/errors} - -#### Error Tag Pair Parameters - -##### `backspace=` - - backspace="3" - -The `backspace=` parameter will remove characters, including spaces and line breaks, from the last iteration of the tag pair. - -#### Error Tag Pair Variables - -##### `{error}` - - {error} - -The error text. - - - ## Example {exp:member:forgot_password_form return="member/forgot-password/sent" + inline_errors="yes" password_reset_url="member/reset-password" email_template="member/email-password-reset" } + {if errors} +
+ Errors + {errors} +

{error}

+ {/errors} +
+ {/if} +


- +

diff --git a/docs/member/forgot-username.md b/docs/member/forgot-username.md index 7da35a676..8cf71e447 100644 --- a/docs/member/forgot-username.md +++ b/docs/member/forgot-username.md @@ -24,6 +24,8 @@ Output a forgotten username form that sends an email with instructions for addre {/exp:member:forgot_username_form} +{{embed:_tips/form-validation.md}} + ## Parameters ### `email_subject=` @@ -37,7 +39,7 @@ Subject of email sent to user. email_template="member/email-forgot-username" -Template to use for email which is sent to user. +Template to use for email which is sent to user. If no template is defined or if the template defined does not exist, the default [Member Profile Template](control-panel/template-manager.md#member-profile-templates) for a forgotten username will be used. @@ -59,46 +61,27 @@ Member email address. This is a **required** field: - - -## Variable Pairs - -### `{errors}` - -Form submission errors are displayed using a "looping pair" as there can be more than 1 error in a form submission. - - {errors} -

{error}

- {/errors} - -#### Error Tag Pair Parameters - -##### `backspace=` - - backspace="3" - -The `backspace=` parameter will remove characters, including spaces and line breaks, from the last iteration of the tag pair. - -#### Error Tag Pair Variables - -##### `{error}` - - {error} - -The error text. - - ## Example {exp:member:forgot_username_form return="member/login/forgot-username" + inline_errors="yes" email_subject="Your Username" email_template="member/email-forgot-username" } + {if errors} +
+ Errors + {errors} +

{error}

+ {/errors} +
+ {/if} +


- +

diff --git a/docs/member/login.md b/docs/member/login.md index 6d99cde80..ca8a130da 100644 --- a/docs/member/login.md +++ b/docs/member/login.md @@ -26,6 +26,8 @@ Output a login form. {/exp:member:login_form} +{{embed:_tips/form-validation.md}} + ## Parameters {{embed:_tips/form-attributes.md}} @@ -114,14 +116,36 @@ It is recommended that you use this variable as indicated in the example code at ## Example - {exp:member:login_form return="member/index"} + {exp:member:login_form return="member/index" inline_errors="yes"} + {!-- You can display all errors at the top of the page or use the individual field {error:} tags shown later --} + {!-- + {if errors} +
+ Errors + {errors} +

{error}

+ {/errors} +
+ {/if} + --} + + {if error:general} + {error:general} + {/if} +


- + + {if error:username} + {error:username} + {/if}


+ {if error:password} + {error:password} + {/if}

{if auto_login}

diff --git a/docs/member/memberlist.md b/docs/member/memberlist.md index b80ce2140..f8606a0e6 100644 --- a/docs/member/memberlist.md +++ b/docs/member/memberlist.md @@ -15,6 +15,8 @@ Outputs a searchable list of members, including form filters to sort and limit the members. +{{embed:_tips/form-validation.md}} + ## Parameters {{embed:_tips/form-attributes.md}} @@ -98,7 +100,7 @@ This is a **required** variable in order to use the search form. It creates the ### `{role_options}` -Form submission errors are displayed using a "looping pair" as there can be more than 1 error in a form submission. +A list of options for filtering by member role {order_by_options} @@ -114,7 +116,7 @@ Form submission errors are displayed using a "looping pair" as there can be more ### `{row_limit_options}` -Form submission errors are displayed using a "looping pair" as there can be more than 1 error in a form submission. +A list of options for changing the number of results returned {sort_order_options} @@ -130,32 +132,6 @@ Form submission errors are displayed using a "looping pair" as there can be more ## Variable Pairs -### `{errors}` - -Form submission errors are displayed using a "looping pair" as there can be more than 1 error in a form submission. - - {errors} -

{error}

- {/errors} - -#### Error Tag Pair Parameters - -##### `backspace=` - - backspace="3" - -The `backspace=` parameter will remove characters, including spaces and line breaks, from the last iteration of the tag pair. - -#### Error Tag Pair Variables - -##### `{error}` - - {error} - -The error text. - - - ### `{member_rows}` Data for each member are shown using a "looping pair". diff --git a/docs/member/registration.md b/docs/member/registration.md index 4ce434879..780667659 100644 --- a/docs/member/registration.md +++ b/docs/member/registration.md @@ -17,6 +17,8 @@ Output a member registration form. NOTE: **Important:** In order for site visitors to be allowed to register for accounts via front-end forms the [Allow Registrations](control-panel/settings/members.md#allow-registrations) must be set to allow registrations under Settings > Member Settings. +{{embed:_tips/form-validation.md}} + ## Parameters {{embed:_tips/form-attributes.md}} @@ -136,6 +138,9 @@ Custom fields can also be output inside the ``{custom_fields}`` variable tag pai {form:custom_profile_field} + {if error} + {error} + {/if}

{/custom_fields} @@ -211,7 +216,7 @@ Displays the custom field input form for the given field (substitute `field_name {exp:member:registration_form return="member/registration/success" - error_handling="inline" + inline_errors="yes" }

* Required fields

@@ -259,6 +264,9 @@ Displays the custom field input form for the given field (substitute `field_name {captcha}
+ {if error:captcha} + {error:captcha} + {/if}

{/if} diff --git a/docs/member/reset-password.md b/docs/member/reset-password.md index e19e702d5..68d3d0028 100644 --- a/docs/member/reset-password.md +++ b/docs/member/reset-password.md @@ -28,6 +28,8 @@ Output a reset password form that allows members accessing it via a link from a {/exp:member:reset_password_form} +{{embed:_tips/form-validation.md}} + ## Parameters ### `return=` @@ -47,7 +49,7 @@ NOTE: Be sure to include the required Javascript and CSS to use the native [Pass
-The new password to set. +The new password to set. ### Password Confirmation @@ -57,49 +59,36 @@ The new password to set. Duplicate of the new password set in the password form input. - -## Variable Pairs - -### `{errors}` - -Form submission errors are displayed using a "looping pair" as there can be more than 1 error in a form submission. - - {errors} -

{error}

- {/errors} - -#### Error Tag Pair Parameters - -##### `backspace=` - - backspace="3" - -The `backspace=` parameter will remove characters, including spaces and line breaks, from the last iteration of the tag pair. - -#### Error Tag Pair Variables - -##### `{error}` - - {error} - -The error text. - - - ## Example {exp:member:reset_password_form return="member/login/success" + inline_errors="yes" } + {if errors} +
+ Errors + {errors} +

{error}

+ {/errors} +
+ {/if} +


+ {if error:password} + {error:password} + {/if}


+ {if error:password_confirm} + {error:password_confirm} + {/if}

diff --git a/docs/templates/form-validation.md b/docs/templates/form-validation.md new file mode 100644 index 000000000..8163a12ac --- /dev/null +++ b/docs/templates/form-validation.md @@ -0,0 +1,96 @@ + + +# Form Validation + +[TOC] + +ExpressionEngine provides several template tags that produce interactive forms. When a user submits a form the input is validated and any errors are then shown to the user. The two methods for presenting these errors to your users are through a system error template or by using inline errors in your own custom templates. + +## Error Template + +By default ExpressionEngine will show validation errors to your users with a system template. You can configure the look and feel of this page by using [Custom System Messages](control-panel/template-manager.md#custom-system-messages). + +## Inline Errors + +Alternatively you can show users any validation errors on the same page where they are providing input with inline errors. The following template tags support inline errors and can make use of the following parameters and variables. + +*Supported Template Tags:* + +- [Comment Submission Form](/comment/form.md) `{exp:comment:form}` +- [Email Contact Form](/add-ons/email.md#email-contact-form) `{exp:email:contact_form}` +- [Member Edit Profile](/member/edit-profile.md) `{exp:member:edit_profile}` +- [Member Forgot Password](/member/forgot-password.md) `{exp:member:forgot_password_form}` +- [Member Forgot Username](/member/forgot-username.md) `{exp:member:forgot_username_form}` +- [Member Login](/member/login.md) `{exp:member:login_form}` +- [Member Registration](/member/registration.md) `{exp:member:registration_form}` +- [Member Reset Password](/member/reset-password.md) `{exp:member:reset_password_form}` + +### Parameters + +[TOC=4] + +#### `inline_errors=` + + inline_errors="yes" + +This parameter allows you to use inline errors in your form. The errors can be displayed using the `{errors}` variable pair or individually using the `{error:field_name}` tag (where `field_name` would be replaced with the name of your field). + +#### `return_error=` + + return_error="template_group/error" + +When inline errors are enabled, this parameter allows you to specify the template to return to if there are errors in the form. The default is the same template that the form is on. + +### Variables + +[TOC=4] + +#### Errors Pair + + {errors}...{error}...{/errors} + +When inline errors enabled, this tag pair will display all errors in a loop. Each individual error message is available as an `{error}` variable within the loop. + +This is useful for displaying all errors at once, for example, in a fieldset at the top of the form. It can also be used as a conditional to check if there are any errors at all: `{if errors}`. + + {if errors} +

Please correct the following errors:

+
    + {errors} +
  • {error}
  • + {/errors} +
+ {/if} + +#### Field Error Single + + {error:field_name} + +You can also access an error for a specific field. This can be desirable if you want to show the error next to the input element that was invalid. + +#### Field Value Single + + {old:field_name} + +Retrieve a value for a specific field that was sent during the invalid submission. + +NOTE: **Note:** These values are only flashed to the session for a single request and fields with sensitive names like "password" will not be stored + +### Example Usage + +``` +

+ + + {if error:username} + {error:username} + {/if} +

+``` diff --git a/docs/templates/globals/single-variables.md b/docs/templates/globals/single-variables.md index 47660fc0f..1b7592136 100755 --- a/docs/templates/globals/single-variables.md +++ b/docs/templates/globals/single-variables.md @@ -7,13 +7,13 @@ @license https://expressionengine.com/license Licensed under Apache License, Version 2.0 --> -# Single Global Variables +# Global Variables [TOC] These Global Variables can be used anywhere within your Templates. Note that they are subject to ExpressionEngine's [parsing order](templates/engine.md), which can affect their availability when used inside other tags. -## Variables +## Single Variables [TOC=3 hide] @@ -39,7 +39,7 @@ The active session id for the control panel. This is the value needed in the "S= • CP Link {/if} -NOTE: **Note:** To check non-primary roles, use [exp:member:has_role](/member/member-roles-tags.html#expmemberhas_role) +NOTE: **Note:** To check non-primary roles, use [exp:member:has_role](/member/member-roles-tags.md#expmemberhas_role) ### `{cp_url}` @@ -315,7 +315,7 @@ The Member ID for the currently logged-in user. The Primary Role ID number for the currently logged-in user. -NOTE: **Note:** To check and display non-primary roles, use [exp:member:has_role](/member/member-roles-tags.html#expmemberhas_role) +NOTE: **Note:** To check and display non-primary roles, use [exp:member:has_role](/member/member-roles-tags.md#expmemberhas_role) ### `{logged_in_primary_role_name}` @@ -360,3 +360,26 @@ The total number of forum topics made by the currently logged-in user. ### `{logged_in_username}` The username for the currently logged-in user. + +## Error Variables + +ExpressionEngine makes several variables available for handling [Form Validation](/templates/form-validation.md) errors. + +### `{if errors}` + +Conditionally check if error messages are present. + +### `{errors}...{error}...{/errors}` + +This variable pair is useful for displaying all errors at once, for example, in a fieldset at the top of the form. Inside the pair, each individual error message is available as `{error}` variable. + + {if errors} +

Please correct the following errors:

+
    + {errors} +
  • {error}
  • + {/errors} +
+ {if:else} + + {/if} \ No newline at end of file diff --git a/docs/toc_sections/_the_fundamentals_toc.yml b/docs/toc_sections/_the_fundamentals_toc.yml index a74b7f465..676d19b06 100644 --- a/docs/toc_sections/_the_fundamentals_toc.yml +++ b/docs/toc_sections/_the_fundamentals_toc.yml @@ -142,7 +142,7 @@ href: templates/variable.md - name: Global Template Variables items: - - name: Single Global Variables + - name: Global Variables href: templates/globals/single-variables.md - name: Linking to Stylesheets href: templates/globals/stylesheet.md @@ -164,6 +164,8 @@ href: templates/routes.md - name: Pagination href: templates/pagination.md + - name: Form Validation + href: templates/form-validation.md - name: The Template Engine href: templates/engine.md From 3565bddcad34458e3a0e1df531f384a9b10d86a4 Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Tue, 10 Sep 2024 13:03:59 -0400 Subject: [PATCH 12/30] Resolve warnings for missing links in documentation --- docs/add-ons/pro-search/examples.md | 4 ++-- docs/add-ons/pro-search/filters.md | 8 ++++---- docs/channels/entries.md | 2 +- docs/control-panel/utilities/data-operations.md | 2 +- docs/development/addon-development-overview.md | 4 ++-- docs/development/services/cookie-registry.md | 2 +- docs/installation/changelog.md | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/add-ons/pro-search/examples.md b/docs/add-ons/pro-search/examples.md index 330935542..e69362ea1 100644 --- a/docs/add-ons/pro-search/examples.md +++ b/docs/add-ons/pro-search/examples.md @@ -280,7 +280,7 @@ Below is a list of radio buttons, one for each letter of the alphabet. Selecting Below is a list of checkboxes based on a custom channel field of the Checkboxes type. You can select multiple options from this list. Entries will be shown that have any of the selected options checked. Uses [Low Options](https://github.com/EEHarbor/low_options) to generate field options. -Adding `contains_words="parameter_name"` to the Results tag will ensure that the selected items are not contained within other words, like appending `\W` to the values. +Adding `contains_words="parameter_name"` to the Results tag will ensure that the selected items are not contained within other words, like appending `\W` to the values. {exp:pro_search:form query="{segment_3}"} {exp:low_options:service_options} @@ -503,7 +503,7 @@ Below are two lists of tags. You can select multiple tags per list. Entries that ## Other & Native -In addition to what all the [filters](/add-ons/pro-search/filters.md) bring to the party, you can also filter by native ExpressionEngine parameters, as well as some [little extras](/add-ons/pro-search/tags.md#results-tag). +In addition to what all the [filters](/add-ons/pro-search/filters.md) bring to the party, you can also filter by native ExpressionEngine parameters, as well as some [little extras](/add-ons/pro-search/tags.md#exppro_searchresults). ### Orderby and sort in one go diff --git a/docs/add-ons/pro-search/filters.md b/docs/add-ons/pro-search/filters.md index a0dca61a9..9f806b694 100644 --- a/docs/add-ons/pro-search/filters.md +++ b/docs/add-ons/pro-search/filters.md @@ -95,7 +95,7 @@ The automatic `keywords:mode` uses operators in keywords for any/all/exact match ### Singulars & Plurals -Pro Search supports singular and plural matching of keywords [inflections](http://en.wikipedia.org/wiki/Inflection). To enable this, both the `keywords:inflect` and the `keywords:lang` parameters must be set. Pro Search supports English inflections natively and you can add support for other languages by adding inflection rules to your [Config file](/general/system_configuration_overrides.md): +Pro Search supports singular and plural matching of keywords [inflections](http://en.wikipedia.org/wiki/Inflection). To enable this, both the `keywords:inflect` and the `keywords:lang` parameters must be set. Pro Search supports English inflections natively and you can add support for other languages by adding inflection rules to your [Config file](/general/system-configuration-overrides.md): ``` $config['pro_search_inflection_rules'][lang] = array( @@ -110,7 +110,7 @@ $config['pro_search_inflection_rules'][lang] = array( ### Stems -Pro Search supports matching of keywords by their stem [stemming](http://en.wikipedia.org/wiki/Stemming). To enable this, both the `keywords:stem` and the `keywords:lang` parameters must be set. English stemming is supported natively, using a [Porter stemmer](http://tartarus.org/martin/PorterStemmer/) class, and you can add support for other languages by adding this to your [Config file](/general/system_configuration_overrides.md): +Pro Search supports matching of keywords by their stem [stemming](http://en.wikipedia.org/wiki/Stemming). To enable this, both the `keywords:stem` and the `keywords:lang` parameters must be set. English stemming is supported natively, using a [Porter stemmer](http://tartarus.org/martin/PorterStemmer/) class, and you can add support for other languages by adding this to your [Config file](/general/system-configuration-overrides.md): ``` $config['pro_search_stemmers'][lang] = array( @@ -154,7 +154,7 @@ You can use the Distance filter to limit results by a given maximum distance. Th NOTE: **Note:** Use two separate fields instead of a single one for better performance. ### Variables -The Distance filter also makes this variable available in the [Results tag](/add-ons/pro-search/tags#results-tag): +The Distance filter also makes this variable available in the [Results tag](/add-ons/pro-search/tags.md#exppro_searchresults): #### `{pro_search_distance}` The calculated distance in the given unit for this entry. @@ -163,7 +163,7 @@ NOTE: **Note:** Using the Distance filter will return the search results ordered ## Field Search -You can use the native `search:field_name` parameter to target specific fields. Additionally, Pro Search can target the entry’s ***title***, ***url_title***, ***status***, target [Grid](/fieldtypes/grid.md) columns, use multiple values for [numeric matching](/channel/channel_entries.md#numeric-matching) (in combination with the `gt`, `gte`, `lt` and `lte` params), and use ***starts / ends with*** matching. +You can use the native `search:field_name` parameter to target specific fields. Additionally, Pro Search can target the entry’s ***title***, ***url_title***, ***status***, target [Grid](/fieldtypes/grid.md) columns, use multiple values for [numeric matching](/channels/entries.md#numeric-matching) (in combination with the `gt`, `gte`, `lt` and `lte` params), and use ***starts / ends with*** matching. ### Parameters diff --git a/docs/channels/entries.md b/docs/channels/entries.md index 4a02a4585..63ea5400b 100755 --- a/docs/channels/entries.md +++ b/docs/channels/entries.md @@ -893,7 +893,7 @@ The "count" out of the current entries being displayed. If five entries are bein Edit Entry {/if} -The URL of the entry form in the control panel where this entry can be edited. It is recommended you wrap this variable in an `{if logged_in}` conditional to hide your control panel's URL from regular site visitors. If you are running a membership-based site, hide it behind an appropriate `logged_in_primary_role_id` conditional or use [exp:member:has_role](/member/member-roles-tags.html#expmemberhas_role). For example, to hide this link from everyone but Super Admins: +The URL of the entry form in the control panel where this entry can be edited. It is recommended you wrap this variable in an `{if logged_in}` conditional to hide your control panel's URL from regular site visitors. If you are running a membership-based site, hide it behind an appropriate `logged_in_primary_role_id` conditional or use [exp:member:has_role](/member/member-roles-tags.md#expmemberhas_role). For example, to hide this link from everyone but Super Admins: {if logged_in_primary_role_id == 1} Edit Entry diff --git a/docs/control-panel/utilities/data-operations.md b/docs/control-panel/utilities/data-operations.md index 16428d4e4..00fb88fac 100644 --- a/docs/control-panel/utilities/data-operations.md +++ b/docs/control-panel/utilities/data-operations.md @@ -59,7 +59,7 @@ Run this utility to convert all files stored in the database from sites previous It is recommended that you make sure all installed add-ons are compatible with ExpressionEngine 7 and newer, and that you have made a backup of your database before running the utility. -After the update operation is completed, visit `Content & Design Settings` to disable [Compatibility Mode](control-panel/file-manager/file-manager.html#compatibility-mode) for File Manager. +After the update operation is completed, visit `Content & Design Settings` to disable [Compatibility Mode](control-panel/file-manager/file-manager.md#compatibility-mode) for File Manager. ## Manage Statistics diff --git a/docs/development/addon-development-overview.md b/docs/development/addon-development-overview.md index 88746112f..376b6e413 100644 --- a/docs/development/addon-development-overview.md +++ b/docs/development/addon-development-overview.md @@ -11,7 +11,7 @@ With custom add-ons you can add new fieldtypes, features, template tags, and much more to ExpressionEngine. Here we are going to look at different parts of an add-on, and how to define just what our add-on is going to do. -TIP: In this section, we're explaining the parts of an add-on. No need to memorize everything though, the [CLI](cli/intro.html) will generate all the pieces we need based on what functions we want our add-on to have. +TIP: In this section, we're explaining the parts of an add-on. No need to memorize everything though, the [CLI](cli/intro.md) will generate all the pieces we need based on what functions we want our add-on to have. [TOC] @@ -32,7 +32,7 @@ Here are some ideas of what you can accomplish with a custom add-on: These are just a few ideas of what you can do with custom add-ons. The possibilities are almost endless. ## Getting Started -Getting started making an add-on is incredibly easy with the CLI. To begin making an add-on, simply use the [`make:addon` command](/cli/built-in-commands/make-addon.md) from the [CLI](/cli/intro.html). +Getting started making an add-on is incredibly easy with the CLI. To begin making an add-on, simply use the [`make:addon` command](/cli/built-in-commands/make-addon.md) from the [CLI](/cli/intro.md). TIP: If you are working with an existing add-on, we recommend you start with [Modernizing add-ons](development/modernizing-existing-add-ons.md) diff --git a/docs/development/services/cookie-registry.md b/docs/development/services/cookie-registry.md index fd0c095c0..becea2312 100644 --- a/docs/development/services/cookie-registry.md +++ b/docs/development/services/cookie-registry.md @@ -15,7 +15,7 @@ For the cookies set in ExpressionEngine, site owners can set the cookie lifetime `CookieRegistry` is the underlying service that makes saving and using those settings possible. -NOTE: Normally, the add-ons that have their cookies properly [registered](development/addon-setup-php-file.html#cookies) do not need to call this service directly. +NOTE: Normally, the add-ons that have their cookies properly [registered](development/addon-setup-php-file.md#cookies) do not need to call this service directly. ## Cookie Registry Constants diff --git a/docs/installation/changelog.md b/docs/installation/changelog.md index 741862653..ce8365c9b 100755 --- a/docs/installation/changelog.md +++ b/docs/installation/changelog.md @@ -1825,6 +1825,6 @@ NOTE:**Note:** If multiple members are needed, an ExpressionEngine Pro license i - Simple Commerce Add-on has now been removed from ExpressionEngine and made a downloadable add-on from the ExpressionEngine Store. On upgrades which use the Simple Commerce Add-on, the add-on will be moved from the `ee/addons` folder to `user/addons` and considered a user installed add-on. - Ip to Nation Add-on has now been removed from ExpressionEngine and made a downloadable add-on from the ExpressionEngine Store. On upgrades which use the Ip to Nation Add-on, the add-on will be moved from the `ee/addons` folder to `user/addons` and considered a user installed add-on. - The included version of jQuery used in the Control Panel has been updated to v3.6.0 - - Added the option to [globally cache](/channels/entries.html#cache-refresh-cache_prefix) Channel Entries tag results + - Added the option to [globally cache](/channels/entries.md#cache-refresh-cache_prefix) Channel Entries tag results - Added [ENV File Support](/advanced-usage/env-support.md) - Added new Shared Form View From 832e205cd420b901ce6287932ca1c9a076392a6c Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Mon, 7 Oct 2024 15:20:56 -0400 Subject: [PATCH 13/30] Add documentation for Template Generators feature --- docs/_images/cp-template-generators.png | Bin 0 -> 151997 bytes .../services/template-generator.md | 230 ++++++++++++++++++ docs/templates/generators.md | 96 ++++++++ docs/toc_sections/_advanced_usage_toc.yml | 10 +- docs/toc_sections/_the_fundamentals_toc.yml | 2 + 5 files changed, 334 insertions(+), 4 deletions(-) create mode 100644 docs/_images/cp-template-generators.png create mode 100644 docs/development/services/template-generator.md create mode 100644 docs/templates/generators.md diff --git a/docs/_images/cp-template-generators.png b/docs/_images/cp-template-generators.png new file mode 100644 index 0000000000000000000000000000000000000000..cb3b33ee1c7fe383ad58e86910cca1fe207fc3d0 GIT binary patch literal 151997 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℞n1X5Je!e84 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 + +# Template Generator Service + +The `TemplateGenerator` Service is responsible for registering and creating template generators. + +[TOC] + +## Template Generator Anatomy + +Template Generators were created to help users accelerate the process of building templates. If you have an Add-on that provides template tags or fieldtypes it may be beneficial to include a template generator as well. + +In its simplest form a template generator is a PHP class file that extends +`ExpressionEngine\Service\TemplateGenerator\AbstractTemplateGenerator`. This file needs to be placed in a `TemplateGenerators` folder within your add-on's folder. The name you give your generator should also be used as the class name and the file name. + +Template generators need to be registered in your `addon.setup.php` file, under a +`templateGenerators` array that should contain a list of your generator names e.g. + +```php + 'ExpressionEngine', + 'author_url' => 'https://expressionengine.com/', + 'name' => 'Channel', + 'description' => '', + 'version' => '2.1.0', + 'namespace' => 'ExpressionEngine\Addons\Channel', + 'settings_exist' => true, + 'templateGenerators' => array( + 'Entries', + ) +); +``` + +When properly defined your template generator will be available to select as long as your add-on is currently installed. We do not display generators for uninstalled add-ons to avoid confusion. + +The generator can be accessed through a dropdown when using the Control Panel or by it's key when using the CLI. The generator key consists of the add-on name and generator name separated with a colon. For example the Entries Generator provided by our Channel add-on has a key of `channel:entries`. + +Each generator is required to have a `$name` protected property that is the name of the generator that will be displayed to the user. + +The generator needs to provide a list of templates that it can generate. This is done by declaring a `$templates` protected property that is an associative array of template names and their description (saved as template notes). E.g. + +```php +protected $templates = [ + 'index' => 'Listing for all entries', + 'entry' => 'Entry detail page', +]; +``` + +If you would like to specify a template type other than HTML you can do so with a more verbose syntax where an array is passed as the value with a `description` and `type` for each template: + +```php +protected $templates = [ + 'feed' => ['name' => 'RSS feed for all entries', 'type' => 'feed'], + 'sitemap' => ['name' => 'XML sitemap for all entries', 'type' => 'xml'], +]; +``` + +Every template name in your list of templates must correspond to a [Template Stub](#template-stubs) file. + +A generator can define a list of options that it supports. For instance, we require a channel name in the Channel Entries generator, so we declare the following: + +```php + protected $options = [ + 'channel' => [ + 'title' => 'channel', + 'desc' => 'channel_desc', + 'type' => 'checkbox', + 'required' => true, + 'choices' => 'getChannels', + ], + ]; +``` +The syntax of this array is similar to the one used by Shared Form View. The only difference is that for options of type 'checkbox', 'select' or 'radio' you can populate the `choices` array dynamically by providing a method name or callback that returns an array. + +Each of the options can be validated using the [Validation service](https://docs.expressionengine.com/latest/development/services/validation.html). Specify the validation rules and define any necessary validation functions in the same class. + +```php + protected $_validation_rules = [ + 'channel' => 'validateChannelExists' + ]; +``` + +A template generator must have a `getVariables()` method that returns an associative array of variables. These will be passed to the View service when rendering the stubs. Here is a simple example of how this method might look: + +```php + public function getVariables(): array + { + return [ + 'channel' = implode('|', $this->input->get('channel')) + ]; + } +``` + +## Template Stubs + +Templates are generated from a "stub" file, which is a PHP file parsed though the [View service](https://docs.expressionengine.com/latest/development/services/view.html). + +Add-ons must store their stubs inside a `stubs` directory within the add-on's own folder. Within the `stubs`, the files are stored in a folder that should match the generator name. The stub file name needs to match the template name that will be created. + +So for an `index` template to be created by Channel Entries generator, the stub file must exist in `Addons/channel/stubs/entries/index.php`. + +The Template Generator Service will search several directories in priority order until it finds a match for the specified stub. + +- `system/user/stubs/{addon_name}/{generator_name}` - User override for specific generator stub +- `system/ee/ExpressionEngine/Addons/{addon_name}/stubs/{generator_name}` - (Core/First-Party) Addon's path for specific generator stub +- `system/user/addons/{addon_name}/stubs/{generator_name}` - (Third-Party) Addon's path for specific generator stub +- `system/user/stubs` - User override for generic stub +- `system/ee/templates/stubs` - System fallback for generic stub + +This example illustrates the concrete paths that the Template Generator will search when looking for the Channel Module's Entries Generator: + +- `system/user/stubs/channel/entries` +- `system/ee/ExpressionEngine/Addons/channel/stubs/entries` +- `system/user/stubs` +- `system/ee/templates/stubs` + +In addition to searching these directories for a match the Template Generator will also search for a stub file that matches the generated template's type and engine. This will work in a manner of most specific to least specific. For example if a user requests to generate an XML template called `sitemap` then the Template Generator will search through the paths in order looking for a `sitemap.xml.php` stub and then a `sitemap.php` stub within each path until a match is found. This allows you to customize the output for different template types. + +When running in an environment that introduces additional template engines this search is extended further to include variations for those engines. We can continue the example above and request to a Twig XML template called `sitemap`. Again the Template Generator will look through each path for the following file names until a match is found `sitemap.xml.twig.php`, `sitemap.twig.php`, `sitemap.xml.php`, `sitemap.php`. + +### Includes + +A generator stub differs from traditional View files in the way it handles embedding other stubs. Usually with a view file you would only need to prefix your included file with the add-on name (e.g. `channel:`). But with generator stubs you must use a combination of the add-on name and generator name (e.g. `channel:entries`) - something like `embed('channel:entries:_field_metadata', $vars)`. Embedding a stub for a fieldtype would still only require the add-on name as a prefix though since there is no generator involved (e.g. `$this->embed('grid:field', $vars)`). + +The variables passed to a stub file include the options passed to the generator along with any variables created by the generator, so use the generator documentation and files for reference. + + +## Fieldtype Stubs + +If the generator is utilizing fieldtypes, the template code is built from the stubs that are specific to the fieldtypes. + +The stubs are required to be placed in `stubs` directory within fieldtype's own folder. Remember that they need to have `.php` extension and will be utilizing View service. + +Default name of field stub is `field`. This can be overridden by setting `$stub` property in fieldtype file, e.g. + +``` +class Example_ft extends EE_Fieldtype +{ + public $stub = 'example'; +} +``` + +Fieldtype stubs for form inputs that will be used with `channel:form` generator need to follow the same naming rules but be placed in a `form` subdirectory (e.g. `system/user/addons/my_field/stubs/form/field.php`). + +The approach for finding a Fieldtype stub is similar to how Template Generator stubs are discovered. Directories are searched in priority order until a matching stub is found. An example directory lookup order for the Grid fieldtype might look like this: + +- `system/user/stubs/grid/field.php` +- `system/ee/ExpressionEngine/Addons/grid/stubs/field.php` +- `system/user/stubs/field.php` +- `system/ee/templates/stubs/field.php` + +If the fieldtype does not provide any stubs, a generic `field.php` fallback is used. It is capable of determining whether the fieldtype is designed to work as a single tag or tag pair, but it cannot provide any specific variables to use within the tag pair. + +## Fieldtype Generators + +Some fieldtypes will return different variables depending on their settings. An example of this is the Grid fieldtype which supports different fieldtypes as columns. In order to build a useful template the fieldtype stub will need a list of the field's columns. To get this list of columns and their properties we will need to create a fieldtype generator. + +A fieldtype generator is a PHP class file that extends `ExpressionEngine\Service\TemplateGenerator\AbstractFieldTemplateGenerator`. +The file needs to be placed in `TemplateGenerators` folder within the add-on folder. The file name is arbitrary, but it needs to match the class name declared in the file. + +Fieldtype generators need to be registered by assigning the generator class name to the `templateGenerator` key in the `addon.setup.php` file within the `fieldtypes` array, e.g. + +```php + [ + 'grid' => [ + 'name' => 'Grid', + 'templateGenerator' => 'Grid', + 'compatibility' => 'grid' + ] + ], + ... +]; +``` +### Fieldtype Generator Methods + +**class `ExpressionEngine\Service\TemplateGenerator\AbstractFieldTemplateGenerator`** + +The only method that fieldtypes generator is required to have is `getVariables()`. Is is required to return the associative array of variables that will be passed to View service when rendering the fieldtype stub. + +The example fieldtype generator for the Grid fieldtype that provides a `$columns` variable to the stub file might look like this: + +```php + [] + ]; + + //get the list of columns for this field + foreach ($this->field->GridColumns as $column) { + $fieldtypeGenerator = ee('TemplateGenerator')->getFieldtype($column->col_type); + + $vars['columns']['grid_col_' . $column->col_id] = [ + 'col_type' => $column->col_type, + 'col_name' => $column->col_name, + 'col_label' => $column->col_label, + 'field_type' => $column->col_type, + 'field_name' => $prefix . ':' . $column->col_name, + 'field_label' => $column->col_label, + 'stub' => $fieldtypeGenerator['stub'], + 'docs_url' => $fieldtypeGenerator['docs_url'], + 'is_tag_pair' => $fieldtypeGenerator['is_tag_pair'], + ]; + } + + return $vars; + } +} +``` \ No newline at end of file diff --git a/docs/templates/generators.md b/docs/templates/generators.md new file mode 100644 index 000000000..96d170cdc --- /dev/null +++ b/docs/templates/generators.md @@ -0,0 +1,96 @@ + + +# Template Generators + +[TOC] + +ExpressionEngine provides a set of template generators that allow you to quickly scaffold templates based on your existing data structures (channels, custom fields, etc.). The template generators are available through both the Control Panel and the Command Line Interface (CLI). The generated templates will demonstrate the most common ways of accessing the data and will include comments for each field with links to the appropriate documentation. + +## Control Panel Usage + +Before you can use the template generators you will need to setup your channels and custom fields. Once this is done you can navigate to Templates > Template Generator. + +![ExpressionEngine Control Panel Template Generator](_images/cp-template-generators.png) + +Select the generator that you want along with any available options and then type in a name for the template group that will be created. + +Upon successful generation of new templates you will be brought to the Template Group page so that you may view and modify any of the generated files. + +## Command Line Usage + +You can also generate templates using [ExpressionEngine's Command Line Interface (CLI)](../cli/usage.md). The main CLI command to access all template generators in the system is: `php system/ee/eecli.php generate:templates`. + +To get the list of available template generators, pass the `--list` option to the command: + +```bash +php system/ee/eecli.php generate:templates --list +``` + +To run a specific template generator, pass its full name as the first argument to the command: + +```bash +php system/ee/eecli.php generate:templates channel:entries +``` + +Each template generator can be configured with the following options while some may offer additional input. + +`--template_group="blog"` - The name of the template group which will contain the new templates. Required + +`--template_engine=twig` - When using [Coilpack](https://expressionengine.github.io/coilpack-docs/) multiple template engines are available. This option lets you specify which template engine to use for template generation. The default is native. + +`--site_id=1` - With MSM you may generate templates for a specific site by referencing the Site ID. If your installation has only one site this can be omitted. + +`--templates="all"` - Specify "all" (default) to generate all templates provided by the generator, or specify a comma-separated list of template names that you want. For example: `--templates="index,single"` will only generate the `index` and `single` templates. + +`--show` - When this parameter is specified the template content will be displayed but no templates will be created. + +## Available Template Generators + +### Channel Entries + +The Channel Entries generator creates several templates to list and render entries for the specified channels. + +**Options**: + +- Channel (Required): Select one or more channels that you want to use in templates + +**CLI Usage**: + +```bash +php system/ee/eecli.php generate:templates channel:entries --template_group=news --templates=all --channel=news +``` + +### Channel Form + +The Channel Form generator creates a template utilizing Channel Form tags for a customizable publishing experience. + +**Options**: + +- Channel (Required): Select the channel that you want to use in templates + +**CLI Usage**: + +```bash +php system/ee/eecli.php generate:templates channel:form --template_group=artists --channel=artists +``` + +### Member Management + +The Member Management generator creates a series of templates to help you get started building a custom member experience. + +**CLI Usage**: + +```bash +php system/ee/eecli.php generate:templates member:profile --template_group=members +``` + +## Developer Documentation + +To learn more about having an Add-on integrate with Template Generators check out the [Template Generator Service](development/services/template-generator.md). \ No newline at end of file diff --git a/docs/toc_sections/_advanced_usage_toc.yml b/docs/toc_sections/_advanced_usage_toc.yml index 0e6fb9dfe..07f2ae6cb 100644 --- a/docs/toc_sections/_advanced_usage_toc.yml +++ b/docs/toc_sections/_advanced_usage_toc.yml @@ -394,6 +394,8 @@ href: development/services/spam.md - name: CP/Table Service href: development/services/table.md + - name: Template Generator Service + href: development/services/template-generator.md - name: CP/URL Service href: development/services/url.md - name: Validation Service @@ -679,9 +681,9 @@ - name: Sync Conditional Fields href: cli/built-in-commands/sync-conditional-fields.md - name: Sync Reindex Content - href: cli/built-in-commands/sync-reindex.md + href: cli/built-in-commands/sync-reindex.md - name: Sync Upload Directory - href: cli/built-in-commands/sync-upload-directory.md + href: cli/built-in-commands/sync-upload-directory.md - name: Update ExpressionEngine href: cli/built-in-commands/update.md - name: Prolet Generator @@ -714,9 +716,9 @@ href: msm/overview.md - name: Variables and Parameter href: msm/code.md - + - name: ExpressionEngine + Laravel items: - name: Overview href: advanced-usage/coilpack/overview.md - + diff --git a/docs/toc_sections/_the_fundamentals_toc.yml b/docs/toc_sections/_the_fundamentals_toc.yml index a74b7f465..f85d88380 100644 --- a/docs/toc_sections/_the_fundamentals_toc.yml +++ b/docs/toc_sections/_the_fundamentals_toc.yml @@ -166,6 +166,8 @@ href: templates/pagination.md - name: The Template Engine href: templates/engine.md + - name: Template Generators + href: templates/generators.md - name: Channels items: From b8a5a994564a5971dbabb8f11e567996fa8fe483 Mon Sep 17 00:00:00 2001 From: Brad Akin Date: Tue, 8 Oct 2024 17:08:11 -0400 Subject: [PATCH 14/30] mention that the documentation and comments are optional and a setting --- docs/templates/generators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/templates/generators.md b/docs/templates/generators.md index 96d170cdc..b58d57b32 100644 --- a/docs/templates/generators.md +++ b/docs/templates/generators.md @@ -11,7 +11,7 @@ [TOC] -ExpressionEngine provides a set of template generators that allow you to quickly scaffold templates based on your existing data structures (channels, custom fields, etc.). The template generators are available through both the Control Panel and the Command Line Interface (CLI). The generated templates will demonstrate the most common ways of accessing the data and will include comments for each field with links to the appropriate documentation. +ExpressionEngine provides a set of template generators that allow you to quickly scaffold templates based on your existing data structures (channels, custom fields, etc.). The template generators are available through both the Control Panel and the Command Line Interface (CLI). The generated templates will demonstrate the most common ways of accessing the data. Additionally, the templates have a settings option to also include comments and links to the field's documenation. ## Control Panel Usage From 58bdeb32172c2c453b1e40d1a0baaa841ad6174b Mon Sep 17 00:00:00 2001 From: Matt Johnson Date: Tue, 8 Oct 2024 16:38:20 -0500 Subject: [PATCH 15/30] Update notes.md --- docs/fieldtypes/notes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/fieldtypes/notes.md b/docs/fieldtypes/notes.md index 7c3731b56..2ea306550 100644 --- a/docs/fieldtypes/notes.md +++ b/docs/fieldtypes/notes.md @@ -28,5 +28,5 @@ This is the content that will appear as a note on the publish form. Markdown for ## Template Tag -The note contents can be displayed in a channel:entries loop using a single variable. +The note contents can be displayed in a `{channel:entries}` loop using a single variable. From be45dd41151a7b912fc9c42662a886a480e0ac5f Mon Sep 17 00:00:00 2001 From: Matt Johnson Date: Tue, 8 Oct 2024 16:55:44 -0500 Subject: [PATCH 16/30] Update template-generator.md --- docs/development/services/template-generator.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/development/services/template-generator.md b/docs/development/services/template-generator.md index 53a490a31..d561749c1 100644 --- a/docs/development/services/template-generator.md +++ b/docs/development/services/template-generator.md @@ -9,7 +9,7 @@ # Template Generator Service -The `TemplateGenerator` Service is responsible for registering and creating template generators. +The Template Generators feature automates the creation of structured templates for rapid development. The `TemplateGenerator` Service is responsible for registering and creating template generators. [TOC] @@ -227,4 +227,4 @@ class Grid extends AbstractFieldTemplateGenerator implements FieldTemplateGenera return $vars; } } -``` \ No newline at end of file +``` From 98a698f808eeac15e86d729eae7c01acffc6ce75 Mon Sep 17 00:00:00 2001 From: Matt Johnson Date: Tue, 8 Oct 2024 17:00:42 -0500 Subject: [PATCH 17/30] Update template-generator.md Update template generator wording --- .../services/template-generator.md | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/development/services/template-generator.md b/docs/development/services/template-generator.md index d561749c1..5eab6d4cb 100644 --- a/docs/development/services/template-generator.md +++ b/docs/development/services/template-generator.md @@ -15,10 +15,10 @@ The Template Generators feature automates the creation of structured templates f ## Template Generator Anatomy -Template Generators were created to help users accelerate the process of building templates. If you have an Add-on that provides template tags or fieldtypes it may be beneficial to include a template generator as well. +Template Generators were created to help users accelerate the process of building templates. If you have an Add-on that provides template tags or fieldtypes, it may also be beneficial to include a template generator. -In its simplest form a template generator is a PHP class file that extends -`ExpressionEngine\Service\TemplateGenerator\AbstractTemplateGenerator`. This file needs to be placed in a `TemplateGenerators` folder within your add-on's folder. The name you give your generator should also be used as the class name and the file name. +In its simplest form, a template generator is a PHP class file that extends +`ExpressionEngine\Service\TemplateGenerator\AbstractTemplateGenerator`. This file must be placed in a `TemplateGenerators` folder within your add-ons. The name you give your generator should also be used as the class name and the file name. Template generators need to be registered in your `addon.setup.php` file, under a `templateGenerators` array that should contain a list of your generator names e.g. @@ -40,11 +40,11 @@ return array( ); ``` -When properly defined your template generator will be available to select as long as your add-on is currently installed. We do not display generators for uninstalled add-ons to avoid confusion. +When properly defined, your template generator will be available to select as long as your add-on is currently installed. We do not display generators for uninstalled add-ons to avoid confusion. -The generator can be accessed through a dropdown when using the Control Panel or by it's key when using the CLI. The generator key consists of the add-on name and generator name separated with a colon. For example the Entries Generator provided by our Channel add-on has a key of `channel:entries`. +The generator can be accessed through a dropdown when using the Control Panel or by its key when using the CLI. The generator key consists of the add-on name and generator name separated with a colon. For example, the Entries Generator provided by our Channel add-on has a key of `channel:entries`. -Each generator is required to have a `$name` protected property that is the name of the generator that will be displayed to the user. +Each generator is required to have a `$name` protected property which is the name of the generator that will be displayed to the user. The generator needs to provide a list of templates that it can generate. This is done by declaring a `$templates` protected property that is an associative array of template names and their description (saved as template notes). E.g. @@ -102,11 +102,11 @@ A template generator must have a `getVariables()` method that returns an associa ## Template Stubs -Templates are generated from a "stub" file, which is a PHP file parsed though the [View service](https://docs.expressionengine.com/latest/development/services/view.html). +Templates are generated from a "stub" file, which is a PHP file parsed through the [View service](https://docs.expressionengine.com/latest/development/services/view.html). Add-ons must store their stubs inside a `stubs` directory within the add-on's own folder. Within the `stubs`, the files are stored in a folder that should match the generator name. The stub file name needs to match the template name that will be created. -So for an `index` template to be created by Channel Entries generator, the stub file must exist in `Addons/channel/stubs/entries/index.php`. +So for an `index` template to be created by the Channel Entries generator, the stub file must exist in `Addons/channel/stubs/entries/index.php`. The Template Generator Service will search several directories in priority order until it finds a match for the specified stub. @@ -123,13 +123,13 @@ This example illustrates the concrete paths that the Template Generator will sea - `system/user/stubs` - `system/ee/templates/stubs` -In addition to searching these directories for a match the Template Generator will also search for a stub file that matches the generated template's type and engine. This will work in a manner of most specific to least specific. For example if a user requests to generate an XML template called `sitemap` then the Template Generator will search through the paths in order looking for a `sitemap.xml.php` stub and then a `sitemap.php` stub within each path until a match is found. This allows you to customize the output for different template types. +In addition to searching these directories for a match, the Template Generator will also search for a stub file that matches the generated template's type and engine. This will work in a manner of most specific to least specific. For example, if a user requests to generate an XML template called `sitemap` then the Template Generator will search through the paths in order looking for a `sitemap.xml.php` stub and then a `sitemap.php` stub within each path until a match is found. This allows you to customize the output for different template types. -When running in an environment that introduces additional template engines this search is extended further to include variations for those engines. We can continue the example above and request to a Twig XML template called `sitemap`. Again the Template Generator will look through each path for the following file names until a match is found `sitemap.xml.twig.php`, `sitemap.twig.php`, `sitemap.xml.php`, `sitemap.php`. +When running in an environment that introduces additional template engines, this search is extended further to include variations for those engines. We can continue the example above and request a Twig XML template called `sitemap`. Again the Template Generator will look through each path for the following file names until a match is found `sitemap.xml.twig.php`, `sitemap.twig.php`, `sitemap.xml.php`, `sitemap.php`. ### Includes -A generator stub differs from traditional View files in the way it handles embedding other stubs. Usually with a view file you would only need to prefix your included file with the add-on name (e.g. `channel:`). But with generator stubs you must use a combination of the add-on name and generator name (e.g. `channel:entries`) - something like `embed('channel:entries:_field_metadata', $vars)`. Embedding a stub for a fieldtype would still only require the add-on name as a prefix though since there is no generator involved (e.g. `$this->embed('grid:field', $vars)`). +A generator stub differs from traditional View files in the way it handles embedding other stubs. Usually with a view file, you would only need to prefix your included file with the add-on name (e.g. `channel:`). But with generator stubs, you must use a combination of the add-on name and generator name (e.g. `channel:entries`) - something like `embed('channel:entries:_field_metadata', $vars)`. Embedding a stub for a fieldtype would still only require the add-on name as a prefix though since there is no generator involved (e.g. `$this->embed('grid:field', $vars)`). The variables passed to a stub file include the options passed to the generator along with any variables created by the generator, so use the generator documentation and files for reference. @@ -138,9 +138,9 @@ The variables passed to a stub file include the options passed to the generator If the generator is utilizing fieldtypes, the template code is built from the stubs that are specific to the fieldtypes. -The stubs are required to be placed in `stubs` directory within fieldtype's own folder. Remember that they need to have `.php` extension and will be utilizing View service. +The stubs are required to be placed in `stubs` directory within fieldtype's own folder. Remember that they need to have `.php` extension and will be utilizing the View service. -Default name of field stub is `field`. This can be overridden by setting `$stub` property in fieldtype file, e.g. +The default name of the field stub is `field`. This can be overridden by setting `$stub` property in the fieldtype file, e.g. ``` class Example_ft extends EE_Fieldtype @@ -188,7 +188,7 @@ return [ **class `ExpressionEngine\Service\TemplateGenerator\AbstractFieldTemplateGenerator`** -The only method that fieldtypes generator is required to have is `getVariables()`. Is is required to return the associative array of variables that will be passed to View service when rendering the fieldtype stub. +The only method that the fieldtypes generator is required to have is `getVariables()`. Is is required to return the associative array of variables that will be passed to the View service when rendering the fieldtype stub. The example fieldtype generator for the Grid fieldtype that provides a `$columns` variable to the stub file might look like this: From 8e444eb31a9032b6fcfa89e8fd83d788c818ed3b Mon Sep 17 00:00:00 2001 From: Matt Johnson Date: Tue, 8 Oct 2024 17:09:42 -0500 Subject: [PATCH 18/30] Update generators.md --- docs/templates/generators.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/templates/generators.md b/docs/templates/generators.md index b58d57b32..a00b395ae 100644 --- a/docs/templates/generators.md +++ b/docs/templates/generators.md @@ -11,17 +11,17 @@ [TOC] -ExpressionEngine provides a set of template generators that allow you to quickly scaffold templates based on your existing data structures (channels, custom fields, etc.). The template generators are available through both the Control Panel and the Command Line Interface (CLI). The generated templates will demonstrate the most common ways of accessing the data. Additionally, the templates have a settings option to also include comments and links to the field's documenation. +ExpressionEngine provides a set of template generators that allow you to quickly scaffold templates based on your existing data structures (channels, custom fields, etc.). The template generators are available through both the Control Panel and the Command Line Interface (CLI). The generated templates will demonstrate the most common ways of accessing the data. Additionally, the templates have a settings option to also include comments and links to the field's documentation. ## Control Panel Usage -Before you can use the template generators you will need to setup your channels and custom fields. Once this is done you can navigate to Templates > Template Generator. +Before you can use the template generators you will need to set up your channels and custom fields. Once this is done you can navigate to Templates > Template Generator. ![ExpressionEngine Control Panel Template Generator](_images/cp-template-generators.png) Select the generator that you want along with any available options and then type in a name for the template group that will be created. -Upon successful generation of new templates you will be brought to the Template Group page so that you may view and modify any of the generated files. +Upon successful generation of new templates, you will be brought to the Template Group page so that you may view and modify any of the generated files. ## Command Line Usage @@ -93,4 +93,4 @@ php system/ee/eecli.php generate:templates member:profile --template_group=membe ## Developer Documentation -To learn more about having an Add-on integrate with Template Generators check out the [Template Generator Service](development/services/template-generator.md). \ No newline at end of file +To learn more about having an Add-on integrate with Template Generators check out the [Template Generator Service](development/services/template-generator.md). From c13701ee3aa8619ac06c8358d235f207b69646cc Mon Sep 17 00:00:00 2001 From: robinsowell Date: Wed, 9 Oct 2024 12:03:22 -0400 Subject: [PATCH 19/30] Added in inline error params and alphabetized in a few cases --- docs/add-ons/email.md | 12 +++++ docs/comment/form.md | 57 +++++++++++++++--------- docs/member/edit-profile.md | 53 +++++++++++++--------- docs/member/forgot-password.md | 12 +++++ docs/member/forgot-username.md | 12 +++++ docs/member/login.md | 11 +++++ docs/member/memberlist.md | 81 ++++++++++++++++++++-------------- docs/member/registration.md | 42 ++++++++++-------- docs/member/reset-password.md | 12 +++++ 9 files changed, 196 insertions(+), 96 deletions(-) diff --git a/docs/add-ons/email.md b/docs/add-ons/email.md index 63f28efe4..733afef84 100755 --- a/docs/add-ons/email.md +++ b/docs/add-ons/email.md @@ -66,6 +66,12 @@ The contact form is created similar to a standard web form, only you **do not** This allows you to set the character set of the email being sent. Use this if your form's template is using a character set other than iso-8859-1. +### `inline_errors=` + + inline_errors="yes" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the type of error reporting: inline or error template. + ### `name=` name="myForm" @@ -122,6 +128,12 @@ If used with the redirect="none" parameter, the link text can be specified by ad If the `redirect` parameter was set to value of `return`, then the user will be redirected immediately after submission of the form. +### `return_error=` + + return_error="template_group/error" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the template to return to if validation errors are detected. + ### `preview=` preview="about/contact-preview" diff --git a/docs/comment/form.md b/docs/comment/form.md index 5c4ea7098..73b8d11c8 100755 --- a/docs/comment/form.md +++ b/docs/comment/form.md @@ -56,28 +56,6 @@ TIP: **Tip:** Notice the variables in the "value" form fields? These allow us to {{embed:_tips/form-attributes.md}} -#### `entry_id=` - - entry_id="24" - -You can hard code the comment form tag to display a comment form for a specific channel entry by its entry ID. - -NOTE: **Note:** This parameter takes precedence over any entry specified dynamically in the URL, so when using this parameter you will want to make sure it is clear to the user which entry the displayed comment form belongs to. - -#### `preview=` - - preview="channel/preview" - -This is a **required** parameter if you are using comment previews indicating which template should be used for comment previews. Like other "path" variables in ExpressionEngine you will use the Template Group/Template name. More on previewing can be found in the [Comment Previewing](#comment-previewing) section. - -#### `url_title=` - - url_title="my_wedding" - -You can hard code the comment for tag to display a comment form for a specific channel entry by its URL title. - -NOTE: **Note:** This parameter takes precedence over any entry specified dynamically in the URL, so when using this parameter you will want to make sure it is clear to the user which entry the displayed comment form belongs to. - #### `channel=` channel="news" @@ -88,6 +66,14 @@ If you link to your comment form page using the entry's URL Title, then you are Because you can have the same URL Title in different channels, using this parameter will ensure that the comment submitted will be associated with the correct entry. Without this parameter, it is possible that the comment could be associated with an entry in a different channel that happens to have the same URL Title. +#### `entry_id=` + + entry_id="24" + +You can hard code the comment form tag to display a comment form for a specific channel entry by its entry ID. + +NOTE: **Note:** This parameter takes precedence over any entry specified dynamically in the URL, so when using this parameter you will want to make sure it is clear to the user which entry the displayed comment form belongs to. + #### `form_class=` form_class="news_comment_form" @@ -100,6 +86,19 @@ With this parameter, you can specify the css class you want the form to have, en With this parameter, you can specify the css id you want the form to have. The default value is 'comment_form' + +#### `inline_errors=` + + inline_errors="yes" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the type of error reporting: inline or error template. + +#### `preview=` + + preview="channel/preview" + +This is a **required** parameter if you are using comment previews indicating which template should be used for comment previews. Like other "path" variables in ExpressionEngine you will use the Template Group/Template name. More on previewing can be found in the [Comment Previewing](#comment-previewing) section. + #### `return=` return="template_group/template/url_title" @@ -111,6 +110,20 @@ This parameter allows you to define where the user will be returned after submit If this parameter is not defined, they will be returned to the form page. +#### `return_error=` + + return_error="template_group/error" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the template to return to if validation errors are detected. + +#### `url_title=` + + url_title="my_wedding" + +You can hard code the comment for tag to display a comment form for a specific channel entry by its URL title. + +NOTE: **Note:** This parameter takes precedence over any entry specified dynamically in the URL, so when using this parameter you will want to make sure it is clear to the user which entry the displayed comment form belongs to. + ### Conditionals [TOC=4] diff --git a/docs/member/edit-profile.md b/docs/member/edit-profile.md index 11996ac8c..81689ee59 100644 --- a/docs/member/edit-profile.md +++ b/docs/member/edit-profile.md @@ -23,25 +23,38 @@ This template tag allows editing a member's profile using the form that is simil {{embed:_tips/form-attributes.md}} + ### `datepicker=` -Include the datepicker javascript. This should be set to ``yes`` if there is a date type member custom field in order to output the calendar. + datepicker="no" - datepicker="yes" +Adds the datepicker to your date fields. Defaults to "yes". -### `include_assets=` +NOTE: **Note:** If you are manually constructing a date field, in order to apply the date picker you must include `rel="date-picker"`. - include_assets="yes" +### `form_class=` -Adds the Javascript and CSS that is required by custom member fields to your form. By default, these are **not** included + form_class="login" -### `datepicker=` +This parameter allows you to specify the class attribute for the <form> tag. - datepicker="no" +### `form_id=` -Adds the datepicker to your date fields. Defaults to "yes". + form_id="login" -NOTE: **Note:** If you are manually constructing a date field, in order to apply the date picker you must include `rel="date-picker"`. +This parameter allows you to specify the id attribute for the <form> tag. + +### `form_name=` + + form_name="login" + +This parameter allows you to specify a name attribute for the <form> tag. + +### `include_assets=` + + include_assets="yes" + +Adds the Javascript and CSS that is required by custom member fields to your form. By default, these are **not** included ### `include_css=` @@ -57,27 +70,23 @@ Includes jQuery automatically. Defaults to "yes". NOTE: **Note:** If you are using your own copy of jQuery you will need to load it **before** the form. -### `return=` - - return="member/registration/success" - -### `form_class=` +### `inline_errors=` - form_class="login" + inline_errors="yes" -This parameter allows you to specify the class attribute for the <form> tag. +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the type of error reporting: inline or error template. -### `form_id=` +### `return=` - form_id="login" + return="member/registration/success" + +### `return_error=` -This parameter allows you to specify the id attribute for the <form> tag. + return_error="template_group/error" -### `form_name=` +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the template to return to if validation errors are detected. - form_name="login" -This parameter allows you to specify a name attribute for the <form> tag. ## Form Inputs NOTE: Be sure to include the required Javascript and CSS to use the native [Password Validation](member/password-validation.md). diff --git a/docs/member/forgot-password.md b/docs/member/forgot-password.md index 707162e26..c457c88f2 100644 --- a/docs/member/forgot-password.md +++ b/docs/member/forgot-password.md @@ -39,6 +39,12 @@ Template to use for email which is sent to user. NOTE: **Note:** If no template is defined, the default [Member Profile Template](control-panel/template-manager.md#member-profile-templates) for a forgotten password will be used. +### `inline_errors=` + + inline_errors="yes" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the type of error reporting: inline or error template. + ### `password_reset_url=` password_reset_url="member/reset-password" @@ -57,6 +63,12 @@ This parameter allows you to define where the user will be returned after succes 1. Use the standard Template_Group/Template syntax to specify where to return the user. For instance, if you want the user to be returned to the "local" Template in the "news" Template Group, you would use: return="member/forgot-password/sent" 2. Use a full URL. For example: return="" +### `return_error=` + + return_error="template_group/error" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the template to return to if validation errors are detected. + ## Form Inputs NOTE: Be sure to include the required Javascript and CSS to use the native [Password Validation](member/password-validation.md). diff --git a/docs/member/forgot-username.md b/docs/member/forgot-username.md index 8cf71e447..16a695561 100644 --- a/docs/member/forgot-username.md +++ b/docs/member/forgot-username.md @@ -43,6 +43,12 @@ Template to use for email which is sent to user. If no template is defined or if the template defined does not exist, the default [Member Profile Template](control-panel/template-manager.md#member-profile-templates) for a forgotten username will be used. +### `inline_errors=` + + inline_errors="yes" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the type of error reporting: inline or error template. + ### `return=` return="member/login/forgot-username" @@ -52,6 +58,12 @@ This parameter allows you to define where the user will be returned after succes 1. Use the standard Template_Group/Template syntax to specify where to return the user. For instance, if you want the user to be returned to the "local" Template in the "news" Template Group, you would use: return="member/login/forgot-username" 2. Use a full URL. For example: return="" +### `return_error=` + + return_error="template_group/error" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the template to return to if validation errors are detected. + ## Form Inputs ### Email diff --git a/docs/member/login.md b/docs/member/login.md index ca8a130da..b170ac170 100644 --- a/docs/member/login.md +++ b/docs/member/login.md @@ -56,6 +56,13 @@ This parameter allows you to specify the id attribute for the <form> tag. This parameter allows you to specify a name attribute for the <form> tag. +### `inline_errors=` + + inline_errors="yes" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the type of error reporting: inline or error template. + + ### `return=` return="site/index" @@ -65,7 +72,11 @@ This parameter allows you to define where the user will be returned after succes 1. Use the standard Template_Group/Template syntax to specify where to return the user. For instance, if you want the user to be returned to the "local" Template in the "news" Template Group, you would use: return="news/local" 2. Use a full URL. For example: return="" +### `return_error=` + + return_error="template_group/error" +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the template to return to if validation errors are detected. ## Form Inputs diff --git a/docs/member/memberlist.md b/docs/member/memberlist.md index f8606a0e6..5d73aa98a 100644 --- a/docs/member/memberlist.md +++ b/docs/member/memberlist.md @@ -21,13 +21,42 @@ Outputs a searchable list of members, including form filters to sort and limit t {{embed:_tips/form-attributes.md}} -### `role_id=` +### `backspace=` - role_id="5" + backspace="3" -Restrict the output to members that belong to certain [role](control-panel/member-manager.md#member-roles). +The `backspace=` parameter will remove the specified number of characters, including spaces and line breaks, from the last iteration of the tag pair. + +### `error_handling="inline"` + error_handling="inline" + +This parameter allows you to use inline errors in your registration form. The errors can be displayed using the `{error:field_name}` tag where `field_name` would need to be replaced with the name of the field that has an error, as used to compose the form. + +### `form_class=` + + form_class="login" + +This parameter allows you to specify the class attribute for the search <form> tag. + +### `form_id=` + + form_id="login" + +This parameter allows you to specify the id attribute for the search <form> tag. + +### `form_name=` + + form_name="login" + +This parameter allows you to specify a name attribute for the search <form> tag. + +### `limit=` + + limit="30" + +Allows you to limit the number of members displayed. +When not set, defaults to [Member List - Rows](control-panel/settings/members.md#total-results) setting or [`memberlist_row_limit` configuration override](general/system-configuration-overrides.md#memberlist_row_limit) -NOTE: This parameter replaces `group_id` which is functionally identical and currently still supported. ### `orderby=` @@ -49,6 +78,15 @@ The "orderby" parameter sets the display order of members. The possible options When not set, defaults to [Member List - Order](control-panel/settings/members.md#order-by) setting or [`memberlist_order_by` configuration override](general/system-configuration-overrides.md#memberlist_order_by) +### `role_id=` + + role_id="5" + +Restrict the output to members that belong to certain [role](control-panel/member-manager.md#member-roles). + +NOTE: This parameter replaces `group_id` which is functionally identical and currently still supported. + + ### `sort=` sort="asc" @@ -57,41 +95,16 @@ setting or [`memberlist_order_by` configuration override](general/system-configu Set the order in which members are displayed. When not set, defaults to [Member List - Sort By](control-panel/settings/members.md#sort-by) setting or [`memberlist_sort_order` configuration override](general/system-configuration-overrides.md#memberlist_sort_order) -### `limit=` - - limit="30" - -Allows you to limit the number of members displayed. -When not set, defaults to [Member List - Rows](control-panel/settings/members.md#total-results) setting or [`memberlist_row_limit` configuration override](general/system-configuration-overrides.md#memberlist_row_limit) - ### `return=` return="member/memberlist" + +### `return_error=` -### `form_class=` - - form_class="login" - -This parameter allows you to specify the class attribute for the search <form> tag. - -### `form_id=` - - form_id="login" - -This parameter allows you to specify the id attribute for the search <form> tag. - -### `form_name=` - - form_name="login" - -This parameter allows you to specify a name attribute for the search <form> tag. - -### `backspace=` - - backspace="3" - -The `backspace=` parameter will remove the specified number of characters, including spaces and line breaks, from the last iteration of the tag pair. + return_error="template_group/error" +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the template to return to if validation errors are detected. + ## Form Variables ### `{form_declaration}` diff --git a/docs/member/registration.md b/docs/member/registration.md index 780667659..7a01d8f43 100644 --- a/docs/member/registration.md +++ b/docs/member/registration.md @@ -23,39 +23,29 @@ NOTE: **Important:** In order for site visitors to be allowed to register for ac {{embed:_tips/form-attributes.md}} -### `return=` - - return="member/registration/success" - -### `form_class=` - - form_class="register" +### `datepicker=` - ### `primary_role=` + datepicker="no" - primary_role="7" +Adds the datepicker to your date fields. Defaults to "yes". -This parameter allows you to specify the primary role to assign the new member, overriding the default member setting. +NOTE: **Note:** If you are manually constructing a date field, in order to apply the date picker you must include `rel="date-picker"`. ### `error_handling="inline"` error_handling="inline" This parameter allows you to use inline errors in your registration form. The errors can be displayed using the `{error:field_name}` tag where `field_name` would need to be replaced with the name of the field that has an error, as used to compose the form. +### `form_class=` + + form_class="register" + ### `include_assets=` include_assets="yes" Adds the Javascript and CSS that is required by custom member fields to your form. By default, these are **not** included -### `datepicker=` - - datepicker="no" - -Adds the datepicker to your date fields. Defaults to "yes". - -NOTE: **Note:** If you are manually constructing a date field, in order to apply the date picker you must include `rel="date-picker"`. - ### `include_css=` include_css="no" @@ -70,6 +60,22 @@ Includes jQuery automatically. Defaults to "yes". NOTE: **Note:** If you are using your own copy of jQuery you will need to load it **before** the form. +### `primary_role=` + + primary_role="7" + +This parameter allows you to specify the primary role to assign the new member, overriding the default member setting. + +### `return=` + + return="member/registration/success" + +### `return_error=` + + return_error="template_group/error" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the template to return to if validation errors are detected. + ## Form Inputs NOTE: Be sure to include the required JavaScript and CSS to use the native [Password Validation](member/password-validation.md). diff --git a/docs/member/reset-password.md b/docs/member/reset-password.md index 68d3d0028..6eb3c3745 100644 --- a/docs/member/reset-password.md +++ b/docs/member/reset-password.md @@ -32,6 +32,12 @@ Output a reset password form that allows members accessing it via a link from a ## Parameters +### `inline_errors=` + + inline_errors="yes" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the type of error reporting: inline or error template. + ### `return=` return="member/login/success" @@ -41,6 +47,12 @@ This parameter allows you to define where the user will be returned after succes 1. Use the standard Template_Group/Template syntax to specify where to return the user. For instance, if you want the user to be returned to the "local" Template in the "news" Template Group, you would use: return="news/local" 2. Use a full URL. For example: return="" +### `return_error=` + + return_error="template_group/error" + +This parameter is for use with [form validation and error handling](/templates/form-validation.md) and determines the template to return to if validation errors are detected. + ## Form Inputs NOTE: Be sure to include the required Javascript and CSS to use the native [Password Validation](member/password-validation.md). From b874737b25e5c4d16b06d70947b46c970911950a Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Wed, 9 Oct 2024 14:00:31 -0400 Subject: [PATCH 20/30] Revert "Fix Fluid Field hooks info" --- .../extension-hooks/model/fluid-field.md | 91 +++++-------------- docs/development/models/fluid-field.md | 6 +- 2 files changed, 25 insertions(+), 72 deletions(-) diff --git a/docs/development/extension-hooks/model/fluid-field.md b/docs/development/extension-hooks/model/fluid-field.md index 4f65b0b5f..315274ff7 100644 --- a/docs/development/extension-hooks/model/fluid-field.md +++ b/docs/development/extension-hooks/model/fluid-field.md @@ -15,76 +15,46 @@ lang: php [TOC=3] -### `fluid_field_get_all_data($data, $fluid_field_id, $fluid_field)` +### `fluid_field_get_all_data($data, $fluid_field_id)` -| Parameter | Type | Description | -| ---------------- | ------------ | ------------------------------------------------------------------------- | -| \$data | `FieldData` | Instance of ExpressionEngine\Model\Content\FieldData for fluid field | -| \$fluid_field_id | `Int` | The ID of Fluid field being fetched | -| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | -| Returns | `FieldData` | Current instance of ExpressionEngine\Model\Content\FieldData | +| Parameter | Type | Description | +| ---------------- | ------------ | ----------------------------------------------------------------------- | +| \$data | `FluidField` | Current instance of ExpressionEngine\Addons\FluidField\Model\FluidField | +| \$fluid_field_id | `Array` | The MemberField model object data as an array | +| Returns | `FluidField` | Current instance of ExpressionEngine\Addons\FluidField\Model\FluidField | -Called after field data has been fetched and before the fluid field field object is returned. +Called before the fluid field field object is returned. How it's called: - ee()->extensions->call('fluid_field_get_all_data', $data, $fluid_field_id, $fluid_field); + ee()->extensions->call('fluid_field_get_all_data', $data, $fluid_field_id); -### `fluid_field_get_field_data($data, $fluid_field_id, $field_data_id, $fluid_field)` +TIP: **New in version 6.1.0.** -| Parameter | Type | Description | -| ---------------- | ------------ | ------------------------------------------------------------------------- | -| \$data | `FieldData` | Instance of ExpressionEngine\Model\Content\FieldData for fluid field | -| \$fluid_field_id | `Int` | The ID of Fluid field being fetched | -| \$field_data_id | `Int` | The ID of row of field data racord | -| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | -| Returns | `Array` | Data for the field in Fluid that's currently fetched | - -Called before field data is fetched. When hook is present, the field data will not be fetched from the database. - -How it's called: - - ee()->extensions->call('fluid_field_get_all_data', $data, $fluid_field_id, $field_data_id, $fluid_field); - -### `fluid_field_add_field($field_table_name, $values, $fluid_field)` +### `fluid_field_add_field($field_table_name, $values)` | Parameter | Type | Description | | ------------------ | ------------ | ----------------------------- | | \$field_table_name | `String` | Name of Fluid field table | | \$values | `Array` | The current field values | -| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | | Returns | `Array` | Adjusted field values | Called before the fluid field is inserted. Changes made to the object will be saved automatically. How it's called: - ee()->extensions->call('fluid_field_add_field', $field_table_name, $values, $fluid_field); - -### `fluid_field_after_add_field($fluid_field, $field_table_name, $values, $id)` - -| Parameter | Type | Description | -| ------------------ | ------------ | ----------------------------- | -| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | -| \$field_table_name | `String` | Name of table being changed | -| \$values | `Array` | The current field values | -| \$id | `Int` | The ID of field that was added | -| Returns | `Void` | Does not return any data | + ee()->extensions->call('fluid_field_add_field', $field_table_name, $values); -Called after the fluid field is inserted. - -How it's called: - - ee()->extensions->call('fluid_field_after_add_field', $fluid_field, $field_table_name, $values, $id); +TIP: **New in version 6.1.0.** ### `fluid_field_update_field($fluid_field, $field_table_name, $values)` -| Parameter | Type | Description | -| ------------------ | ------------ | ------------------------------------------------------------------------- | -| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | -| \$field_table_name | `String` | Name of table being changed | -| \$values | `Array` | The current field values | -| Returns | `Array` | Adjusted field values | +| Parameter | Type | Description | +| ------------------ | ------------ | ----------------------------------------------------------------------- | +| \$fluid_field | `FluidField` | Current instance of ExpressionEngine\Addons\FluidField\Model\FluidField | +| \$field_table_name | `String` | Name of table being changed | +| \$values | `Array` | The current field values | +| Returns | `Array` | Adjusted field values | Called before the fluid field is updated. Changes made to the object will be saved automatically. @@ -92,27 +62,14 @@ How it's called: ee()->extensions->call('fluid_field_update_field', $field_table_name, $values); -### `fluid_field_after_update_field($fluid_field, $field_table_name, $values)` - -| Parameter | Type | Description | -| ------------------ | ------------ | ------------------------------------------------------------------------- | -| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | -| \$field_table_name | `String` | Name of table being changed | -| \$values | `Array` | The current field values | -| Returns | `Void` | Does not return any data | - -Called after the fluid field has been updated. - -How it's called: - - ee()->extensions->call('fluid_field_add_field', $fluid_field, $field_table_name, $values); +TIP: **New in version 6.1.0.** ### `fluid_field_remove_field($fluid_field)` -| Parameter | Type | Description | -| ------------------ | ------------ | ------------------------------------------------------------------------- | -| \$fluid_field | `FluidField` | Current instance of [FluidField model](development/models/fluid-field.md) | -| Returns | `null` | | +| Parameter | Type | Description | +| ------------------ | ------------ | ----------------------------------------------------------------------- | +| \$fluid_field | `FluidField` | Current instance of ExpressionEngine\Addons\FluidField\Model\FluidField | +| Returns | `null` | | Called before the fluid field is deleted. Field will be deleted after hook is called @@ -120,4 +77,4 @@ How it's called: ee()->extensions->call('fluid_field_remove_field', $fluid_field); -TIP: **New in version 6.1.0.** \ No newline at end of file +TIP: **New in version 6.1.0.** diff --git a/docs/development/models/fluid-field.md b/docs/development/models/fluid-field.md index 81f91e35a..0430bb459 100644 --- a/docs/development/models/fluid-field.md +++ b/docs/development/models/fluid-field.md @@ -15,8 +15,6 @@ lang: php **class `ExpressionEngine\Addons\FluidField\Model\FluidField`** -This model is used to manipulate custom field which is being used inside a Fluid Field for certain Channel Entry. - [TOC] ## Properties @@ -24,7 +22,6 @@ This model is used to manipulate custom field which is being used inside a Fluid - `id` Key - `fluid_field_id` - `entry_id` -- `field_group_id` - `field_id` - `field_data_id` - `order` @@ -32,8 +29,7 @@ This model is used to manipulate custom field which is being used inside a Fluid ## Relationships - `ChannelEntry` -- `ChannelField` -- `ChannelFieldGroup` +- `ChannelFields` - `FieldField` ## Methods From 900e533c092cd1e8835b44251e362e58329436de Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Wed, 9 Oct 2024 14:07:31 -0400 Subject: [PATCH 21/30] Fix broken link --- docs/templates/generators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/templates/generators.md b/docs/templates/generators.md index a00b395ae..b12130d5a 100644 --- a/docs/templates/generators.md +++ b/docs/templates/generators.md @@ -25,7 +25,7 @@ Upon successful generation of new templates, you will be brought to the Template ## Command Line Usage -You can also generate templates using [ExpressionEngine's Command Line Interface (CLI)](../cli/usage.md). The main CLI command to access all template generators in the system is: `php system/ee/eecli.php generate:templates`. +You can also generate templates using [ExpressionEngine's Command Line Interface (CLI)](/cli/usage.md). The main CLI command to access all template generators in the system is: `php system/ee/eecli.php generate:templates`. To get the list of available template generators, pass the `--list` option to the command: From 1e75cfdfeb34cd75328835dc723fba99f7784ce2 Mon Sep 17 00:00:00 2001 From: robinsowell Date: Mon, 14 Oct 2024 11:22:22 -0400 Subject: [PATCH 22/30] Added a link to template generator detail page from template manager --- docs/control-panel/template-manager.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/control-panel/template-manager.md b/docs/control-panel/template-manager.md index 19474caf2..0a8be57fd 100755 --- a/docs/control-panel/template-manager.md +++ b/docs/control-panel/template-manager.md @@ -239,6 +239,12 @@ Tip: Custom Ordering Template Groups This section of the Control Panel allows you to create or edit a template group. +## Template Generators + +**Control Panel Location: `Developer > Templates > Template Generators`** + +This section of the Control Panel allows you to automatically create the basic tag framework for a variety of modules, including channels, navigation, member tags, etc. using [Template Generators](templates/generators.md). + ## Export Templates **Control Panel Location: `Developer > Templates > Export`** From 8d8302b09134a64821a841288f3f4b5fbbfee7a8 Mon Sep 17 00:00:00 2001 From: robinsowell Date: Mon, 14 Oct 2024 11:53:18 -0400 Subject: [PATCH 23/30] Added info on tag copying updated entry create and added info to channel and field manager pages on copying tags. Included https requirement. --- docs/control-panel/channels.md | 4 +++- docs/control-panel/create.md | 2 +- docs/control-panel/field-manager/field-manager-settings.md | 2 ++ 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/control-panel/channels.md b/docs/control-panel/channels.md index 902c9443e..f1b762d15 100755 --- a/docs/control-panel/channels.md +++ b/docs/control-panel/channels.md @@ -11,7 +11,9 @@ **Control Panel Location: `Developer > Channels`** -This section of the Control Panel is where channels are created, edited and deleted. +This section of the Control Panel is where channels are created, edited and deleted. + +The channel shortname on the main display supports quick copying the full template tag for the channel, including all fields assigned to the channel. The copied code is ready to use on your [templates](templates/overview.md). Quick copying code via the channel shortname is only supported when on HTTPS. [TOC] diff --git a/docs/control-panel/create.md b/docs/control-panel/create.md index ff7c01ba9..60ab33d36 100755 --- a/docs/control-panel/create.md +++ b/docs/control-panel/create.md @@ -51,7 +51,7 @@ This can be done in two ways: - assign custom field to a [Field Group](/control-panel/field-manager/field-manager-settings.md#createedit-field-group) which is associated to the Channel - assign field directly to channel by editing [Channel preferences](control-panel/channels.md#fields-tab) -When working with [templates](templates/overview.md) you will be referencing the field by its short name. For convenience the short name can be displayed next to the field's name in the publish form (field short name) and will be copied to the clipboard when clicked. Displaying the short name can be toggled on or off in the [Role](control-panel/member-manager.md) settings. +When working with [templates](templates/overview.md) you will be referencing the field by its short name or tag pair. For convenience the short name can be displayed next to the field's name in the publish form (field short name) and the variable(s) required to display the content will be copied to the clipboard when clicked. Displaying the short name can be toggled on or off in the [Role](control-panel/member-manager.md) settings. Copying code via the shortname is only supported when on HTTPS. Note that some fields can be displayed with just single tags while others would require a tag pair with extra variables. More information can be found in the documentation for the field's specific [field type](fieldtypes/overview.md). diff --git a/docs/control-panel/field-manager/field-manager-settings.md b/docs/control-panel/field-manager/field-manager-settings.md index ea247afba..1b7da923c 100644 --- a/docs/control-panel/field-manager/field-manager-settings.md +++ b/docs/control-panel/field-manager/field-manager-settings.md @@ -17,6 +17,8 @@ This section of the Control Panel is where custom fields are created, edited and ![](_images/cp-field-manager.png) +The field shortname supports quick copying the full tag needed to display the field. The copied can is ready to use on your [templates](templates/overview.md). Quick copying code via the channel shortname is only supported when on HTTPS. + Tip: How to Find Where a Field Is Used
From ee76a3d92e1fc26c3081c8dc6897dfe80cf62177 Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Mon, 14 Oct 2024 12:50:41 -0400 Subject: [PATCH 24/30] Release 7.5.0 --- docs/installation/changelog.md | 40 ++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/docs/installation/changelog.md b/docs/installation/changelog.md index ce8365c9b..ab57fa2c1 100755 --- a/docs/installation/changelog.md +++ b/docs/installation/changelog.md @@ -8,6 +8,46 @@ --> # ExpressionEngine v7 Change Log +# Version 7.5.0 +(Release: October 14, 2024) + +- **Contributors** 🙌 +
+
+ +
+
+ +**Enhancements** 🚀 + +- Introducing [Template Generators](https://expressionengine.com/blog/7.5-code-generators) +- Show errors in Control Panel using default layout with sidebar [#3536](https://github.com/ExpressionEngine/ExpressionEngine/issues/3536) +- Update specialty message templates if the site is using outdated EE2 versions +- Fluid Field Group Improvements: Allow field group parsing outside of `{fields}` loop, Add new fixed_order and order parameters to `{fields}` tag, Update order of fields within `{fields}` tag to default to Field Group order +- Enable cloning of Menu Sets [#4214](https://github.com/ExpressionEngine/ExpressionEngine/issues/4214) +- Add support for inline_errors in form submissions [#2871](https://github.com/ExpressionEngine/ExpressionEngine/issues/2871) +- Added `{exp:channel:field}` tag to display field properties [#2870](https://github.com/ExpressionEngine/ExpressionEngine/issues/2870) +- Update License Validation banners and improve messaging for users without ability to manage licenses +- Added new config variable for setting the default template engine `$config['default_template_engine']` +- Added Channel filter to the Field Manager +- Updated Note Fieldtype so it can be used in templates to display its content + +**Bug Fixes** 💃🐛 + +- Fixed [#4087](https://github.com/ExpressionEngine/ExpressionEngine/issues/4087), [#4055](https://github.com/ExpressionEngine/ExpressionEngine/issues/4055) where there were problems with copying short name of a field in the publish form +- Resolved [#3556](https://github.com/ExpressionEngine/ExpressionEngine/issues/3556) where date fields could not accommodate dates past year 2038 +- Resolved [#3865](https://github.com/ExpressionEngine/ExpressionEngine/issues/3865) where cloning a fluid field could break existing field groups +- Fix Live Preview bugs with Fluid field group [#4388](https://github.com/ExpressionEngine/ExpressionEngine/issues/4388) +- Fix bug where adding new fields to field group in fluid would not allow existing entries to accept content for that field [#3741](https://github.com/ExpressionEngine/ExpressionEngine/issues/3741) +- Fixed possible PHP warnings in Pro Search keyword handling + # Version 7.4.11 (Release: June 13, 2024) From 45fa49224e387a694a4c582b600883722f3a561b Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Mon, 14 Oct 2024 13:51:26 -0400 Subject: [PATCH 25/30] Small updates to shortname tag copying --- docs/control-panel/channels.md | 7 +++++-- docs/control-panel/create.md | 9 ++++++--- .../field-manager/field-manager-settings.md | 2 +- docs/control-panel/member-manager.md | 4 ++-- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/control-panel/channels.md b/docs/control-panel/channels.md index f1b762d15..4b499d8bb 100755 --- a/docs/control-panel/channels.md +++ b/docs/control-panel/channels.md @@ -11,9 +11,12 @@ **Control Panel Location: `Developer > Channels`** -This section of the Control Panel is where channels are created, edited and deleted. +This section of the Control Panel is where channels are created, edited and deleted. -The channel shortname on the main display supports quick copying the full template tag for the channel, including all fields assigned to the channel. The copied code is ready to use on your [templates](templates/overview.md). Quick copying code via the channel shortname is only supported when on HTTPS. +The channel shortname on the main display supports quick copying the full template tag for the channel, including all fields assigned to the channel. The copied code is ready to use on your [templates](templates/overview.md). Displaying the short name can be toggled on or off in the [Role](control-panel/member-manager.md) settings. + +NOTE: +Due to security restrictions in modern browsers quick copying code via the shortname is only supported when on HTTPS. [TOC] diff --git a/docs/control-panel/create.md b/docs/control-panel/create.md index 60ab33d36..4f0c4e2b5 100755 --- a/docs/control-panel/create.md +++ b/docs/control-panel/create.md @@ -39,7 +39,7 @@ NOTE: **Note:** If you let the system create your URL Title for you it will conv ### Entry Fields -The names and types of entry custom fields displayed will be determined by what [Fields](/fieldtypes/overview.md) you have defined for this channel. +The names and types of entry custom fields displayed will be determined by what [Fields](/fieldtypes/overview.md) you have defined for this channel. If an entry field is set to be "hidden" by default, it will have to be expanded by clicking on the field name before content can be entered. @@ -51,7 +51,10 @@ This can be done in two ways: - assign custom field to a [Field Group](/control-panel/field-manager/field-manager-settings.md#createedit-field-group) which is associated to the Channel - assign field directly to channel by editing [Channel preferences](control-panel/channels.md#fields-tab) -When working with [templates](templates/overview.md) you will be referencing the field by its short name or tag pair. For convenience the short name can be displayed next to the field's name in the publish form (field short name) and the variable(s) required to display the content will be copied to the clipboard when clicked. Displaying the short name can be toggled on or off in the [Role](control-panel/member-manager.md) settings. Copying code via the shortname is only supported when on HTTPS. +When working with [templates](templates/overview.md) you will be referencing the field by its short name or tag pair. For convenience the short name can be displayed next to the field's name in the publish form (field short name) and the variable(s) required to display the content will be copied to the clipboard when clicked. Displaying the short name can be toggled on or off in the [Role](control-panel/member-manager.md) settings. + +NOTE: +Due to security restrictions in modern browsers quick copying code via the shortname is only supported when on HTTPS. Note that some fields can be displayed with just single tags while others would require a tag pair with extra variables. More information can be found in the documentation for the field's specific [field type](fieldtypes/overview.md). @@ -189,6 +192,6 @@ A live preview of the entry is available if the `channel_prefs_preview_url` is s If neither is set, the preview button will have an exclamation mark (!) and will link to channel preferences page where Preview URL can be set. -The preview will open a split screen that allows a live preview of edits. The template used to display the preview is based on the Page fields if set and the channel preview URL otherwise. +The preview will open a split screen that allows a live preview of edits. The template used to display the preview is based on the Page fields if set and the channel preview URL otherwise. When the preview is triggered, it is being displayed side-by-side with edit screen. The size of preview container can be adjusted with mouse dragging its border. The preview is dynamically being updated as you change the fields. diff --git a/docs/control-panel/field-manager/field-manager-settings.md b/docs/control-panel/field-manager/field-manager-settings.md index 1b7da923c..2815fde8b 100644 --- a/docs/control-panel/field-manager/field-manager-settings.md +++ b/docs/control-panel/field-manager/field-manager-settings.md @@ -17,7 +17,7 @@ This section of the Control Panel is where custom fields are created, edited and ![](_images/cp-field-manager.png) -The field shortname supports quick copying the full tag needed to display the field. The copied can is ready to use on your [templates](templates/overview.md). Quick copying code via the channel shortname is only supported when on HTTPS. +The field shortname supports quick copying the full tag needed to display the field. The copied can is ready to use on your [templates](templates/overview.md). Displaying the short name can be toggled on or off in the [Role](control-panel/member-manager.md) settings. Due to security restrictions in modern browsers quick copying code via the shortname is only supported when on HTTPS. Tip: How to Find Where a Field Is Used
diff --git a/docs/control-panel/member-manager.md b/docs/control-panel/member-manager.md index 9858222ed..86eac6474 100755 --- a/docs/control-panel/member-manager.md +++ b/docs/control-panel/member-manager.md @@ -82,13 +82,13 @@ This tab contains the generic settings for the role. You can also assign the rol - **Include members in: author/member lists.** -- Roles included in the author list are available in the author select field on the entry publish/edit page for any channel the role has permission to publish in. --- Roles included in the member lists are available to display in the [member list tag](member/memberlist.md). +-- Roles included in the member lists are available to display in the [member list tag](member/memberlist.md). - **Security Lock** -- If enabled, only Super Admin users can add or remove members to the role. - **Role Groups** -- Assign the role to [role groups](control-panel/member-manager.md#role-groups). -- **Show field names on Publish** -- Enables the display of the field tags on the entry publish/edit page. This option is only available to the Super Admin role. +- **Show field names on Publish** -- Enables the display of field short names on the entry publish/edit page. Tip: Hide and Show Field Short Names in the Publish Area
From 317505b91ae83abce6189ff0555b4ec931578fc9 Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Mon, 14 Oct 2024 14:06:37 -0400 Subject: [PATCH 26/30] Add line about enhancements for copy shortname functionality --- docs/installation/changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/installation/changelog.md b/docs/installation/changelog.md index ab57fa2c1..da0ec17f4 100755 --- a/docs/installation/changelog.md +++ b/docs/installation/changelog.md @@ -28,6 +28,7 @@ **Enhancements** 🚀 - Introducing [Template Generators](https://expressionengine.com/blog/7.5-code-generators) +- Expanded copy shortname functionality to the Channel and Field Manager making it possible to copy full template code for channels, field groups, and fields. - Show errors in Control Panel using default layout with sidebar [#3536](https://github.com/ExpressionEngine/ExpressionEngine/issues/3536) - Update specialty message templates if the site is using outdated EE2 versions - Fluid Field Group Improvements: Allow field group parsing outside of `{fields}` loop, Add new fixed_order and order parameters to `{fields}` tag, Update order of fields within `{fields}` tag to default to Field Group order From 5f9646e34553ae4d56ad51fff09ae32f6469f074 Mon Sep 17 00:00:00 2001 From: robinsowell Date: Tue, 10 Sep 2024 15:14:37 -0400 Subject: [PATCH 27/30] Rough draft template generator 'note' I'm wondering if this might be better as a section than a note, and if so, where. Especially with the pro search one, there are some requirements for it to work. But... rough draft, so I shall ponder. --- docs/add-ons/pro-search/tags.md | 1 + docs/channels/channel-form/overview.md | 2 ++ docs/channels/entries.md | 2 ++ docs/member/index.md | 2 ++ 4 files changed, 7 insertions(+) diff --git a/docs/add-ons/pro-search/tags.md b/docs/add-ons/pro-search/tags.md index d77a64782..9deb2bcc1 100644 --- a/docs/add-ons/pro-search/tags.md +++ b/docs/add-ons/pro-search/tags.md @@ -22,6 +22,7 @@ added in X.X.X: This parameter/field is only available from this version forward logged in: This tag is only available if the user is logged in. ``` +NOTE: See the [template generator](control-panel/template-manager.md#template-generators) for the keyword search in ExpressionEngine 7.5+. Pro Search must be installed and a Collection created. ## {exp:pro_search:form} diff --git a/docs/channels/channel-form/overview.md b/docs/channels/channel-form/overview.md index 4a866b93d..2fa858cba 100755 --- a/docs/channels/channel-form/overview.md +++ b/docs/channels/channel-form/overview.md @@ -24,6 +24,8 @@ The Channel Form makes it possible to add and edit channel entries from outside - Server-side validation. - Handles AJAX requests and can output responses in JSON. +NOTE: See the [template generator](control-panel/template-manager.md#template-generators) for the channel form in ExpressionEngine 7.5+. + ## Basic Usage TIP: Please visit the [Examples](channels/channel-form/examples.md) page to see a variety of implementations. diff --git a/docs/channels/entries.md b/docs/channels/entries.md index 63ea5400b..2a4bb9287 100755 --- a/docs/channels/entries.md +++ b/docs/channels/entries.md @@ -33,6 +33,8 @@ The directives that tell the tag how to behave are **parameters**: Within the opening and closing ExpressionEngine Tags are **variables**. `{title}` is replaced with the Title of each entry, and `{body}` is replaced with the content from the "Body" field of each entry. +NOTE: See the [template generator](control-panel/template-manager.md#template-generators) for the channel entries in ExpressionEngine 7.5+. + ## Parameters [TOC=3 hide] diff --git a/docs/member/index.md b/docs/member/index.md index 5ddb9317a..926bc53ef 100755 --- a/docs/member/index.md +++ b/docs/member/index.md @@ -34,6 +34,8 @@ NOTE: **Note:** A member account's Username and Screen Name can be identical, bu - [Ignore List Tag](member/ignore-list.md) - [Profile Templates (Legacy)](member/profile-templates.md) +NOTE: See the [template generator](control-panel/template-manager.md#template-generators) for the member templates in ExpressionEngine 7.5+. + ### Member Navigation From efe625bdc2067ba23e13af5816172d254888e2c8 Mon Sep 17 00:00:00 2001 From: robinsowell Date: Tue, 8 Oct 2024 13:06:18 -0400 Subject: [PATCH 28/30] Fixed note format and added structure note re template generators --- docs/add-ons/pro-search/tags.md | 2 +- docs/add-ons/structure/overview.md | 4 +++- docs/channels/entries.md | 2 +- docs/member/index.md | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/add-ons/pro-search/tags.md b/docs/add-ons/pro-search/tags.md index 9deb2bcc1..52b927bbe 100644 --- a/docs/add-ons/pro-search/tags.md +++ b/docs/add-ons/pro-search/tags.md @@ -22,7 +22,7 @@ added in X.X.X: This parameter/field is only available from this version forward logged in: This tag is only available if the user is logged in. ``` -NOTE: See the [template generator](control-panel/template-manager.md#template-generators) for the keyword search in ExpressionEngine 7.5+. Pro Search must be installed and a Collection created. +NOTE: **Note:** See the [template generator](control-panel/template-manager.md#template-generators) for the keyword search in ExpressionEngine 7.5+. Pro Search must be installed and a Collection created. ## {exp:pro_search:form} diff --git a/docs/add-ons/structure/overview.md b/docs/add-ons/structure/overview.md index 333aebeb7..cb8c068ee 100644 --- a/docs/add-ons/structure/overview.md +++ b/docs/add-ons/structure/overview.md @@ -13,4 +13,6 @@ Structure is a powerful add-on that lets you create pages, generate navigation, It forgoes the default template_group/template setup and creates “static” and “listing” pages that are all editable through a tree sitemap view. With Structure enabled, traditional page style content and multiple entry pages can live within the same area. -NOTE:**Note:** Documentation for Structure is still being migrated. Until this is complete, please reference the [Structure documentation on EEHarbor's website](https://eeharbor.com/structure/documentation). \ No newline at end of file +NOTE:**Note:** Documentation for Structure is still being migrated. Until this is complete, please reference the [Structure documentation on EEHarbor's website](https://eeharbor.com/structure/documentation). + +NOTE:**Note:** See the [template generator](control-panel/template-manager.md#template-generators) for the structure templates in ExpressionEngine 7.5+. \ No newline at end of file diff --git a/docs/channels/entries.md b/docs/channels/entries.md index 2a4bb9287..be2d5eef5 100755 --- a/docs/channels/entries.md +++ b/docs/channels/entries.md @@ -33,7 +33,7 @@ The directives that tell the tag how to behave are **parameters**: Within the opening and closing ExpressionEngine Tags are **variables**. `{title}` is replaced with the Title of each entry, and `{body}` is replaced with the content from the "Body" field of each entry. -NOTE: See the [template generator](control-panel/template-manager.md#template-generators) for the channel entries in ExpressionEngine 7.5+. +NOTE: **Note:** See the [template generator](control-panel/template-manager.md#template-generators) for the channel entries in ExpressionEngine 7.5+. ## Parameters diff --git a/docs/member/index.md b/docs/member/index.md index 926bc53ef..1ece2396a 100755 --- a/docs/member/index.md +++ b/docs/member/index.md @@ -34,7 +34,7 @@ NOTE: **Note:** A member account's Username and Screen Name can be identical, bu - [Ignore List Tag](member/ignore-list.md) - [Profile Templates (Legacy)](member/profile-templates.md) -NOTE: See the [template generator](control-panel/template-manager.md#template-generators) for the member templates in ExpressionEngine 7.5+. +NOTE: **Note:** See the [template generator](control-panel/template-manager.md#template-generators) for the member templates in ExpressionEngine 7.5+. ### Member Navigation From 0fbac7a9c9339b20eaf758d2effeee5d40fc5dc5 Mon Sep 17 00:00:00 2001 From: Bryan Nielsen Date: Mon, 14 Oct 2024 16:16:52 -0400 Subject: [PATCH 29/30] Update cross-references to template generators --- docs/add-ons/pro-search/tags.md | 34 +++++++++++++------------- docs/add-ons/structure/overview.md | 4 +-- docs/channels/channel-form/overview.md | 5 ++-- docs/channels/entries.md | 2 +- docs/control-panel/template-manager.md | 4 +-- docs/member/index.md | 4 +-- docs/templates/generators.md | 2 +- 7 files changed, 26 insertions(+), 29 deletions(-) diff --git a/docs/add-ons/pro-search/tags.md b/docs/add-ons/pro-search/tags.md index 52b927bbe..9d111072b 100644 --- a/docs/add-ons/pro-search/tags.md +++ b/docs/add-ons/pro-search/tags.md @@ -10,19 +10,19 @@ [TOC] -**These terms are used throughout the documentation:** +**These terms are used throughout the documentation:** ``` -required: This parameter/field is required for this tag to function. -form only: This can only be set as a field in the form and not as a parameter in the tag. -param only: This parameter can only be set in the tag and not as a field in the form. -fixed value: This field cannot be edited and is set with a fixed value. -recurring only: This parameter/field only applies to recurring charges. -one-time only: This parameter/field only applies to one-time charges. -added in X.X.X: This parameter/field is only available from this version forward. -logged in: This tag is only available if the user is logged in. +required: This parameter/field is required for this tag to function. +form only: This can only be set as a field in the form and not as a parameter in the tag. +param only: This parameter can only be set in the tag and not as a field in the form. +fixed value: This field cannot be edited and is set with a fixed value. +recurring only: This parameter/field only applies to recurring charges. +one-time only: This parameter/field only applies to one-time charges. +added in X.X.X: This parameter/field is only available from this version forward. +logged in: This tag is only available if the user is logged in. ``` -NOTE: **Note:** See the [template generator](control-panel/template-manager.md#template-generators) for the keyword search in ExpressionEngine 7.5+. Pro Search must be installed and a Collection created. +NOTE: **Note:** See the [template generator](templates/generators.md) for the keyword search in ExpressionEngine 7.5+. Pro Search must be installed and a Collection created. ## {exp:pro_search:form} @@ -157,7 +157,7 @@ Short syntax for the URL tag. When used, it will automatically inherit the query ## {exp:pro_search:filters} The Filters tag works identically to the Form tag, without generating a search form. Use it to show specific search filters anywhere on your page, or to create a list of URL tags in short syntax. The following example shows a list of one-click filters based on the current search that could be used to modify the results display with javascript: - + {exp:pro_search:filters query="{segment_3}"} {exp:channel:categories channel="entries" style="linear"} {if count == 1}