Jump to content

Settings Factory


Macrura

Recommended Posts

sf_logo.png.273967076f19a5f3601ac83abc3cef49.png

This is the new topic for the Settings Factory module (formerly known as Settings Train).

Repo:

https://github.com/outflux3/SettingsFactory

I'm not sure what versions this is compatible with, it has only been tested on 3.x branch;
it is not namespaced, and i'm not sure if namespacing is necessary or a benefit for this module; if any namespace or module gurus can weigh in on this, let me know. I'm also not sure if there needs to be a minimum php version;

I have one live site using this now and it's working great; But before submitting to mods directory, would be better if there was some additional testing by other users.

  • Like 11
Link to comment
Share on other sites

Hi Marc

Much prefer this name - makes more sense. Will test it out (functionality-wise) today.

You don't need to namespace it if you're maintaing compatibility with PW-legacy. I don't namespace my module files, but only everything outside of them. For example, Typographer uses two namespaces: Rockett and Typographer, both of which are imported via the PW class loader. Everything should work fine in legacy, so long as you don't use any features that are only available after 3.0.62 as legacy will probably only be brought up to speed when the next 3.x stable comes out. 

In terms of PHP compatibility, I make it a rule to support only 5.6+, as it is currently the oldest version with security support. With that said, my phpfmt (mentioned below) is configured to use PHP 5.4-style arrays.

Some other recommendations from my side:

  1. Be consistent with spaces/tabs. Tabs are generally frowned upon on the PSR side of things, but it's really up to you, provided it's consistent. I use four spaces for indentation, and I also use phpfmt in Sublime to automatically format my code.
  2. in processForm(), you're pulling in the page title within the walls of a translation helper. As far as I know, this doesn't work, so you'll need to use sprintf to import the page title: sprintf($this->_('Saved: %s'), $this->wire('page')->title)
  3. wire is imported into the Process, so can use $this->wire(…) everywhere that doesn't have a static scope, instead of the wire() helper.

Hope that helps. 😊

  • Like 4
Link to comment
Share on other sites

Thanks @Mike Rockett!

5 hours ago, Mike Rockett said:

Be consistent with spaces/tabs. Tabs are generally frowned upon on the PSR side of things, but it's really up to you, provided it's consistent. I use four spaces for indentation, and I also use phpfmt in Sublime to automatically format my code.

currently as far as i know/can see in Sublime, the module follows the PW coding guide, so only uses tabs

I fixed all the other items according to your recommendations, commit after testing..

Link to comment
Share on other sites

You're welcome.

25 minutes ago, Macrura said:

currently as far as i know/can see in Sublime, the module follows the PW coding guide, so only uses tabs

The GH editor is showing me spaces in some places, and so the indentation appears inconsistent. 

I wasn't actually aware of a style guide for PW (I've now seen it). I tend to stick to PSR1 and 2 along with the following configuration:

Spoiler

[
	"AddMissingParentheses",
	"AutoSemicolon",
	"ClassToSelf",
	"DocBlockToComment",
	"DoubleToSingleQuote",
	"EchoToPrint",
	"GeneratePHPDoc",
	"IndentTernaryConditions",
	"MergeElseIf",
	"NewLineBeforeReturn",
	"OrderMethod",
	"OrganizeClass",
	"PrettyPrintDocBlocks",
	"PSR2EmptyFunction",
	"ReindentSwitchBlocks",
	"RemoveSemicolonAfterCurly",
	"RemoveUseLeadingSlash",
	"ReplaceIsNull",
	"ReturnNull",
	"ShortArray",
	"StripNewlineAfterCurlyOpen",
	"StripSpaceWithinControlStructures",
	"WrongConstructorName"
],

 

 

  • Like 2
Link to comment
Share on other sites

By strange coincidence, I was just thinking that maybe PW should have a standard EditorConfig file as part of the suite. Whilst it does not address all of the code styling issues raised above, it would allow us to all get the tabs/spaces/line endings/whitespace trimming right for this project by just using an editor that either supports EditorConfig out of the box, or via a plugin. I've started using it on my current project and it seems to work quite well.

  • Like 4
Link to comment
Share on other sites

26 minutes ago, netcarver said:

By strange coincidence, I was just thinking that maybe PW should have a standard EditorConfig file as part of the suite. Whilst it does not address all of the code styling issues raised above, it would allow us to all get the tabs/spaces/line endings/whitespace trimming right for this project by just using an editor that either supports EditorConfig out of the box, or via a plugin. I've started using it on my current project and it seems to work quite well.

