We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 23879
    • 18 Posts
    In it’s current form, MODx only supports three document types (2, really). Folders, documents (type in both cases is document) and a weblink (reference). And most of the time, that enough. Though, for a client of mine, I wanted to add a photo gallery to the document tree so they didn’t have to fiddle around in the Module section to start the module (that’s alot less intuitive as far as I can tell).

    And, as far as I could see, MODx didn’t support that out of the box. (Well, alot has been done to make it easy, but here are the finishing touches). Note: the modifications were origionally done against the 0.9.1 release, but the line numbers below resemble the 0.9.2 (and 0.9.2.1)

    manager/actions/dynamic/mutate_content.dynamic.action.php
    LINE 700
    REPLACE
               <?php if($content['type']!="reference" && $_REQUEST['a']!=72) { ?>  
    WITH:
               <?php if($content['type']=="document" && $_REQUEST['a']!=72) { ?> // there are some more !="reference" things around, but only this one has to be changed (as far as I can tell)
    
    LINE 742
    REPLACE:
     			<input type="hidden" name="type" value="reference" />
    WITH:
     			<input type="hidden" name="type" value="<?php echo $content['type']?>" />
    
    ## Below is optional, and only needed if you want your custom document to display above the Access Permissions block, which will usually be the case
    
    LINE 1029
    ADD:
     // invoke OnDocFormRender event
     $evtOut = $modx->invokeEvent("OnDocFormRender",array("id" => $id));
     if(is_array($evtOut)) echo implode("",$evtOut);
    
    LINE 1104
    REMOVE:
     <?php
     	// invoke OnDocFormRender event
     	$evtOut = $modx->invokeEvent("OnDocFormRender",array("id" => $id));
    	if(is_array($evtOut)) echo implode("",$evtOut);
     ?>
    


    That’s all that is needed to change to the core, though it still doesn’t do much... (Nothing different at least smiley). Next, we’ll need to add two menu items (i’d love to be able to do that dynamically).

    File: /manager/frames/l4mnu.php
    LINE 80:
    ADD
    <li><a onclick="this.blur();" href="index.php?a=85&cft" target="main">My new custom folder type</a></li>
    <li><a onclick="this.blur();" href="index.php?a=72&cdt" target="main">My new custom document type</a></li>
    


    For "folders" (eg, a gallery or a shopping cart administration) the href in the link should be index.php?a=85&<a name for your type>. (You’ll see why <a name for your type> is needed soon). And for documents it should be index.php?a=72&<another name>. (Note, those names should be different!).
    There is no limitation to the number of custom documents and folders smiley.

    Now, the only thing to do is, write a plugin to handle your document. This is the bare minimum to get this to work:
    if(!function_exists('Find_type_slow')){
    	function Find_type_slow($id){
    		if($id == '') return false;
    
    		$query = "SELECT type FROM " . $GLOBALS['modx']->getFullTableName('site_content') . ' WHERE id=' . $id;
    		return $GLOBALS['modx']->db->getValue($GLOBALS['modx']->db->query($query));
    	}
    }
    
    $e =& $modx->Event;
    $isFolder = isset($_REQUEST['cft']) || $content['type'] == 'my type of folder' || Find_type_slow($id) == 'my type of folder';
    
    if($isFolder){
    	if($e->name == 'OnDocFormRender'){
    		$e->output('<p>The form for createing and editing your type</p>');
    		$e->output('<input type="hidden" name="cft" value="">'); // name should be the same as the $_REQUEST parameter we're checking above!
    	}elseif($e->name == 'OnBeforeDocFormSave'){
    		if($mode == 'new'){
    			// Insert your new folder in the database.
    			// Note: you don't have to do the General settings dialog, MODx does that for you. You only need to save YOUR document to the database
    		}else{
    			// Update your new folder. Same note as above applies
    		}
    
    		$GLOBALS['type'] = 'my type of folder';
    		$GLOBALS['isfolder'] = true; // Set to false if you used id=72
    	}elseif($e->name == 'OnDocFormDelete'){
    		// Database query for deleting your document
    	}
    }
    

    Lastly, configure the plugin to handle the OnDocFormDelete, OnBeforeDocFormSave, OnDocFormRender events (more events doesn’t hurt, but these are the only events we need).

    As a final note, there is no OnDocTreePrune (or something) event, so you’ll have to delete your type completely.

    Hope I’ve helped at least someone with this!

    Edit: forgot one thing!
    If saving the document doesn’t work for some reason (or any other event), this code could be helpfull!
    $e->alert("<strong>Warning:</strong><br>This cannot be saved!");
    $modx->manager->saveFormValues(72);
    $modx->sendRedirect('index.php?a=72&pic');
    exit;
    
      • 14575
      • 21 Posts
      At first glance it looks awesome!
      I think this makes my dream come true from an old topic. I hope official support will be implemented around this and hopefully it will be added into the core release tongue
        • 23879
        • 18 Posts
        Quote from: jojo1313 at Apr 27, 2006, 08:17 AM

        At first glance it looks awesome!
        I think this makes my dream come true from an old topic. I hope official support will be implemented around this and hopefully it will be added into the core release tongue
        Nice to know you like it, but before it goes in the core (and if), i think there should be a decent way to create dynamic menus and an OnDocTreePrune event. (I currently don’t have the time to do that, but I did start looking at what needs to be done). But yeah, it would (ofcouse) be nice to see this in the core. smiley (That shouldn’t be all that difficult, as it’s just the first code block posted above).
        At the moment, I’m re-building EPG2 to suit my needs - eg, work with this hack -. (And recode it a bunch.) Which should be released quite soon (give me a week or maybe two).
          • 25663 MODX Staff
          • 12,272 Posts
          Nice work. smiley

          You might get inspired a bit by the new module menu in 0.9.2 which dynamically builds the module menu based on what modules are loaded in your system.
            Ryan Thrash, MODX Co-Founder
            Follow me on Twitter at @rthrash or catch my occasional unofficial thoughts at thrash.me
            • 23879
            • 18 Posts
            Quote from: rthrash at Apr 27, 2006, 09:10 AM

            Nice work. smiley
            Thanks smiley

            You might get inspired a bit by the new module menu in 0.9.2 which dynamically builds the module menu based on what modules are loaded in your system.
            As far as I can tell, that doesn’t, currently, do much. If I decide to proceed with the dynamic menu implementation, it’ll have be a little more compex. But, it’s a good start. Though, it’s a good thing that the manager’s menu system isn’t that complicated, the real pain probably is integrating it with the current manager, as I’d like to remove the huge switch-statement in index.php.
              • 28042 ☆ A M B ☆
              • 24,524 Posts
              Doesn’t do much? In the main menu there is a Modules item. Click on that, and the submenu shows all the modules installed, plus a Manage Modules item. Click on any of the installed modules listed to run that module. Click on Manage Modules to get the old Manage Modules page for editing etc. the modules. So just Modules -> ModuleName to run a module; that’s pretty simple.
                Studying MODX in the desert - http://sottwell.com
                Tips and Tricks from the MODX Forums and Slack Channels - http://modxcookbook.com
                Join the Slack Community - http://modx.org
                • 23879
                • 18 Posts
                Quote from: sottwell at Apr 27, 2006, 10:11 AM

                Doesn’t do much?
                I meant the source, 5 lines isn’t doing much, although it’s a great improvement.

                What I meant:
                <?php
                      $list = '';  // initialize list variable 
                      $rs = $modx->db->select('*',$modx->getFullTableName('site_modules'));  // get modules
                      while($content = $modx->db->getRow($rs)) {
                        $list .= '<li><a onclick="this.blur();" href="index.php?a=112&id='.$content['id'].'" target="main">'.$content['name'].'</a></li>';
                    	}
                    	echo $list;
                    ?>
                


                But it’s quite a big (relative) step from there, to make the full menu dynamic in which you’re dealing with child/parent relationships, access rights, and possibly some more. (And the one-time steps, like trimming down index.php and move some stuff around).
                  • 22303 MODX Staff
                  • 10,725 Posts
                  I’m a little lost on this HACK -- what is the purpose of this? MODx supports custom content types on documents, so I’m not quite sure why anyone would need this hack. Is there some confusion between content-type, as handled by browsers and defined by mime-type mappings, and modx document types, which have no meaning to anything other than internally to MODx (i.e. distinguish between a regular page or a symbolic link representation of it). Or maybe I just don’t follow the reasoning. Can you help me understand the motivation for this?
                    • 14575
                    • 21 Posts
                    *cheers on for PrisonerOfPain *

                    One situation could be that you might have some standard look for some pages (player profiles for example) and they would require a main document and then sub-documents in the MODx document tree. Maybe you have a bunch of content editors that are responsible for creating those pages. Sure, you can teach them how to make ’em but in some way it feels a bit awkward for them to create a main page and those subpages. It would be so much easier if they could just click *New Page*, select a MODx document type (with maybe a new document type created by you called PlayerProfile) and then you’d get up all the right forms when you create the document (so instead of the main content form that is with the default MODx document type you might get fields like age, stats and what not and it would be more straight forward for the content editors).

                    A new member in the community made a post the other day and mentioned DotNetNuke and maybe along with some other forum users I giggled a bit when I heard the Nuke name because I aint got a good experience with PHP-Nuke. I checked out DotNetNuke though and they got some impressive stuff. For example I liked over there how you could drag modules to a page and thus have multiple fields per page (for example you could drag a text module, announcement module etc). Maybe the modules are the way to go but then it might be sweet to create some sort of default set-up and be able to store it so that content editors don’t have to know how to add modules and things like that. Those default set-up’s could for example be different MODx document types.

                    Bah, I think I’m doing a bad job at explaining what I mean, lol.
                    *points at the picture in the post below because pictures often say more than a thousand words*
                      • 23879
                      • 18 Posts
                      Quote from: OpenGeek at Apr 27, 2006, 11:30 AM

                      I’m a little lost on this HACK -- what is the purpose of this? MODx supports custom content types on documents, so I’m not quite sure why anyone would need this hack. Is there some confusion between content-type, as handled by browsers and defined by mime-type mappings, and modx document types, which have no meaning to anything other than internally to MODx (i.e. distinguish between a regular page or a symbolic link representation of it). Or maybe I just don’t follow the reasoning. Can you help me understand the motivation for this?
                      It doesn’t have anything to do with the MIME-Type, nor the Content-Type. The purpose I built this hack was to be able to place my clients photo gallery directly in the content menu. Normally you would’ve done that with a snippet which you just pass parameters to ([!PhotoGallery?galleryid=15&....!]) but I wanted the gallery to be controlled (and created) from within the normal MODx GUI.

                      Now, that could’ve been done using modules, which involves allot more steps (Modules -> MyPhotoGalleryModule -> Run -> Create Gallery, etc) or (Modules ->MyPhothoGalleryModule -> Create Gallery). But that doesn’t seem "natural" or intuitive to me. Because, if I create a document, I’ll go Content -> New document. Why can’t I do Content -> New gallery, or Content -> New picture). And this was the solution I came up with.

                      Look at the screenshot, that might clarify some things.