Jump to content
Macrura

Settings Factory

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 10

Share this post


Link to post
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

Share this post


Link to post
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..

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

Oh, and just to follow up on the PHP compatibility. It's currently compatible with 5.4+. If the square array notation is changed in both files (three small occurrences in total), then it supports 5.2+.

  • Like 1

Share this post


Link to post
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

Share this post


Link to post
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!

Share this post


Link to post
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

Share this post


Link to post
Share on other sites

I would have taken an exception in this particular case :)

  • Like 1

Share this post


Link to post
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...)

Share this post


Link to post
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

Share this post


Link to post
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....

 

Share this post


Link to post
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

Share this post


Link to post
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;

 

Share this post


Link to post
Share on other sites

ok i think i have fixed this, and improved the extraction process for the inputfields. Can you try the latest version?

Share this post


Link to post
Share on other sites

@adrianromega - thanks for taking it for a test drive, and identifying that problem!

I ended up rewriting the method that extracts the inputfields and now it should work a lot better thanks to your testing of that scenario.

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
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;

Share this post


Link to post
Share on other sites

Actually I was thinking about Profields ( tables, multiplier). So there are no repeatable field types that we can use with the module. 

Share this post


Link to post
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..

Share this post


Link to post
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 2

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By alanxptm
      Hi, first time here.
      I've been working on my first site with PW and it has been a pleasure, I'm around 75% of structure and logic completion I think, and polishing some things now.
      My question is: I have a parent 'category' page that musn't be editable by the author role, but they must be able to add children 'post page' to the 'category'.
      I've been playing with the settings and can just let the author create childs if is able too to edit the parent category, so.. How can I do it?
       
       
    • By louisstephens
      So I have been hard at work creating url segments for a template (api) and everything is working swimmingly in creating a simple end point for svelte.js. I have however, run into a few questions that I can wrap my head around.
      In my api template I have:
      if($input->urlSegment1 === 'clients') { header('Content-Type: application/json'); $clients = $pages->find("template=clients"); $client_array = array(); foreach ($clients as $client) { $id = $client->id; $title = $client->title; $url = $client->url; $clientName = $client->client_name; $clientColor = $client->client_color->value; $assigned = $client->assigned_to->user_full_name; $client_array[] = array( 'id' => $id, 'code' => $title, 'name' => $clientName, 'associated_users' => $assigned, 'url' => $url ); } $client_json = json_encode($client_array, true); echo $client_json; } The output json from this is:
      [ { "id":1644, "code":"abc", "name":"Test Name", "associated_users":null, "url":"\/pw\/clients\/abc\/" }, { "id": 1645, "code": "xyz", "name": "Test Name", "associated_users": null, "url": "\/pw\/clients\/xyz\/" }, ] I was curious is it possible to add in "clients" before this output json so it would appear as 
      clients: [ { "id":1644, "code":"abc", "name":"Test Name", "associated_users":null, "url":"\/pw\/clients\/abc\/" }, { "id": 1645, "code": "xyz", "name": "Test Name", "associated_users": null, "url": "\/pw\/clients\/xyz\/" }, ] I was not really sure of how to tackle this in my php code, and have spent more time than I care to admit trying to figure it out. Another question I have is that "associated_users" is returning null, which in this instance is correct. It is a multi page field that is set to pull a custom name field from the users template, ie "Louis Stephens" would be associated with the first page. I understand that I need to use a foreach to get the correct data, but I was really unsure of how to place this inside an array, or update the array with the new data. Any help with any of this would greatly be appreciated.
    • By MateThemes
      Hello everyone!
      I have searched the forum for quite a long time and I tried some solutions for my topic but nothing seems to work.
      I need to create a Settings Page and for a native feeling I want to create it under the main navigation on top. The settings page should hold the Main Logo, some styling and other settings. As I said nothing seems to work for me. I tried to create a Page under Admin with Admin Template and ProcessPageEdit but then I can't assign an image field. 
      I don't want to write a module because it is to much work for only 3 settings.
      I hope someone of the forum could help me out!
      Have a nice day!
    • By louisstephens
      So I reread my first draft, and it made absolutely no sense (I deleted it to hopefully better explain myself).  I am trying to make a system (that to me is a bit complicated) utilizing jquery and processwire together. My whole goal is to put a url like https://domain.com/launch?first_name=jim&occupation=builder in a script tag on another site(just a localhost .php page) to then pull out the data for that person and append to divs etc. Basically, the initial script tag would point to "launch" which has a content-type of "application/javascript". Using jquery, I would pull out the persons name and occupation and then make a specific ajax get request to "domain.com/api" (in json format) for a look up of the person. Essentially then I could pull that particular person's information from the json data, and do with it how I please in the "launch" page.  In processwire, I have a page structure like:
      People -Jim Bob (template: person ) --Occupations (template: basic-page) ---Builder (template: occupation) ---Greeter (template: occupation) It is really just a bunch of people with their occupations and a few fields to the occupation template. With the "api" (template: api) url, I was hoping to return all the data (of people) in json format like:
      Example Format:
      { "id": 1, "title": "Jim Bob", "occupations": { "builder": { "id": 44, "title": "Builder", "years_worked": 1, "etc": "ect", }, "Greeter": { "id": 44, "title": "Greeter", "years_worked": 1, "etc": "ect", }, } } Where I get lost is really outputting the page names and nesting in the occupations into json. I have used Pages2JSON before, but I was a bit lost on how to implement what i was thinking.
       
      I have access to all the local host files, but I was hoping to kind of build out a "system" where I could place the script tag/parameters in any project, and be able to interact with the data without doing an ajax call on the actual site. In a way, this would keep processwire handling all the data and requests, and my other "projects" just with a simple script tag. This might all be way too much/over complicated, but I couldn't quite wrap my head around how to achieve it. 
    • By Arunesh Dutta
      Hello all
      I am newbie.Wanted to know does processwire will allow to display external website content and other sources to my website using API powered by processwire
×
×
  • Create New...