Didn't know there was some sort of universal config like that. Tried it out in Sublime, works well!

Link to comment
Share on other sites

13 hours ago, Mike Rockett said:

Tabs are generally frowned upon on the PSR side of things

Tabs 4 Life, brah! There is no more definitive authority than Richard Hendricks:

(I've posted that before but could not resist)

But seriously, the PW code style gets things so right. The braces style too. Some reasoned argument:
https://github.com/php-fig-rectified/fig-rectified-standards/blob/master/Reasoning-Tabs-vs-Spaces.md
https://github.com/php-fig-rectified/fig-rectified-standards/blob/master/Reasoning-Brace-Styles.md

 

  • Like 1
  • Haha 2
Link to comment
Share on other sites

@Robin S They make some valid arguments, though I'm used to fig. On the flip side, their readmes use spaces for indentation, even in code blocks that state that a tab should be used instead. ;-) Good video though - hadn't seen that before.

Edit: Anyways, let's not hijack the thread - we could always open up a new one to discuss these things. (Sorry, Marc...)

Link to comment
Share on other sites

8 minutes ago, adrianromega said:

Interesting module, but how are you suppose to access all the defined fields in the front-end ?

I'm working on the github wiki which will include those instructions, but here it is in a nutshell:

Once you have created the process page for the settings, those settings are available using the process name, so if you made a page with the name theme-settings, you would do this:

$factory = $modules->get("SettingsFactory");
$themeSettings = $factory->getSettings('theme-settings');

the settings are delivered as a WireArray (or can be delivered as a plain array getSettingsArray('name-of-process); Here is the bar dump of those settings, using default wireArray;

59e2496382961_My_Great_Site__The_Best_Site_In_the_Universe.jpg.d38e21898e8c5b3ccc15fcf637f38993.jpg

In some scenarios i'm getting the raw array and merging it with some other hardcoded array, like for outputting JSON-LD schema:

Person.schema.php:

<?php namespace ProcessWire;

if(empty($item)) $item = $page;
if(!isset($tag)) $tag = true;

$jsonld = array(
	"@context" 		=> $tag ? "http://schema.org/" : '',
	'@type'			=> 'Person',
	'mainEntityOfPage' => array(
		'@type' => "WebPage",
		'@id'	=> $pages->get(1)->httpUrl,
	)
);

$factory = $modules->get('SettingsFactory');
$personSchema = $factory->getSettingsArray('schema-person');
$jsonld = array_merge($jsonld, $personSchema);

// add image here...
$profileMedia = wire('pages')->get("template=media, media_roles.name=schema-profile, images.count>0");
if($profileMedia->id) {
	$image = $profileMedia->images->first()->width(696);
	$jsonld['image']		= array(
		"@type" => "ImageObject",
		'url'	=> $image->httpUrl,
		'height'=> $image->height,
		'width' => $image->width
	);
}

$jsonld = array_filter($jsonld);
if(!$tag) {
	return $jsonld;
} else {
	if($user->isLoggedin()) {
		$jsonld = json_encode($jsonld, JSON_PRETTY_PRINT);
	} else {
		$jsonld = json_encode($jsonld);
	}
	echo '<script type="application/ld+json">' . $jsonld . '</script>';
}

 

 

  • Like 2
Link to comment
Share on other sites

Thanks for info, now is all clear.

Using your module you can define all kind of fields, except for InputfieldImage and InputfieldFile.... what is your suggestion to have in "settings"  fields for images or files (for logoes, backgound image, etc) ?

I hope you understand what I mean....

 

Link to comment
Share on other sites

On 10/23/2017 at 12:02 PM, adrianromega said:

what is your suggestion to have in "settings"  fields for images or files (for logoes, backgound image, etc) ?

Since i typically maintain separate pages for those types of media (in a media library for every site), it is just a matter of setting up page select field. I use selectize so that the user can see what they are selecting. Also if i use a page for logo, then they can update the logo from the media library without having to change the setting; or they can add several logos to the media library and then select which one to use on the settings page.

I don't yet know how to support image/file fields natively in this module, although since the settings pages themselves are pages of template admin, it might be possible. I was actually able to use both image and file fields and upload an image, however there are still errors with the value of the inputfield not yet working...

In other news, here are some new screenshots of settings panels using UiKit theme, including a working example of using  WireTabs:

59f4d949123a1_Theme_Settings__ProcessWire__localhost.thumb.jpg.bfb1461cded2a615e778a50d8bea6833.jpg

59f4d950c8e71_WireTabs_Testing__ProcessWire__localhost.thumb.jpg.13ddd192e24c657e684b2a01e9e95db0.jpg

 

 

 

  • Like 5
Link to comment
Share on other sites

thanks for your reply.

I have tried also the new version with support for InputfieldWrapper.

Based on your example, wiretabs-example.php, I have tried to use 2 InputfieldFieldsets inside first wiretab (InputfieldWrapper inside InputfieldWrapper), the display of fields is fine, but it is not saving values of fields properly...depends on the position of the nested InputfieldWrappers, some values are saved, some are not. With only one InputfieldWrapper inside another InputfieldWrapper, all is fine, but with more nested InputfieldWrappers, something is wrong.

for the config below for example, is not saving the field values form the first InputfieldFieldset.

 

<?php

/**
 * since you can only return 1 array to the module, you have to wrap 
 * the tabs in an inputfield wrapper
 */
$inputfields = new InputfieldWrapper();

//---------------------------------------------------
$general = [
    [
        'name' => 'site_name',
        'label' => __('Site Name'),
        'type' => 'InputfieldText',
        'value' => ''
    ],
    [
        'name' => 'email_address',
        'label' => __('E-mail'),
        'type' => 'InputfieldEmail',
        'value' => ''
    ],
    [
        'name' => 'telephone',
        'label' => __('Telephone'),
        'type' => 'InputfieldText',
        'value' => ''
    ],
    [
        'name' => 'fax',
        'label' => __('Fax'),
        'type' => 'InputfieldText',
        'value' => ''
    ],
];



$general2 = [
    [
        'name' => 'set_1',
        'label' => __('Setting 1'),
        'type' => 'InputfieldText',
        'value' => ''
    ],
    [
        'name' => 'set_2',
        'label' => __('Setting 2'),
        'type' => 'InputfieldText',
        'value' => ''
    ]
];

$general3 = [
    [
        'name' => 'set_3',
        'label' => __('Setting 3'),
        'type' => 'InputfieldText',
        'value' => ''
    ],
    [
        'name' => 'set_4',
        'label' => __('Setting 4'),
        'type' => 'InputfieldText',
        'value' => ''
    ] 
];



$tab = new InputfieldWrapper();
$tab->attr('title', 'General');
$tab->attr('class', 'WireTab');




$advanced = new InputfieldFieldset();
$advanced->label = __('Advanced Settings');
$advanced->description = __('These settings are not required');
$advanced->columnWidth = 50;
$advanced->add($general2);
$tab->add($advanced);



$advanced = new InputfieldFieldset();
$advanced->label = __('Advanced Settings');
$advanced->description = __('These settings are not required');
$advanced->columnWidth = 50;
$advanced->add($general3);
$tab->add($advanced);



$tab->add($general);

$inputfields->append($tab);

//---------------------------------------------------
$location = [
    [
        'name' => 'address',
        'label' => __('Address'),
        'type' => 'InputfieldText',
        'required' => true,
        'value' => ''
    ],
    [
        'name' => 'postal_code',
        'label' => __('Postal code'),
        'type' => 'InputfieldText',
        'required' => true,
        'value' => '',
        'columnWidth' => 33
    ],
    [
        'name' => 'city',
        'label' => __('City'),
        'type' => 'InputfieldText',
        'required' => true,
        'value' => '',
        'columnWidth' => 67
    ],
];

$tab = new InputfieldWrapper();
$tab->attr('title', 'Location');
$tab->attr('class', 'WireTab');
$tab->add($location);
$inputfields->append($tab);

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


return $inputfields;

 

  • Like 1
Link to comment
Share on other sites

  • 2 weeks later...
1 hour ago, Zeka said:

Great module. Thank you for your work. Just curious is there some limitation of input field types? 

It is probably limited to the types of fields you can use generally in module configs, and currently there is no way to handle custom processing of form data, it uses the default $form->process() function from the core; If there are any specific fields you want to test let me know and i'll give them a go; The obvious ones that won't work are files and images, as well as any profileds like tables, repeaters and stuff like that;

Link to comment
Share on other sites

3 hours ago, Zeka said:

So there are no repeatable field types that we can use with the module. 

Yeah, i haven't found any way to do repeatable content yet, but it could be possible to roll your own multiplier field using text inputs and some javascript. If i get around to that i will post how it is done..

Link to comment
Share on other sites

the input form is all native PW; so you just supply your array of field definitions using the correct keys for that inputfield type;

no graphical ui would be possible, but there is a kitchen sink file where you just grab the type of inputfield you want, paste it in to your fields array, change the settings and bob's your uncle.

  • Like 3
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By sms77io
      Hi all,
      we made a small module for sending SMS via Sms77.io. It supports sending to one and multiple users.
      You can download it from GitHub and follow the instructions on how to install it - it is quite easy. An API key is required for sending, get yours for free @ Sms77 and receive 0,50 €.
      Hope this helps somebody and we are open for improvement suggestions!
       
      Best regards
      André
    • By opalepatrick
      I see old posts saying that repeaters are not the way to go in Custom Process Modules. If that is the case, when using forms (as I am trying to do) how would one tackle things like repeat contact fields where there can be multiple requirements for contact details with different parameters? (Like point of contact, director, etc) or even telephone numbers that have different uses?
      Just for background I am creating a process module that allows me to create types of financial applications in the admin area (no need to publish any of this, pure admin) that require a lot of personal or company information.
      Maybe I am thinking about this incorrectly?
    • By jploch
      Hey folks,
      for a module (a pagebuilder based on PageTable) I need to save some settings as JSON. The values are saved for each page table item (a pw page). It's working well, but I am looking for ways to improve the structure I have. As I'm not that experienced with JSON, maybe someone more experienced can take a look and tell me if my approach is good practice. 

      My goal is to make all the items accessible by page id, without looping over them (using objects instead of arrays):
      // access from template with pw page var $jsonObject->items->{$page}->cssClass; Her is an example of my JSON structure:
      { "items": { "3252": { "id": "3252", "cssClass": "pgrid-main", "breakpoints": { "base": { "css": { "grid-column-end": "auto", "grid-row-end": "auto", "grid-column-start": "auto", "grid-row-start": "auto", "align-self": "auto", "z-index": "auto", "padding-left": "60px", "padding-right": "60px", "padding-top": "60px", "padding-bottom": "60px", "background-color": "rgb(255, 255, 255)", "color": "rgb(0, 0, 0)" }, "size": "@media (min-width: 576px)", "name": "base" } } }, "3686": { "id": "3686", "cssClass": "test_global", "breakpoints": { "base": { "css": { "grid-column-end": "-1", "grid-row-end": "span 1", "grid-column-start": "1", "grid-row-start": "auto", "align-self": "auto", "z-index": "auto", "padding-left": "0px", "padding-right": "0px", "padding-top": "0px", "padding-bottom": "0px", "background-color": "rgba(0, 0, 0, 0)", "color": "rgb(0, 0, 0)" }, "size": "@media (min-width: 576px)", "name": "base" } } }, "3687": { "id": "3687", "cssClass": "block_editor-3687", "breakpoints": { "base": { "css": { "grid-column-end": "span 2", "grid-row-end": "span 1", "grid-column-start": "auto", "grid-row-start": "auto", "align-self": "auto", "z-index": "auto", "padding-left": "0px", "padding-right": "0px", "padding-top": "0px", "padding-bottom": "0px", "background-color": "rgba(0, 0, 0, 0)", "color": "rgb(0, 0, 0)" }, "size": "@media (min-width: 576px)", "name": "base" } } }, "3696": { "id": "3696", "cssClass": "block_editor-3696", "breakpoints": { "base": { "css": { "grid-column-end": "span 2", "grid-row-end": "span 1", "grid-column-start": "auto", "grid-row-start": "auto", "align-self": "auto", "z-index": "auto", "padding-left": "0px", "padding-right": "0px", "padding-top": "0px", "padding-bottom": "0px", "background-color": "rgba(0, 0, 0, 0)", "color": "rgb(0, 0, 0)" }, "size": "@media (min-width: 576px)", "name": "base" } } } }, "breakpointActive": "base", "breakpointActiveSize": "@media (min-width: 576px)" }  
    • By hellerdruck
      Hi all
      I need to export all the texts from a website to a translation company (as json or csv or txt...). How can this be done? Of course manually, but this website is huge and it would take me years...
      Also, as a second step, importing the translation ...
      Any ideas anyone? Tutorials? Plugins?
      Thanks for your help.
    • By jonatan
      So... I thought (for some stupid reason I can't even recall now no wait now I remember.. I wanted to hide the "Trash" for "editor" role users) that it'd be super duper smart to "Enable access control" for the field "process" on the admin template.... Really really stupid.... Now all I get is:

       
       
       
      – when I go to mywebsitedomain.com/admin
      but.... my website domain.com and all its subpages works perfectly fine! So it's ONLY the /admin (processwire) which throws a 503 at me. 
      🥵🤯☠️💩😭😱
      S.O.S.
×
×
  • Create New...