Project

General

Profile

Feature #24060 » modernbe_patch_16396_V1.diff

Administrator Admin, 2010-11-16 12:22

View differences:

t3lib/class.t3lib_befunc.php (working copy)
't3ver_wsid' => $val['t3ver_wsid'],
't3ver_state' => $val['t3ver_state'],
't3ver_swapmode' => $val['t3ver_swapmode'],
't3ver_stage' => $val['t3ver_stage']
't3ver_stage' => $val['t3ver_stage'],
'be_layout' => $val['be_layout']
);
if (isset($val['_ORIG_pid'])) {
$output[$c]['_ORIG_pid'] = $val['_ORIG_pid'];
......
$row = $getPageForRootline_cache[$ident];
} else {
$res = $GLOBALS['TYPO3_DB']->exec_SELECTquery(
'pid,uid,title,TSconfig,is_siteroot,storage_pid,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_swapmode,t3ver_stage',
'pid,uid,title,TSconfig,is_siteroot,storage_pid,t3ver_oid,t3ver_wsid,t3ver_state,t3ver_swapmode,t3ver_stage,be_layout',
'pages',
'uid=' . intval($uid) . ' ' .
self::deleteClause('pages') . ' ' .
......
return $configuration;
}
}
?>
?>
t3lib/stddb/tables.sql (working copy)
alias varchar(32) DEFAULT '' NOT NULL,
l18n_cfg tinyint(4) DEFAULT '0' NOT NULL,
fe_login_mode tinyint(4) DEFAULT '0' NOT NULL,
be_layout int(10) DEFAULT '0' NOT NULL,
be_layout_next_level int(10) DEFAULT '0' NOT NULL,
PRIMARY KEY (uid),
KEY t3ver_oid (t3ver_oid,t3ver_wsid),
KEY parent (pid,sorting,deleted,hidden),
t3lib/stddb/tbl_be.php (working copy)
);
/**
* System filemounts - Defines filepaths on the server which can be mounted for users so they can upload and manage files online by eg. the Filelist module
*/
t3lib/stddb/tbl_pages.php (working copy)
$TCA['pages'] = array(
'ctrl' => $TCA['pages']['ctrl'],
'interface' => array(
'showRecordFieldList' => 'doktype,title,alias,hidden,starttime,endtime,fe_group,url,target,no_cache,shortcut,keywords,description,abstract,newUntil,lastUpdated,cache_timeout',
'showRecordFieldList' => 'doktype,title,alias,hidden,starttime,endtime,fe_group,url,target,no_cache,shortcut,keywords,description,abstract,newUntil,lastUpdated,cache_timeout,be_layout,be_layout_next_level',
'maxDBListItems' => 30,
'maxSingleDBListItems' => 50,
),
......
),
),
),
'be_layout' => array (
'exclude' => 1,
'label' => 'LLL:EXT:cms/locallang_tca.xml:pages.be_layout',
'config' => array (
'type' => 'select',
'foreign_table' => 'be_layouts',
'foreign_table_where' => 'AND ( ( ###PAGE_TSCONFIG_ID### = 0 AND ###STORAGE_PID### = 0 ) OR ( be_layouts.pid = ###PAGE_TSCONFIG_ID### OR be_layouts.pid = ###STORAGE_PID### ) ) AND be_layouts.hidden = 0',
'items' => array (
array ('', 0),
array ('none', -1)
),
'selicon_cols' => 5,
'size' => 1,
'maxitems' => 1,
'default' => ''
)
),
'be_layout_next_level' => array (
'exclude' => 1,
'label' => 'LLL:EXT:cms/locallang_tca.xml:pages.be_layout_next_level',
'config' => array (
'type' => 'select',
'foreign_table' => 'be_layouts',
'foreign_table_where' => 'AND ( ( ###PAGE_TSCONFIG_ID### = 0 AND ###STORAGE_PID### = 0 ) OR ( be_layouts.pid = ###PAGE_TSCONFIG_ID### OR be_layouts.pid = ###STORAGE_PID### ) ) AND be_layouts.hidden = 0',
'items' => array (
array ('', 0),
array ('none', -1)
),
'selicon_cols' => 5,
'size' => 1,
'maxitems' => 1,
'default' => ''
)
)
),
'types' => array(
// normal
......
'7' => array(
'showitem' => 'is_siteroot',
),
'8' => array(
'showitem' => 'be_layout_next_level'
),
'standard' => array(
'showitem' => 'doktype;LLL:EXT:cms/locallang_tca.xml:pages.doktype_formlabel',
'canNotCollapse' => 1,
......
'canNotCollapse' => 1,
),
'layout' => array(
'showitem' => 'layout;LLL:EXT:cms/locallang_tca.xml:pages.layout_formlabel, newUntil;LLL:EXT:cms/locallang_tca.xml:pages.newUntil_formlabel',
'showitem' => 'layout;LLL:EXT:cms/locallang_tca.xml:pages.layout_formlabel, newUntil;LLL:EXT:cms/locallang_tca.xml:pages.newUntil_formlabel, --linebreak--, be_layout;LLL:EXT:cms/locallang_tca.xml:pages.be_layout_formlabel, be_layout_next_level;LLL:EXT:cms/locallang_tca.xml:pages.be_layout_next_level_formlabel',
'canNotCollapse' => 1,
),
'module' => array(
......
'config' => array(
'showitem' => 'TSconfig;LLL:EXT:cms/locallang_tca.xml:pages.TSconfig_formlabel',
'canNotCollapse' => 1,
),
),
)
)
);
......
--div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.access,
starttime, endtime, fe_group, extendToSubpages,
--div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.options,
TSconfig;;6;nowrap;4-4-4, storage_pid;;7, l18n_cfg,
TSconfig;;6;nowrap;4-4-4, storage_pid;;7, l18n_cfg, be_layout;;8,
--div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.extended,
');
// adding doktype 2 ("Advanced")
......
--div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.access,
starttime, endtime, fe_login_mode, fe_group, extendToSubpages,
--div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.options,
TSconfig;;6;nowrap;6-6-6, storage_pid;;7, l18n_cfg, module, content_from_pid,
TSconfig;;6;nowrap;6-6-6, storage_pid;;7, l18n_cfg, module, content_from_pid, be_layout;;8,
--div--;LLL:EXT:cms/locallang_tca.xml:pages.tabs.extended,
');
}
typo3/sysext/cms/class.tx_cms_be_layout.php (revision 0)
<?php
class tx_cms_be_layout {
/**
* @mficzel
* @todo add items
* @param unknown_type $params
*/
function colPosListItemProcFunc( &$params ){
$params['items'] = $this->addColPosListLayoutItems ( $params['row']['pid'], $params['items'] );
}
function addColPosListLayoutItems ( $pageId, $items ){
$layout = $this->getSelectedBackendLayout($pageId);
if( $layout && $layout['__items'] ){
$items = $layout['__items'];
}
return $items;
}
function getColPosListItemsParsed ( $id ){
$tsConfig = t3lib_BEfunc::getModTSconfig( $id ,'TCEFORM.tt_content.colPos');
$tcaConfig = $GLOBALS['TCA']['tt_content']['columns']['colPos']['config'];
$TCEForms = t3lib_div::makeInstance( 't3lib_TCEForms' );
$tcaItems = $tcaConfig['items'];
$tcaItems = $TCEForms->addItems($tcaItems, $tsConfig['properties']['addItems.']);
if (isset($tcaConfig['itemsProcFunc']) && $tcaConfig['itemsProcFunc']) {
$tcaItems = $this->addColPosListLayoutItems ($id , $tcaItems ) ;
}
foreach ( t3lib_div::trimExplode(',',$tsConfig['properties']['removeItems'],1) as $removeId ){
unset( $tcaItems[$removeId] );
}
return $tcaItems;
}
function getSelectedBackendLayout($id) {
$rootline = t3lib_BEfunc::BEgetRootLine($id);
$backendLayoutUid = null;
for ($i = count($rootline); $i > 0; $i--) {
$res = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,be_layout,be_layout_next_level','pages','uid='.intval($rootline[$i]['uid']));
$page = $res[0];
if (intval($page['be_layout_next_level']) > 0 && $page['uid'] != $id ) {
$backendLayoutUid = intval($page['be_layout_next_level']);
break;
} else if (intval($page['be_layout']) > 0) {
$backendLayoutUid = intval($page['be_layout']);
break;
}
}
$backendLayout = null;
if ($backendLayoutUid){
$res = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('*','be_layouts','uid='.$backendLayoutUid );
if ($res){
$backendLayout = $res[0];
$parser = t3lib_div::makeInstance('t3lib_TSparser');
$parser->parse($backendLayout['config']);
$backendLayout['__config'] = $parser->setup;
$backendLayout['__items'] = array();
$backendLayout['__colPosList'] = array();
// create items and colPosList
if ( $backendLayout['__config']['be_layout.'] && $backendLayout['__config']['be_layout.']['rows.'] ){
foreach( $backendLayout['__config']['be_layout.']['rows.'] as $row){
if ( true && count($row['columns.'])){
foreach ( $row['columns.'] as $column) {
if ( true ){
$backendLayout['__items'][] = array (
$column['name'],
$column['colPos'],
null
);
$backendLayout['__colPosList'][] = $column['colPos'];
}
}
}
}
}
}
}
return $backendLayout;
}
}
?>
typo3/sysext/cms/ext_tables.php (working copy)
// Add allowed records to pages:
t3lib_extMgm::allowTableOnStandardPages('pages_language_overlay,tt_content,sys_template,sys_domain');
t3lib_extMgm::allowTableOnStandardPages('pages_language_overlay,tt_content,sys_template,sys_domain,be_layouts');
// ******************************************************************
......
);
// ******************************************************************
// layouts
// ******************************************************************
$TCA['be_layouts'] = array (
'ctrl' => array (
'title' => 'LLL:EXT:cms/locallang_tca.xml:be_layouts',
'label' => 'title',
'tstamp' => 'tstamp',
'crdate' => 'crdate',
'cruser_id' => 'cruser_id',
'versioningWS' => TRUE,
'origUid' => 't3_origuid',
'sortby' => 'sorting',
'delete' => 'deleted',
'enablecolumns' => array (
'disabled' => 'hidden',
),
'dynamicConfigFile' => t3lib_extMgm::extPath($_EXTKEY).'tbl_cms.php',
'iconfile' => 'be_layout.gif',
'selicon_field' => 'icon',
'selicon_field_path' => 'uploads/media',
'thumbnail' => 'resources',
)
);
?>
typo3/sysext/cms/ext_tables.sql (working copy)
KEY parent (pid,sorting),
KEY language (l18n_parent,sys_language_uid)
);
#
# Table structure for table 'be_layouts'
#
CREATE TABLE be_layouts (
uid int(11) NOT NULL auto_increment,
pid int(11) DEFAULT '0' NOT NULL,
t3ver_oid int(11) DEFAULT '0' NOT NULL,
t3ver_id int(11) DEFAULT '0' NOT NULL,
t3ver_wsid int(11) DEFAULT '0' NOT NULL,
t3ver_label varchar(255) DEFAULT '' NOT NULL,
t3ver_state tinyint(4) DEFAULT '0' NOT NULL,
t3ver_stage tinyint(4) DEFAULT '0' NOT NULL,
t3ver_count int(11) DEFAULT '0' NOT NULL,
t3ver_tstamp int(11) DEFAULT '0' NOT NULL,
t3ver_move_id int(11) DEFAULT '0' NOT NULL,
t3_origuid int(11) DEFAULT '0' NOT NULL,
tstamp int(11) unsigned DEFAULT '0' NOT NULL,
crdate int(11) unsigned DEFAULT '0' NOT NULL,
cruser_id int(11) unsigned DEFAULT '0' NOT NULL,
hidden tinyint(4) unsigned DEFAULT '0' NOT NULL,
deleted tinyint(4) DEFAULT '0' NOT NULL,
sorting int(11) unsigned DEFAULT '0' NOT NULL,
title varchar(255) DEFAULT '' NOT NULL,
description text NOT NULL,
config text NOT NULL,
icon text NOT NULL,
PRIMARY KEY (uid),
KEY parent (pid),
KEY t3ver_oid (t3ver_oid,t3ver_wsid)
);
typo3/sysext/cms/layout/class.tx_cms_layout.php (working copy)
'showInfo' => 1, // Boolean: Display info-marks or not
'showCommands' => 1, // Boolean: Display up/down arrows and edit icons for tt_content records
'single' => 1, // Boolean: If set, the content of column(s) $this->tt_contentConfig['showSingleCol'] is shown in the total width of the page
'showAsGrid' => 0, // Boolean: If set, the content of columns is shown in grid
'showSingleCol' => 0, // The column(s) to show if single mode (under each other)
'languageCols' => 0,
'languageMode' => 0,
......
}
/**
* Returns the backend layout which should be used for this page.
*
* @param integer $id: Uid of the current
* @return integer The Uid of the backend layout record
*/
function getSelectedBackendLayoutUid($id) {
$rootline = t3lib_BEfunc::BEgetRootLine($id);
$backendLayoutUid = null;
for ($i = count($rootline); $i > 0; $i--) {
$res = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid,be_layout,be_layout_next_level','pages','uid='.intval($rootline[$i]['uid']));
$page = $res[0];
if (intval($page['be_layout_next_level']) > 0 && $page['uid'] != $id ) {
$backendLayoutUid = intval($page['be_layout_next_level']);
break;
} else if (intval($page['be_layout']) > 0) {
$backendLayoutUid = intval($page['be_layout']);
break;
}
}
return $backendLayoutUid;
}
/**
* Renders Content Elements from the tt_content table from page id
*
* @param integer Page id
......
// Add new-icon link, header:
$newP = $this->newContentElementOnClick($id,$key,$lP);
$head[$key].= $this->tt_content_drawColHeader(t3lib_BEfunc::getProcessedValue('tt_content','colPos',$key), ($this->doEdit&&count($rowArr)?'&edit[tt_content]['.$editUidList.']=edit'.$pageTitleParamForAltDoc:''), $newP);
$colTitle = t3lib_BEfunc::getProcessedValue('tt_content','colPos',$key);
/**
* @mficzel
* @todo get complete title from tca inclusive ts config manipulations by user func and tsConfig
*/
$tcaItems = t3lib_div::callUserFunction( 'EXT:cms/class.tx_cms_be_layout.php:tx_cms_be_layout->getColPosListItemsParsed' , $id, $this );
foreach( $tcaItems as $item) {
if ( $item[1] == $key) {
$colTitle = $GLOBALS['LANG']->sL( $item[0] );
}
}
$head[$key].= $this->tt_content_drawColHeader($colTitle , ($this->doEdit&&count($rowArr)?'&edit[tt_content]['.$editUidList.']=edit'.$pageTitleParamForAltDoc:''), $newP);
$editUidList = '';
}
// For EACH column, fit the rendered content into a table cell:
$out='';
foreach($cList as $k => $key) {
if (!$k) {
$out.= '
<td><img src="clear.gif" width="'.$lMarg.'" height="1" alt="" /></td>';
} else {
$out.= '
<td><img src="clear.gif" width="4" height="1" alt="" /></td>
<td bgcolor="#cfcfcf"><img src="clear.gif" width="1" height="1" alt="" /></td>
<td><img src="clear.gif" width="4" height="1" alt="" /></td>';
if ($this->tt_contentConfig['showAsGrid']) {
$backendLayoutUid = $this->getSelectedBackendLayoutUid($id);
$backendLayoutRecord = t3lib_BEfunc::getRecord('be_layouts', intval($backendLayoutUid));
if (empty($backendLayoutRecord['config'])) {
// TODO: show a message that no layout was found
$this->tt_contentConfig['showAsGrid'] = 0;
}
$out.= '
<td class="t3-page-column t3-page-column-' . $key . '">' . $head[$key] . $content[$key] . '</td>';
}
// Storing content for use if languageMode is set:
if ($this->tt_contentConfig['languageMode']) {
$languageColumn[$key][$lP] = $head[$key].$content[$key];
if (!$this->defLangBinding) {
$languageColumn[$key][$lP].='<br /><br />'.$this->newLanguageButton($this->getNonTranslatedTTcontentUids($defLanguageCount[$key],$id,$lP),$lP);
if (!$this->tt_contentConfig['showAsGrid']) {
foreach($cList as $k => $key) {
if (!$k) {
$out.= '
<td><img src="clear.gif" width="'.$lMarg.'" height="1" alt="" /></td>';
} else {
$out.= '
<td><img src="clear.gif" width="4" height="1" alt="" /></td>
<td bgcolor="#cfcfcf"><img src="clear.gif" width="1" height="1" alt="" /></td>
<td><img src="clear.gif" width="4" height="1" alt="" /></td>';
}
$out.= '
<td class="t3-page-column t3-page-column-' . $key . '">' . $head[$key] . $content[$key] . '</td>';
// Storing content for use if languageMode is set:
if ($this->tt_contentConfig['languageMode']) {
$languageColumn[$key][$lP] = $head[$key].$content[$key];
if (!$this->defLangBinding) {
$languageColumn[$key][$lP].='<br /><br />'.$this->newLanguageButton($this->getNonTranslatedTTcontentUids($defLanguageCount[$key],$id,$lP),$lP);
}
}
}
}
// Wrap the cells into a table row:
$out = '
// Wrap the cells into a table row:
$out = '
<table border="0" cellpadding="0" cellspacing="0" class="t3-page-columns">
<tr>'.$out.'
</tr>
</table>';
} else {
// GRID VIEW:
// initialize TS parser to parse config to array
$parser = t3lib_div::makeInstance('t3lib_TSparser');
$parser->parse($backendLayoutRecord['config']);
$grid .= '<div class="t3-gridContainer"><table border="0" cellspacing="1" cellpadding="4" width="80%" height="100%" class="t3-page-columns t3-gridTable">';
// add colgroups
$colCount = intval($parser->setup['be_layout.']['colCount']);
$grid .= '<colgroup>';
for ($i = 0; $i < $colCount; $i++) {
$grid .= '<col style="width:'.(100/$colCount).'%"></col>';
}
$grid .= '</colgroup>';
// cycle through rows
if(count($parser->setup['be_layout.']['rows.'])) {
foreach ($parser->setup['be_layout.']['rows.'] as $rowConfig) {
$grid .= '<tr>';
// and colummns
if(count($rowConfig['columns.'])) {
foreach ($rowConfig['columns.'] as $columnConfig) {
// which tt_content colPos should be displayed inside this cell
$columnKey = intval($columnConfig['colPos']);
// render the grid cell
$grid .= '<td valign="top"'.
(isset($columnConfig['colspan']) ? ' colspan="'.$columnConfig['colspan'].'"' : '').
(isset($columnConfig['rowspan']) ? ' rowspan="'.$columnConfig['rowspan'].'"' : '').
' class="t3-gridCell t3-page-column t3-page-column-' . $columnKey .
(isset($columnConfig['colspan']) ? ' t3-gridCell-width'.$columnConfig['colspan'] : '') .
(isset($columnConfig['rowspan']) ? ' t3-gridCell-height'.$columnConfig['rowspan'] : '').'">';
$grid .= $head[$columnKey] . $content[$columnKey] . '</td>';
}
}
$grid .= '</tr>';
}
}
$out .= $grid.'</table></div>';
}
// CSH:
$out.= t3lib_BEfunc::cshItem($this->descrTable,'columns_multi',$GLOBALS['BACK_PATH']);
}
......
$lines[]='';
$lines[]=array($LANG->getLL('pI_hitsPeriod').':',t3lib_BEfunc::date($rrow2[0]).' - '.t3lib_BEfunc::date($rrow2[1]).' ('.t3lib_BEfunc::calcAge($rrow2[1]-$rrow2[0],$this->agePrefixes).')');
$lines[]=array($LANG->getLL('pI_hitsTotal').':',$rrow[0]);
$lines[]=array($LANG->getLL('pI_hitsTotal').':',$rrow2[0]);
// Last 10 days
typo3/sysext/cms/layout/db_layout.php (working copy)
0 => $LANG->getLL('m_function_0'),
1 => $LANG->getLL('m_function_1'),
2 => $LANG->getLL('m_function_2'),
3 => $LANG->getLL('pageInformation')
3 => $LANG->getLL('pageInformation'),
4 => $LANG->getLL('gridView')
),
'language' => array(
0 => $LANG->getLL('m_default')
......
// Find columns
$modTSconfig_SHARED = t3lib_BEfunc::getModTSconfig($this->id,'mod.SHARED'); // SHARED page-TSconfig settings.
$this->colPosList = strcmp(trim($this->modTSconfig['properties']['tt_content.']['colPos_list']),'') ? trim($this->modTSconfig['properties']['tt_content.']['colPos_list']) : $modTSconfig_SHARED['properties']['colPos_list'];
$this->colPosList = strcmp($this->colPosList,'')?$this->colPosList:'1,0,2,3';
$this->colPosList = implode(',',array_unique(t3lib_div::intExplode(',',$this->colPosList))); // Removing duplicates, if any
if( !strcmp($this->colPosList,'') ) {
$beLayout = t3lib_div::callUserFunction( 'EXT:cms/class.tx_cms_be_layout.php:tx_cms_be_layout->getSelectedBackendLayout' , $this->id, $this );
if(count($beLayout['__colPosList'])) {
$this->colPosList = implode(',', $beLayout['__colPosList']);
}
}
if( !strcmp($this->colPosList, '') ){
$this->colPosList = '1,0,2,3';
}
$this->colPosList = implode(',', array_unique(t3lib_div::intExplode(',',$this->colPosList))); // Removing duplicates, if any
// Render the primary module content:
if ($this->MOD_SETTINGS['function']==0) {
$body = $this->renderQuickEdit(); // QuickEdit
......
$dblist->tt_contentConfig['showInfo'] = 1; // Boolean: Display info-marks or not
$dblist->tt_contentConfig['single'] = 0; // Boolean: If set, the content of column(s) $this->tt_contentConfig['showSingleCol'] is shown in the total width of the page
if ($this->MOD_SETTINGS['function'] == 4) {
// grid view
$dblist->tt_contentConfig['showAsGrid'] = 1;
}
// Setting up the tt_content columns to show:
if (is_array($TCA['tt_content']['columns']['colPos']['config']['items'])) {
$colList = array();
foreach($TCA['tt_content']['columns']['colPos']['config']['items'] as $temp) {
$tcaItems = t3lib_div::callUserFunction( 'EXT:cms/class.tx_cms_be_layout.php:tx_cms_be_layout->getColPosListItemsParsed' , $this->id, $this );
foreach($tcaItems as $temp) {
$colList[] = $temp[1];
}
} else { // ... should be impossible that colPos has no array. But this is the fallback should it make any sense:
......
$SOBE->main();
$SOBE->printContent();
?>
?>
typo3/sysext/cms/layout/locallang.xml (working copy)
<label index="m_function_0">QuickEdit</label>
<label index="m_function_1">Columns</label>
<label index="m_function_2">Languages</label>
<label index="gridView">Grid-View</label>
<label index="m_tt_board_0">List topics only</label>
<label index="m_tt_board_expand">Expand Threads</label>
<label index="m_tt_address_0">Short List</label>
......
<label index="content_from_pid_title">Page uses content from this page: %s</label>
</languageKey>
</data>
</T3locallang>
</T3locallang>
typo3/sysext/cms/layout/res/grideditor.css (revision 0)
* {
padding: 0;
margin: 0;
position: relative;
}
body, html {
height: 100%;
width: 100%;
}
div.typo3-noDoc {
width: 98%;
height: 90%;
margin: 0;
padding: 5px;
}
table#outer_container td, table#editor td {
vertical-align: middle;
}
table#outer_container td.editor_cell {
height: 100%;
}
table.editor {
border-right: 1px gray dashed;
border-bottom: 1px gray dashed;
}
table.editor td {
border-top: 1px gray dashed;
border-left: 1px gray dashed;
text-align: center;
z-index: 2000;
background-color: white;
min-height: 100px;
}
div#editor {
height: 100%;
}
div.cell_container {
width: 60px;
height: 60px;
position: relative;
left: 50%;
margin-left: -30px;
opacity: 0.3;
}
div.cell_container:hover {
opacity: 1;
}
.link_expand_right, .link_shrink_left, .link_expand_down, .link_shrink_up, .link_editor {
display: block;
position: absolute;
width: 14px;
height: 32px;
z-index: 1100;
}
.link_expand_down, .link_shrink_up {
width: 32px;
height: 14px;
}
.link_expand_right {
background-image: url(t3grid-editor-right-inactive.png);
left: 46px;
top: 14px;
}
.link_expand_right:hover {
background-image: url(t3grid-editor-right.png);
}
.link_shrink_left {
background-image: url(t3grid-editor-left-inactive.png);
left: 0px;
top: 14px;
}
.link_shrink_left:hover {
background-image: url(t3grid-editor-left.png);
}
.link_expand_down {
background-image: url(t3grid-editor-down-inactive.png);
left: 14px;
top: 46px;
}
.link_expand_down:hover {
background-image: url(t3grid-editor-down.png);
}
.link_shrink_up {
background-image: url(t3grid-editor-up-inactive.png);
left: 14px;
top: 0px;
}
.link_shrink_up:hover {
background-image: url(t3grid-editor-up.png);
}
.link_editor {
background-image: url(t3grid-edit-inactive.png);
width: 32px;
height: 32px;
left: 14px;
top: 14px;
}
.link_editor:hover {
background-image: url(t3grid-edit.png);
}
.question {
background-image: url(t3grid-layer-icon-help.png) !important;
}
.save {
background-image: url(t3grid-layer-icon-save.png) !important;
}
.cancel {
background-image: url(t3grid-layer-icon-close.png) !important;
}
typo3/sysext/cms/layout/res/grideditor.js (revision 0)
/**
* A JavaScript object to handle, edit, draw and export a grid. The grid is basically
* a table with some colspan and rowspan. Each cell can additionally hold a name and
* column.
*
* @author Thomas Hempel <thomas@typo3.org>
*/
Ext.namespace('TYPO3.Backend.t3Grid');
TYPO3.Backend.t3Grid = Ext.extend(Ext.Component, {
/*
colCount: 0,
rowCount: 0,
data: [],
nameLabel: '',
columnLabel: '',
*/
constructor: function(config) {
config = Ext.apply({
colCount: config.colCount,
rowCount: config.rowCount,
data: config.data,
nameLabel: config.nameLabel,
columnLabel: config.columnLabel,
targetElement: config.targetElement
}, config);
TYPO3.Backend.t3Grid.superclass.constructor.call(this, config);
},
/**
* Adds a row below the grid
*/
addRow: function() {
var newRow = [];
for (var i = 0; i < this.colCount; i++) {
newRow[i] = {spanned:false,rowspan:1,colspan:1};
}
this.data.push(newRow);
this.rowCount++;
},
/**
* Removes the last row of the grid and adjusts all cells that might be effected
* by that change. (Removing colspans)
*
* @returns void
*/
removeRow: function() {
if (this.rowCount <= 1) return false;
var newData = [];
for (var rowIndex = 0; rowIndex < this.rowCount-1; rowIndex++) {
newData.push(this.data[rowIndex]);
}
// fix rowspan in former last row
for (var colIndex = 0; colIndex < this.colCount; colIndex++) {
if (this.data[this.rowCount-1][colIndex].spanned == true) {
this.findUpperCellWidthRowspanAndDecreaseByOne(colIndex,this.rowCount-1);
}
}
this.data = newData;
this.rowCount--;
},
/**
* Takes a cell and looks above it if there are any cells that have colspans that
* spanns into the given cell. This is used when a row was removed from the grid
* to make sure that no cell with wrong colspans exists in the grid.
*
* @param col integer
* @param row integer
* @return void
*/
findUpperCellWidthRowspanAndDecreaseByOne: function(col,row) {
var upperCell = this.getCell(col, row-1);
if (!upperCell) return false;
if (upperCell.spanned == true) {
this.findUpperCellWidthRowspanAndDecreaseByOne(col, row-1);
} else {
if (upperCell.rowspan > 1) {
this.removeRowspan(col, row-1);
}
}
},
/**
* Removes the outermost right column from the grid.
*
* @return void
*/
removeColumn: function() {
if (this.colCount <= 1) return false;
var newData = [];
for (var rowIndex = 0; rowIndex < this.rowCount; rowIndex++) {
var newRow = [];
for (colIndex = 0; colIndex < this.colCount-1; colIndex++) {
newRow.push(this.data[rowIndex][colIndex]);
}
if (this.data[rowIndex][this.colCount-1].spanned == true) {
this.findLeftCellWidthColspanAndDecreaseByOne(this.colCount-1, rowIndex);
}
newData.push(newRow);
}
this.data = newData;
this.colCount--;
},
/**
* Checks if there are any cells on the left side of a given cell with a
* rowspan that spans over the given cell.
*
* @param col integer
* @param row integer
* @return void
*/
findLeftCellWidthColspanAndDecreaseByOne: function(col,row) {
var leftCell = this.getCell(col-1, row);
if (!leftCell) return false;
if (leftCell.spanned == true) {
this.findLeftCellWidthColspanAndDecreaseByOne(col-1, row);
} else {
if (leftCell.colspan > 1) {
this.removeColspan(col-1, row);
}
}
},
/**
* Adds a column at the right side of the grid.
*
* @return void
*/
addColumn: function() {
for (var rowIndex = 0; rowIndex < this.rowCount; rowIndex++) {
this.data[rowIndex].push({spanned:false,rowspan:1,colspan:1,name:this.colCount+'x'+rowIndex});
}
this.colCount++;
},
/**
* Draws the grid as table into a given container.
* It also adds all needed links and bindings to the cells to make it editable.
*
* @return void
*/
drawTable: function() {
var domHelper = Ext.DomHelper;
var newTable = {tag:'table',children:[],id:'base',border:'0',width:'100%',height:'100%','class':'editor',cellspacing:'0',cellpadding:'0'};
var colgroups = {tag:'colgroup',children:[]};
for (var col = 0; col < this.colCount; col++) {
colgroups.children.push({tag:'col',style:'width:'+parseInt(100/this.colCount)+'%'});
}
newTable.children.push(colgroups);
for (var row = 0; row < this.rowCount; row++) {
var rowData = this.data[row];
if (rowData.length == 0) continue;
var rowSpec = {tag: 'tr', children:[]};
for (var col = 0; col < this.colCount; col++) {
var cell = this.data[row][col];
if (cell.spanned == true) {
continue;
}
var cellHtml = '<div class="cell_container"><a class="link_editor" id="e_'+col+'_'+row+'" href="#"><!-- --></a>';
if (this.cellCanSpanRight(col, row)) cellHtml += '<a href="#" id="r_'+col+'_'+row+'" class="link_expand_right"><!-- --></a>';
if (this.cellCanShrinkLeft(col, row)) cellHtml += '<a href="#" id="l_'+col+'_'+row+'" class="link_shrink_left"><!-- --></a>';
if (this.cellCanSpanDown(col, row)) cellHtml += '<a href="#" id="d_'+col+'_'+row+'" class="link_expand_down"><!-- --></a>';
if (this.cellCanShrinkUp(col, row)) cellHtml += '<a href="#" id="u_'+col+'_'+row+'" class="link_shrink_up"><!-- --></a>';
cellHtml += '</div>';
cellHtml += '<div class="cell_data">Name: '+(cell.name ? cell.name : 'not set')+'<br />Column: '+((parseInt(cell.column) === false) ? 'not set' : cell.column)+'</div>';
// create cells
var child = {
tag: 'td',
height: parseInt(100/this.rowCount)*cell.rowspan+'%',
width: parseInt(100/this.colCount)*cell.colspan+'%',
html: cellHtml
};
if (cell.colspan > 1) {
child.colspan = cell.colspan;
}
if (cell.rowspan > 1) {
child.rowspan = cell.rowspan;
}
rowSpec.children.push(child);
}
newTable.children.push(rowSpec);
}
domHelper.overwrite(Ext.Element.get(this.targetElement), newTable);
this.bindLinks();
},
/**
* Sets the name of a certain grid element.
*
* @param newName string
* @param col integer
* @param row integer
*
* @return boolean
*/
setName: function(newName, col, row) {
var cell = this.getCell(col, row);
if (!cell) return false;
cell.name = newName;
return true;
},
/**
* Sets the column field for a certain grid element. This is NOT the column of the
* element itself.
*
* @param newColumn integer
* @param col integer
* @param row integer
*
* @return boolean
*/
setColumn: function(newColumn, col, row) {
var cell = this.getCell(col, row);
if (!cell) return false;
cell.column = newColumn;
return true;
},
/**
* Searches for all a tags with certain classes and binds some actions to them.
*
* @return void
*/
bindLinks: function() {
for (var row = 0; row < this.rowCount; row++) {
for (var col = 0; col < this.colCount; col++) {
// span right
var el = Ext.Element.get('r_'+col+'_'+row);
if (el) {
el.addListener('click', function(e, sender, params) {
this.addColspan(params.colIndex, params.rowIndex);
this.drawTable();
}, this, {stopEvent:true, colIndex:col, rowIndex:row});
}
// reduce to left
var el = Ext.Element.get('l_'+col+'_'+row);
if (el) {
el.addListener('click', function(e, sender, params) {
this.removeColspan(params.colIndex, params.rowIndex);
this.drawTable();
}, this, {stopEvent:true, colIndex:col, rowIndex:row});
}
// span down
var el = Ext.Element.get('d_'+col+'_'+row);
if (el) {
el.addListener('click', function(e, sender, params) {
this.addRowspan(params.colIndex, params.rowIndex);
this.drawTable();
}, this, {stopEvent:true, colIndex:col, rowIndex:row});
}
// reduce up
var el = Ext.Element.get('u_'+col+'_'+row);
if (el) {
el.addListener('click', function(e, sender, params) {
this.removeRowspan(params.colIndex, params.rowIndex);
this.drawTable();
}, this, {stopEvent:true, colIndex:col, rowIndex:row});
}
// edit
var el = Ext.Element.get('e_'+col+'_'+row);
if (el) {
el.addListener('click', function(e, sender, params) {
this.showOptions(sender, params.colIndex, params.rowIndex);
}, this, {stopEvent:true, colIndex:col, rowIndex:row});
}
}
}
},
/**
* Creates an ExtJs Window with two input fields and shows it. On save, the data
* is written into the grid element.
*
* @param sender DOM-object (the link)
* @param col integer
* @param row integer
*/
showOptions: function(sender, col, row) {
var win;
sender = Ext.get('base');
var cell = this.getCell(col, row);
if (!cell) return false;
if(!win){
var fieldName = new Ext.form.TextField({
fieldLabel: TYPO3.lang.name,
name: 'name',
width: 200,
value: cell.name,
tabIndex: 1
});
var fieldColumn = new Ext.form.NumberField({
fieldLabel: TYPO3.lang.column,
name: 'column',
width: 50,
value: cell.column,
tabIndex: 2
});
win = new Ext.Window({
layout: 'fit',
title: TYPO3.lang.title,
width: '50%',
modal: true,
closable: true,
resizable: false,
items: [{
xtype: 'fieldset',
autoHeight: true,
autoWidth: true,
labelWidth: 100,
border: false,
items: [fieldName, fieldColumn]
}],
buttons: [{
iconCls:'save',
text: TYPO3.lang.save,
handler: function(fieldName, fieldColumn, col, row) {
t3Grid.setName(fieldName.getValue(), col, row);
t3Grid.setColumn(fieldColumn.getValue(), col, row);
win.close();
t3Grid.drawTable();
}.createDelegate(this, [fieldName, fieldColumn, col, row])
}]
});
}
win.show(this);
},
/**
* Returns a cell element from the grid.
*
* @param col integer
* @param row integer
* return Object
*/
getCell: function(col, row) {
if (col > this.colCount-1) return false;
if (row > this.rowCount-1) return false;
return this.data[row][col];
},
/**
* Checks wether a cell can span to the right or not. A cell can span to the right
* if it is not in the last column and if there is no cell beside it that is
* already overspanned by some other cell.
*
* @param col integer
* @param row integer
*
* @return boolean
*/
cellCanSpanRight: function(col, row) {
if (col == this.colCount-1) {
return false;
}
var cell = this.getCell(col, row);
if (cell.rowspan > 1) {
for (var rowIndex = row; rowIndex < row+cell.rowspan; rowIndex++) {
var checkCell = this.getCell(col+cell.colspan, rowIndex);
if (!checkCell || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) {
return false;
}
}
} else {
var checkCell = this.getCell(col+cell.colspan, row);
if (!checkCell || cell.spanned == true || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) {
return false;
}
}
return true;
},
/**
* Checks wether a cell can span down or not.
*
* @param col integer
* @param row integer
*
* @return boolean
*/
cellCanSpanDown: function(col, row) {
if (row == this.rowCount-1) {
return false;
}
var cell = this.getCell(col, row);
if (cell.colspan > 1) {
// we have to check all cells on the right side for the complete colspan
for (var colIndex = col; colIndex < col+cell.colspan; colIndex++) {
var checkCell = this.getCell(colIndex, row+cell.rowspan);
if (!checkCell || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) {
return false;
}
}
} else {
var checkCell = this.getCell(col, row+cell.rowspan);
if (!checkCell || cell.spanned == true || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) {
return false;
}
}
return true;
},
/**
* Checks if a cell can shrink to the left. It can shrink if the colspan of the
* cell is bigger than 1.
*
* @param col integr
* @param row integer
*
* @return boolean
*/
cellCanShrinkLeft: function(col, row) {
return (this.data[row][col].colspan > 1);
},
/**
* Returns if a cell can shrink up. This is the case if a cell has at least
* a rowspan of 2.
*
* @param col integr
* @param row integer
*
* @return boolean
*/
cellCanShrinkUp: function(col, row) {
return (this.data[row][col].rowspan > 1);
},
/**
* Adds a colspan to a grid element.
*
* @param col integr
* @param row integer
*/
addColspan: function(col, row) {
var cell = this.getCell(col, row);
if (!cell || !this.cellCanSpanRight(col, row)) return false;
for (var rowIndex = row; rowIndex < row+cell.rowspan; rowIndex++) {
this.data[rowIndex][col+cell.colspan].spanned = true;
}
cell.colspan += 1;
},
/**
* Adds a rowspan to grid element.
*
* @param col integr
* @param row integer
*
* @return void
*/
addRowspan: function(col, row) {
var cell = this.getCell(col, row);
if (!cell || !this.cellCanSpanDown(col, row)) return false;
for (var colIndex = col; colIndex < col+cell.colspan; colIndex++) {
this.data[row+cell.rowspan][colIndex].spanned = true;
}
cell.rowspan += 1;
},
/**
* Removes a colspan from a grid element.
*
* @param col integr
* @param row integer
*
* @return void
*/
removeColspan: function(col, row) {
var cell = this.getCell(col, row);
if (!cell || !this.cellCanShrinkLeft(col, row)) return false;
cell.colspan -= 1;
for (var rowIndex = row; rowIndex < row+cell.rowspan; rowIndex++) {
this.data[rowIndex][col+cell.colspan].spanned = false;
}
},
/**
* Removes a rowspan from a grid element.
*
* @param col integr
* @param row integer
*
* @return void
*/
removeRowspan: function(col, row) {
var cell = this.getCell(col, row);
if (!cell || !this.cellCanShrinkUp(col, row)) return false;
cell.rowspan -= 1;
for (var colIndex = col; colIndex < col+cell.colspan; colIndex++) {
this.data[row+cell.rowspan][colIndex].spanned = false;
}
},
/**
* Exports the current grid to a TypoScript notation that can be read by the
* page module and is human readable.
*
* @return string
*/
export2LayoutRecord: function() {
var result = "be_layout {\n\tcolCount = "+this.colCount+"\n\trowCount = "+this.rowCount+ "\n\trows {\n";
for (var row = 0; row < this.rowCount; row++) {
result += "\t\t"+(row+1)+" {\n";
result += "\t\t\tcolumns {\n";
colIndex = 0;
for (var col = 0; col < this.colCount; col++) {
var cell = this.getCell(col, row);
if (cell && !cell.spanned) {
colIndex++;
result += "\t\t\t\t"+(colIndex)+" {\n";
result += "\t\t\t\t\tname = "+((!cell.name) ? col+"x"+row : cell.name)+"\n";
if (cell.colspan > 1) result += "\t\t\t\t\tcolspan = "+cell.colspan+"\n";
if (cell.rowspan > 1) result += "\t\t\t\t\trowspan = "+cell.rowspan+"\n";
if (typeof(cell.column) === 'number') result += "\t\t\t\t\tcolPos = "+cell.column+"\n";
result += "\t\t\t\t}\n";
}
}
result += "\t\t\t}\n";
result += "\t\t}\n";
}
result += "\t}\n}\n";
return result;
}
});
typo3/sysext/cms/layout/res/pagemodul.css (revision 0)
table.typo3-page-colHeader tr.colHeader td {
background-color: #B8BEC9;
background-image: url(../icons/gfx/shortcut_background.gif);
background-repeat: repeat-x;
padding-bottom: 2px;
padding-top: 2px;
}
table.typo3-page-colHeader tr.colHeader td div {
text-align: center;
color: #333;
padding-top: 2px;
}
table.typo3-page-colHeader tr.colHeader td div a.left {
float: left;
}
table.typo3-page-colHeader tr.colHeader td div a.right {
float: right;
}
table.typo3-page-ceHeader tr.ceHeader td {
background-color: #B8BEC9;
background-image: url('../icons/gfx/alt_menu_mainitem_bg.gif');
background-repeat: repeat-x;
color: #fff;
}
div.normal-element {
border-left: 1px solid #D7DBE2;
border-right: 1px solid #D7DBE2;
border-bottom: 1px solid #D7DBE2;
padding: 2px;
min-height: 24px;
background-color: #E4E5F0;
overflow: hidden;
}
table.typo3-page-colHeader{
margin-bottom: 5px;
}
div.contentElement{
position: relative;
}
table.typo3-page-langMode div.contentElement{
padding-bottom: 26px;
}
table.typo3-page-cols div.contentElement{
padding-bottom: 26px;
}
td.gridCell{
padding-left: 5px;
padding-right: 5px;
}
div.contentElement div{
padding-top: 0px;
}
div.contentElement table tbody tr td.ttContentHeaderWrapper{
height: 25px;
background-color: #adb5c0;
padding: 2px;
}
div.contentElement *{
opacity:0.9;filter:alpha(opacity=90);
}
div.contentElement.active *{
opacity:1.0;filter:alpha(opacity=100);
}
table.typo3-page-ceFooter tr td{
padding-top: 5px;
padding-bottom: 5px;
}
tr.colSubHeader td{
padding-top: 5px;
padding-bottom: 5px;
}
div#typo3-inner-docbody div table{
border: 0px;
}
div#typo3-inner-docbody td.colContent{
padding-left: 10px;
padding-right: 10px;
border: solid 1px;
border-color: #ccc;
}
table.typo3-page-colHeader tbody tr.colHeader td.bgColor2{
background-color: #aeb5c1;
background-image: url('');
}
img.languageFlag{
opacity:0.8;filter:alpha(opacity=80);
}
div.dropZone{
height: 25px;
width: 100%;
visibility: hidden;
}
div.dropZoneHighlight{
border: dotted 1px;
border-color: #b5bcc7;
height: 23px;
text-align: center;
min-width: 150px;
}
div.dropZone.active {
visibility: visible;
background-color: #ead2b7;
opacity:1.0;filter:alpha(opacity=100);
}
div.dropZone.validDrop{
background-color: #ff8700;
}
div.columnDropZone{
bottom: 0px;
margin-top: -30px;
}
div.contentElementDropZoneAfter{
position: absolute;
bottom: 0px;
margin-bottom: 0px;
}
div.ttContentHeader{
padding: 0px;
margin: 0px;
position: relative;
}
div.ttContentHeader div.left{
position: absolute;
left: 1px;
top: 2px;
}
div.ttContentHeader div.right{
position: absolute;
right: 1px;
top: 2px;
}
.displayNone{
display: none;
}
.onDrag{
border: solid 1px;
border-color: #cb2409;
width: 150px;
overflow: hidden;
}
div.gridContainer {
}
table.gridTable {
margin: -1px;
table-layout: fixed;
}
.td.gridCell {
background-color: #efeff4;
height: 100%;
padding: 5px
}
div.gridContainerNotEditable {
background-image: url(/typo3/sysext/cms/layout/res/grid.png);
border: 1px #bfbfc3 solid;
height: 100%;
padding: 0px 4px;
... This diff was truncated because it exceeds the maximum size that can be displayed.
(3-3/3)