Jump to content

thetuningspoon

Members
  • Posts

    691
  • Joined

  • Last visited

  • Days Won

    6

Posts posted by thetuningspoon

  1. Why would this be triggered by a guest on the site, though? I don't recall any of these sites saving or creating fields or pages from within templates.

    Edit: I also know for certain that at least one of them didn't have any changes made on the backend by the client during this time, either.

  2. I recently upgraded a few of my older ProcessWire sites to 2.5.23. Soon thereafter I've been getting the following error report sent to me from several of the sites:

    Page: .../http404/

    User: guest

    Exception: SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '41-0' for key 'PRIMARY' (in .../wire/core/FieldtypeMulti.php line 261)

    I can't seem to replicate the issue, and I'm not even sure where it's happening because reportedly it is happening on the 404 page?

    Any ideas?

  3. Like the title says, I upgraded one of my older sites to PW dev 2.5.22 and TinyMCE doesn't seem to be working with the new links Attributes tab. If I try to set a link to open in a new window and then check the code in TinyMCE, it doesn't add target="_blank" to the code.

    I have tried refreshing the modules and clearing browser cache. Any other steps I can try? And are others using TinyMCE successfully with the new features?

  4. Adrian,

    If I hook into InputfieldSelect::render instead of InputfieldPage::render then your code works (but of course that's not what I want).

    The module is extending WireData and I've commented out all my other hooks to make sure nothing else might be causing the problem.

    I just uninstalled my module and tested your code in admin.php. No luck  :(

  5. Thanks for the suggestions. I just discovered addClass() while looking through the code in Inputfield.php.

    Unfortunately neither is working. The particular Inputfield I'm trying to work with is InputfieldPage. I'm wondering if the problem is that this is a sort of "hybrid" inputfield? It doesn't seem to use the attributes in its render() function at all, as far as I can tell.

    EDIT: I'm now trying to hook after InputfieldPage::getInputfield to see if that will work. Still no luck.

    public function init() {
        $this->addHookAfter('InputfieldPage::getInputfield', $this, 'hookAddCssClass');
    }
    
    public function hookAddCssClass(HookEvent $event) {
    		
    		$inputfield = $event->return;
    		$inputfield->addClass('myClassName');
    		$event->return = $inputfield; 
    	}
    
    • Like 1
  6. Adrian,

    I just played around with this some more and discovered that the api call was unnecessary. The only thing I was missing was the "object" property. So $event->object->editable returns what I'm looking for. Here is my modified hook:

    public function hookAfterGetConfigInputFields(HookEvent $event) {
    		if($event->object->hasFieldtype !== false) { 
    			$field = $this->modules->get('InputfieldCheckbox');
    			$field->attr('name', 'editable'); 
    			$field->attr('value', 1); 
    			$field->label = $this->_('Use page edit link?');
    			$field->description = $this->_('If checked, pages selected with this field may be edited in a modal window.');
    			
    			if($event->object->editable) $field->attr('checked', 'checked'); 
    
    			$event->return->append($field);
    		}
    	} 
    • Like 1
  7. Have you checked the value of $event->editable ?

    I am not sure in your situation, but you might try this. Of course my ternary approach is not relevant, but you might need to get the value of editable like this:

    $field->attr('checked', $this->fields->get($event->object->name)->editable ? 'checked' : '' );

    Thanks Adrian, that did it! After posting I checked and discovered that the value of editable was being saved in the database, but just wasn't reflected in the GUI because $event->editable was returning nothing.

    I am a little confused how the $event variable works. What does "object" represent here?

  8. I'm trying to add a configuration option to InputfieldPage using a hook. I am able to create the new field (a checkbox) by hooking into InputfieldPage::getConfigInputfields so it shows up on the field's settings page, but when I try saving the field with the checkbox checked off, the setting does not save. (it remains unchecked)

    public function hookAfterGetConfigInputFields(HookEvent $event) {
    		if($event->hasFieldtype !== false) { 
    			$field = $this->modules->get('InputfieldCheckbox');
    			$field->attr('name', 'editable'); 
    			$field->attr('value', 1); 
    			$field->label = $event->_('Use page edit link?');
    			$field->description = $event->_('If checked, pages selected with this field may be edited in a modal window.');
    
    			if($event->editable) $field->attr('checked', 'checked'); 
    			
    			$event->return->append($field);
    		}
    	}
    
  9. You didn't even scratch on the surface yet... :) It's possible, just if it makes sense or there's isn't any drawbacks is a different question.

    If you want you can overwrite and change almost everything. And if not, there's maybe just a hook needed to add to core. There's many different approaches as always in PW.

    Fo example you could set all templates to have "main" as alternative template 

    foreach($this->templates as $tpl){
         if($tpl->name != "admin") $tpl->altFilename = "main";
    }

    Depends really where you put this code. Most sense would make inside a autoload module like the HelloWorld.module. But then you have ALL templates always use main.php. You can't change it unless you add more logic to this script.

    After all I've come away from the "delegate" approach I've posted here, and use the one Ryan proposed. Including the main.php at the end of a template file makes things easier when you want to add stuff per template. Some more flexibility after all. 

    Hi Soma, I've recently been experimenting with your original delegate approach and I like the idea of having a single main template file that controls everything else. But like thistimj mentioned, it doesn't give you a place to set variables or put in template-specific logic before the view is loaded. What do you think of the idea of having a separate templates/controllers/ folder where you store a controller file for each template (just like your views folder), and then including that automatically in main.php before you output the html and the view file? This way the programming logic is still kept separate from the view.

    So, in other words... Every template is set to use main.php.

    Then, main.php:

    1. Sets up any variables/arrays and loads in css files, scripts, php functions the that apply the site as a whole (site-wide controller)

       

    2. Loads the template-specific controller which adds to or modifies these variables/arrays to suit the particular template. The template controller would also include things like form processing.

       

    3. Outputs the basic html structure (header & footer) and with the css/scripts

       

    4. Includes the template-specific view (within the html structure)

    Some of the above parts could be further broken off into separate files, depending on the needs and complexity of the particular site. But now I am starting to question whether the 1-1 relationship of template controller to view really makes sense. So maybe the view(s) should be set as variables in the template controller, more like Ryan's method.

    In the end I suppose the two methods can end up very similar. The delegate approach just eliminates the need to include the same files from each template file (or setup the prepend and append for each in the admin).

  10. Hmm... When I try this with templates I get the error "You must save Fieldgroup 'X' before adding to Template 'X'"

    It seems like that would be the job of the setImportData() function to make sure that happens?

    Edit: Got it. Here's the template builder:

    protected function buildTemplatesFromJson($json) {
      	$data = is_array($json) ? $json : wireDecodeJSON($json);
      	
      	// Loop through each template in the JSON
      	foreach($data as $name => $templateData) {
      		unset($templateData['id']); // Get rid of the ID so it doesn't conflict with the new installation
      			
      		$template = $this->templates->get($name); // If the template exists, grab it
      		
      		// Create the template if it doesn't already exist
      		if(!$template) {
      			$template = new Template();
      			$template->name = $name;
      		}
      		
      		$template->setImportData($templateData); // Import the data for the field
      		
      		$fieldgroup = $template->fieldgroup;
      		$fieldgroup->save();
      		$fieldgroup->saveContext();
      		$template->save();
      		if(!$template->fieldgroup_id) {
      			$template->setFieldgroup($fieldgroup);
      			$template->save();
      		}
      	}
      }
    
    • Like 3
  11. Okay, so after playing around with this and looking at Ryan's code in ProcessFieldExportImport I was able to put together a simplified function to create fields from a JSON export. This only creates a field if it doesn't already exist, and you can do it one at a time or send in multiple fields at once.

    protected function buildFieldsFromJson($json) {
      	$data = is_array($json) ? $json : wireDecodeJSON($json);
      	
      	// Loop through each field in the JSON
      	foreach($data as $name => $fieldData) {
      			unset($fieldData['id']); // Get rid of the ID so it doesn't conflict with the new installation
      			
      			// Create the field only if it doesn't already exist
      			if(!$this->fields->get($name)) {
      				$field = new Field();
      				$field->name = $name;
      				
      				$field->setImportData($fieldData); // Import the data for the field
      				$field->save();
      			}
      		}
      }
    

    Calling it from within my module's install() function:

    $this->buildFieldsFromJson('PASTE_JSON_EXPORT_HERE');
    

    Hope that helps someone else. Now onto the templates...

    • Like 2
  12. Yes, I was looking that over. It hadn't occurred to me that the JSON export/import could be used in such a way.

    I'm thinking that it is still best to do it one field and one template at a time, so I can check for the existence of the item before creating it and also make sure I get the order correct when it comes to Page fields. But it should save tons of time either way!

    Edit: This looks a little more complex than at first glance, looking at ProcessFieldExportImport.

  13. I've been building some modules which use fields/pages/templates for data storage and manipulation. I'm nearing completion on one of these modules, and am going to have to move it from my development to my production PW installation on a different site.

    The problem is that most of the fields, templates, and structural pages were created via the admin UI, which means creating my install() function is going to be quite tedious. I suppose this is my fault for not creating these things via the API all along.

    Is there any kind of utility that exists that would help me generate this code, or is there something else I might be overlooking? If not, I guess I have a bit of coding ahead of me  ;)

  14. I have a hard time understanding what people mean by "MVC" sometimes, but it seems to me that the PW module system is natural for building this way. You can set the module to autoload and then use it as your Controller. Keeping all your logic in there, the template then becomes your View, and the Pages API already handles the Model side of things.

    But I could be totally wrong...

    • Like 2
  15. Got it! I found the Permissions class which is also based on PagesType and was able to find its instantiation in ProcessWire.php, which was helpful.

    I had to add the following to the init() method in my module:

    $customers = new Customers($this->templates->get('si-customers'), $this->pages->get("template=si-customers")); // Instantiates the Customers class
    $this->wire('customers', $customers); // Make the $customers variable available to templates
    
    

    My Customers class right now is just:

    <?php
    class Customers extends PagesType {}
    
    

    And is then required at the top of my module.

    • Like 4
×
×
  • Create New...