Hey all,
Custom Sidebar Manager for Evolution
Easily manage the sidebar of your website via drag and drop.
I have always wanted an easier way to maintain sidebar content for my clients. I had this idea where clients would be able to see the names of all the available sidebar chunks to choose from and then be able to select some to output and then be able to drag and drop sort them in the desired order. It seemed totally intuitive. Only problem was that it was difficult for the non developer.
Years have passed.
MODX implemented the custom TV input type for evolution 1.05. I heard about it, but never had the time to devote to it until now.
I watched ChuckTrucks amazing Youtube screencast and had also read Splitting Red's tutorial on the old modx wiki. I had also played with and implemented Temus' plugins to add multiphotos to a document. His tutorial had been translated into English by Sharkbait at www.kunane.com. I have sinced played around with a lot of permutations and have something to share with you.
It is rough.
It works.
I hope that you use it, improve it and then share your improvements with the community.
You will have to create one tv, one snippet with attached code and you will be good to go.
Here is how to implement it:
1. Create new tv named ourCustomTv
2. Give it the following values:
caption : sidebar
Input Type: Custom Input
Input Option Values: @INCLUDE manager/tvs/customtvSort.php
Widget: Delimited List, delimiter is comma
3. Link this new tv to template you'd like to have sidebar chunks output to.
4. Create a new chunk category called "sidebar".
5. Create a snippet named chunkParser and paste in the following code which is attached in the zip file:
$ar_chunks = explode(',',$chunks);
$ar_chunks = array_unique($ar_chunks);
$output = '';
foreach ($ar_chunks as $chunk) {
if ($chunk != '') {
$c = $modx->getChunk($chunk);
if ($c) $output .= $c;
}
}
if ($output != '' && isset($wrapperdiv)) {
$output = '<div id="'.$wrapperdiv.'">'.$output.'</div>';
}
return $output;
6. call it like this:
[!chunkParser?chunks=`[*ourCustomTv*]` &wrapperdiv=`sidebarChunks`!]
where [*ourCustomTv*] is the name of the custom TV and wrapperdiv is the name of the div that you want the output to be wrapped in.
You could also modify the snippet code below to change:
if ($output != '' && isset($wrapperdiv)) { $output = '<div id="'.$wrapperdiv.'">'.$output.'</div>';
To:
if ($output != '') { $output = $output;
And the chunks would be output in the place where the snippet is called without being wrapped in a div. In this case you would call the snippet like:
[!chunkParser?chunks=`[*ourCostomTv*]`!]
7. Download the zip file and and extract it in the root level of your site. I have included the files needed to get this to work.
8. If you don't want to download zip, paste code below into file named 'customtvSort.php' and save it in manager/tvs:
<!--
Notes:
This is a custom input Template Variable implementation based on a tutorial written by splittingred at http://wiki.modxcms.com/index.php/Create_TV-Based_Chunks and a 4 part youtube screencast presented by ChuckTruck at http://www.youtube.com/watch?v=Ufl50K37PWo&feature=mfu_in_order&list=UL
I have always wanted to be able to create a dynamic list of available chunks inside a category and them to be able to drag and drop sort them in the order you'd prefer. You can see a forum thread that we talked about it in mid 2009 at
https://forums.modx.com/thread/35945/create-tv-based-chunks---custom-sequential-sorting.
This solution pulls all chunks that live inside a preconfigured chunk category and generates a sortable list. Check the chunks you want to activate(output on page), sort away via drag and drop, click save and the selected chunks will output to your page in the place where you output the helper snippet included in these comments.
Have fun, improve and share!
-Noah Learner
www.learnerdesign.com
[email protected]
@noahlearner
Usage:
1. Create new tv named ourCustomTv
2. Give it the following values:
caption : sidebar
Input Type: Custom Input
Input Option Values: @INCLUDE manager/tvs/customtvSort.php
Widget: Delimited List, delimiter is comma
3. Link this new tv to template you'd like to have sidebar chunks output to.
4. Create a new chunk category called "sidebar".
5. You also need to create a snippet with the following code:
Snippet is called chunkParser
$ar_chunks = explode(',',$chunks);
$ar_chunks = array_unique($ar_chunks);
$output = '';
foreach ($ar_chunks as $chunk) {
if ($chunk != '') {
$c = $modx->getChunk($chunk);
if ($c) $output .= $c;
}
}
if ($output != '' && isset($wrapperdiv)) {
$output = '<div id="'.$wrapperdiv.'">'.$output.'</div>';
}
return $output;
call it like this:
[!chunkParser?chunks=`[*c*]` &wrapperdiv=`sidebarChunks`!]
where [*ourCustomTv*] is the name of the custom TV and wrapperdiv is the name of the div that you want the output to be wrapped in.
You could also modify the snippet code below to change:
if ($output != '' && isset($wrapperdiv)) {
$output = '<div id="'.$wrapperdiv.'">'.$output.'</div>';
To:
if ($output != '') {
$output = $output;
and the chunks would be output in the place where the snippet is called without being wrapped in a div. In this case you would call the snippet like:
[!chunkParser?chunks=`[*ourCostomTv*]`!]
Set up category name in variable name below.
Remember it must appear exactly like the name of the chunk;
Any chunk that you want the dynamic menu to pull from needs to be put in this category.
6. Create a new directory inside manager and name it tvs
7. Paste code below into file named 'customtvSort.php' and save it in manager/tvs
8. Open up a document and edit the sidebar chunks you'd like to appear on the page.
9. You can select one to activate and drag and drop sort them and click save. The selected options should be saved in the order you saved them in.
10. If you preview the page you should see the chunks output on the page.
11. Boat drinks all around!!
KNOWN LIMITATIONS:
1. This doeasn't work if you have categorized_tv_tabs Plugin enabled. If this code is refactored it will work. I was willing to keep my tvs below the content area though.
2. The code could be improved and I'm sure you will. I only ask you share your improvements with the rest of us!
-->
<?php /* The first HTML-Element must be the TV field */ ?>
<input type="hidden" id="tv<?php echo $row['id']; ?>" name="tv<?php echo $row['id']; ?>" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<script>
$.noConflict();
jQuery(function() {
jQuery('#sortable').sortable({placeholder: 'ui-state-highlight',axis:'y'});
jQuery('#sortable').disableSelection();
jQuery('#sortable li').filter(':has(:checkbox:checked)').addClass('selected').end().click(function(event) {
if (event.target.type !== 'checkbox') {
jQuery(':checkbox', this).trigger('click');
}
}).find(':checkbox').click(function(event) {
jQuery(this).parents('li:first').toggleClass('selected');
});
jQuery('input[type=checkbox]').click(function(){
jQuery(this).parent('li').toggleClass('checked');
})
});
</script>
<style type="text/css" media="all">
li.checked {background: #CFEFC6;}
ul#sortable li {cursor: move;padding: 0.5em 0;width: 250px;margin: 0.5em 0;list-style:none!important; border: 1px solid #cccccc;}
.ui-state-highlight { height: 2.5em; line-height: 1.2em; background-color: yellow; }
ul#sortable {list-style: none;}
</style>
<?php
$category = 'sidebar'; // I used sidebar for configurable name of chunk category to pull chunks from.
echo'<p><strong>click on list Item to select / deselect. Drag and drop to sort. Click Save.</strong></p>';
echo '<ul id="sortable">';
$selected_values = explode('||', $row['value']);
$selected = array();
$not_selected = array();
if ($selected_values[0] == '') {
} else {
foreach ($selected_values as $set) {
echo '<li class="checked"><input value="' . $set . '" name="tv' . $field_id . '[]" style="" onchange="documentDirty=true;" type="checkbox"';
echo 'checked="checked"';
echo '>';
echo '<label>' . $set . '</label></li>';
}
}
$q_chunks = $modx->db->query('SELECT chunk.* FROM ' . $modx->getFullTableName('site_htmlsnippets') . ' AS chunk INNER JOIN ' . $modx->getFullTableName('categories') . ' AS category ON chunk.category = category.id WHERE category.category IN ("' . $category . '") ORDER BY name');
$ar_chunks = array();
while ($row = $modx->db->getRow($q_chunks)) {
$ar_chunks[] = $row['name'];
}
foreach ($ar_chunks as $set) {
if (in_array($set, $selected_values)) {
} else {
echo '<li class="unchecked"><input value="' . $set . '" name="tv' . $field_id . '[]" onchange="documentDirty=true;" type="checkbox"';
echo '>';
echo '<label>' . $set . '</label></li>';
}
}
echo '</ul>';
?>
9. Set up category name in variable name below.
Remember it must appear exactly like the name of the chunk;
Any chunk that you want the dynamic menu to pull from needs to be put in this category.
10. You can select one to activate and drag and drop sort them and click save. The selected options should be saved in the order you saved them in.
11. Hit preview the page and you will see the chunks output on the page.
12. Boat drinks all around!!
Known Limitations
This doeasn't work if you have categorized_tv_tabs Plugin enabled. If this code is refactored by you, wise reader, it will work. I was willing to keep my tvs below the content area though.
The code could be improved and I'm sure you will.
I only ask you share your improvements with the rest of us!
[ed. note: noahlearner last edited this post 14 years, 8 months ago.]