Category Archives: Codice

Sass mixin to generate a full set of classes with mediaqueries variants

Here we are, we need a full set of some specific classes, why don’t write a sass mixin for that?

do more with less code!

The need classes are like:

.margin-top-small { margin-top: $gutter-grid-width / 2; }
.margin-top-normal { margin-top: $gutter-grid-width; }
.margin-top-large { margin-top: $gutter-grid-width * 2; }
.margin-top-xlarge { margin-top: $gutter-grid-width * 3; }

.margin-bottom-small { margin-bottom: $gutter-grid-width / 2; }
.margin-bottom-normal { margin-bottom: $gutter-grid-width; }
.margin-bottom-large { margin-bottom: $gutter-grid-width * 2; }
.margin-bottom-xlarge { margin-bottom: $gutter-grid-width * 3; }

and then we need some classes for specific mediaqueries

.margin-top-md-small, .margin-top-md-normal, .margin-top-md-large
.margin-top-sm-small, ...
.margin-top-xs-small, ...

and so on, if you ask why, the answer is: we like to use those classes here and there in several projects to have a solid and common understanding of margins, especially used for separate content elements in a complex CMS like TYPO3 in a middle company with several developers.

<div class="margin-top-large margin-bottom-small"> 

since the set is growing and i need also specific mediaquery classes I create a sass mixin to generate the whole set:

@mixin class-property-scale($classname, $property) {

	$list: none, xsmall, small, large, xlarge, xxlarge;
	$scale: 0, 1/3, 1/2, 1, 2, 3;

	@for $i from 1 through length($list) {
	   .#{$classname}-#{nth($list, $i)} {
		   #{$property}: $grid-gutter-width * nth($scale, $i)
	   }
	}

}

and the usage is

// create a full set of margin padding for varius mediaqueries

// all devices
@include class-property-scale(mt, margin-top);
@include class-property-scale(mb, margin-bottom);
@include class-property-scale(pt, padding-top);
@include class-property-scale(pb, padding-bottom);

// only small screen
@media (max-width: $screen-sm-max) {
	@include class-property-scale(mt-xs, margin-top);
	@include class-property-scale(mb-xs, margin-bottom);
	@include class-property-scale(pt-xs, padding-top);
	@include class-property-scale(pb-xs, padding-bottom);
}

// tablets
@media (min-width: $screen-sm-min) and (max-width: $screen-md-max) {
	@include class-property-scale(mt-sm, margin-top);
	@include class-property-scale(mb-sm, margin-bottom);
	@include class-property-scale(pt-sm, padding-top);
	@include class-property-scale(pb-sm, padding-bottom);
}

// desktop
@media (min-width: $screen-md-min) {
	@include class-property-scale(pr-md, padding-right);
	@include class-property-scale(mt-md, margin-top);
	@include class-property-scale(mb-md, margin-bottom);
	@include class-property-scale(pt-md, padding-top);
	@include class-property-scale(pb-md, padding-bottom);
}

(instead of margin-top-large i used mt-large and mb-large)
and the result in my final css is :


.mt-none {
    margin-top: 0
}

.mt-xsmall {
    margin-top: 10px
}

.mt-small {
    margin-top: 15px
}

.mt-large {
    margin-top: 30px
}

.mt-xlarge {
    margin-top: 60px
}

.mt-xxlarge {
    margin-top: 90px
}

.mb-none {
    margin-bottom: 0
}

.mb-xsmall {
    margin-bottom: 10px
}

.mb-small {
    margin-bottom: 15px
}

.mb-large {
    margin-bottom: 30px
}

.mb-xlarge {
    margin-bottom: 60px
}

.mb-xxlarge {
    margin-bottom: 90px
}

.pt-none {
    padding-top: 0
}

.pt-xsmall {
    padding-top: 10px
}

.pt-small {
    padding-top: 15px
}

.pt-large {
    padding-top: 30px
}

.pt-xlarge {
    padding-top: 60px
}

.pt-xxlarge {
    padding-top: 90px
}

.pb-none {
    padding-bottom: 0
}

.pb-xsmall {
    padding-bottom: 10px
}

.pb-small {
    padding-bottom: 15px
}

.pb-large {
    padding-bottom: 30px
}

.pb-xlarge {
    padding-bottom: 60px
}

.pb-xxlarge {
    padding-bottom: 90px
}

@media (max-width: 1023px) {
    .mt-xs-none {
        margin-top:0
    }

    .mt-xs-xsmall {
        margin-top: 10px
    }

    .mt-xs-small {
        margin-top: 15px
    }

    .mt-xs-large {
        margin-top: 30px
    }

    .mt-xs-xlarge {
        margin-top: 60px
    }

    .mt-xs-xxlarge {
        margin-top: 90px
    }

    .mb-xs-none {
        margin-bottom: 0
    }

    .mb-xs-xsmall {
        margin-bottom: 10px
    }

    .mb-xs-small {
        margin-bottom: 15px
    }

    .mb-xs-large {
        margin-bottom: 30px
    }

    .mb-xs-xlarge {
        margin-bottom: 60px
    }

    .mb-xs-xxlarge {
        margin-bottom: 90px
    }

    .pt-xs-none {
        padding-top: 0
    }

    .pt-xs-xsmall {
        padding-top: 10px
    }

    .pt-xs-small {
        padding-top: 15px
    }

    .pt-xs-large {
        padding-top: 30px
    }

    .pt-xs-xlarge {
        padding-top: 60px
    }

    .pt-xs-xxlarge {
        padding-top: 90px
    }

    .pb-xs-none {
        padding-bottom: 0
    }

    .pb-xs-xsmall {
        padding-bottom: 10px
    }

    .pb-xs-small {
        padding-bottom: 15px
    }

    .pb-xs-large {
        padding-bottom: 30px
    }

    .pb-xs-xlarge {
        padding-bottom: 60px
    }

    .pb-xs-xxlarge {
        padding-bottom: 90px
    }
}

@media (min-width: 768px) and (max-width:1399px) {
    .mt-sm-none {
        margin-top:0
    }

    .mt-sm-xsmall {
        margin-top: 10px
    }

    .mt-sm-small {
        margin-top: 15px
    }

    .mt-sm-large {
        margin-top: 30px
    }

    .mt-sm-xlarge {
        margin-top: 60px
    }

    .mt-sm-xxlarge {
        margin-top: 90px
    }

    .mb-sm-none {
        margin-bottom: 0
    }

    .mb-sm-xsmall {
        margin-bottom: 10px
    }

    .mb-sm-small {
        margin-bottom: 15px
    }

    .mb-sm-large {
        margin-bottom: 30px
    }

    .mb-sm-xlarge {
        margin-bottom: 60px
    }

    .mb-sm-xxlarge {
        margin-bottom: 90px
    }

    .pt-sm-none {
        padding-top: 0
    }

    .pt-sm-xsmall {
        padding-top: 10px
    }

    .pt-sm-small {
        padding-top: 15px
    }

    .pt-sm-large {
        padding-top: 30px
    }

    .pt-sm-xlarge {
        padding-top: 60px
    }

    .pt-sm-xxlarge {
        padding-top: 90px
    }

    .pb-sm-none {
        padding-bottom: 0
    }

    .pb-sm-xsmall {
        padding-bottom: 10px
    }

    .pb-sm-small {
        padding-bottom: 15px
    }

    .pb-sm-large {
        padding-bottom: 30px
    }

    .pb-sm-xlarge {
        padding-bottom: 60px
    }

    .pb-sm-xxlarge {
        padding-bottom: 90px
    }
}

@media (min-width: 1024px) {
    .pr-md-none {
        padding-right:0
    }

    .pr-md-xsmall {
        padding-right: 10px
    }

    .pr-md-small {
        padding-right: 15px
    }

    .pr-md-large {
        padding-right: 30px
    }

    .pr-md-xlarge {
        padding-right: 60px
    }

    .pr-md-xxlarge {
        padding-right: 90px
    }

    .mt-md-none {
        margin-top: 0
    }

    .mt-md-xsmall {
        margin-top: 10px
    }

    .mt-md-small {
        margin-top: 15px
    }

    .mt-md-large {
        margin-top: 30px
    }

    .mt-md-xlarge {
        margin-top: 60px
    }

    .mt-md-xxlarge {
        margin-top: 90px
    }

    .mb-md-none {
        margin-bottom: 0
    }

    .mb-md-xsmall {
        margin-bottom: 10px
    }

    .mb-md-small {
        margin-bottom: 15px
    }

    .mb-md-large {
        margin-bottom: 30px
    }

    .mb-md-xlarge {
        margin-bottom: 60px
    }

    .mb-md-xxlarge {
        margin-bottom: 90px
    }

    .pt-md-none {
        padding-top: 0
    }

    .pt-md-xsmall {
        padding-top: 10px
    }

    .pt-md-small {
        padding-top: 15px
    }

    .pt-md-large {
        padding-top: 30px
    }

    .pt-md-xlarge {
        padding-top: 60px
    }

    .pt-md-xxlarge {
        padding-top: 90px
    }

    .pb-md-none {
        padding-bottom: 0
    }

    .pb-md-xsmall {
        padding-bottom: 10px
    }

    .pb-md-small {
        padding-bottom: 15px
    }

    .pb-md-large {
        padding-bottom: 30px
    }

    .pb-md-xlarge {
        padding-bottom: 60px
    }

    .pb-md-xxlarge {
        padding-bottom: 90px
    }
}

don’t worry the css is minified and gzipped via gulp at the end 😉

bootstrap equal-height columns with flexbox ultimate solution for mobile safari and IE11

I’ve struggled a lot trying to use flexbox to create equal-height boxes.

As we know flexbox is not really well implemented expecially on mobile safari and IE11

The situation is the classical bootstrap with some columns with bootstrap classes

<div class="row eq-height">
	<div class="col-sm-6 col-md-4">bla bla bla</div>
	<div class="col-sm-6 col-md-4">bla bla bla</div>
	<div class="col-sm-6 col-md-4">bla bla blabla bla</div>
	<div class="col-sm-6 col-md-4">bla bla blabla bla blabla bla blabla bla bla</div>
	<div class="col-sm-6 col-md-4">bla<br /><br /> bla<br /> bla</div>
	<div class="col-sm-6 col-md-4">bla bla bla</div>
	<div class="col-sm-6 col-md-4">bla bla<br /> bla</div>
	<div class="col-sm-6 col-md-4">bla bla bla</div>
	<div class="col-sm-6 col-md-4">bla bla bla</div>
</div>

the sass css that solve my issues is:

.eq-height {
	@media (min-width:$screen-sm-min) {
		display: flex;
		flex-wrap: wrap;
	}


	& > [class*='col-'] {
		background-clip: content-box;
		@media (min-width:$screen-sm-min) {
			display: flex;
			flex-wrap: wrap;
			flex-direction: column; // FF 47-
			-webkit-flex-direction: row; // iOS safari
			-ms-flex-direction: column; // IE11
		}
	}

	&:before,
	&:after {
		@media (min-width:$screen-sm-min) {
			content: normal; // IE doesn't support `initial`
		}
	}
}

gulp + sass generate all browser prefixes but I added different flex-direction for different browsers on col-* classes. That’s my solution that do the magic on safari, chrome, firefox and IE11.

	flex-direction: column; // FF 47-
	-webkit-flex-direction: row; // iOS safari
	-ms-flex-direction: column; // IE11

How to quickly handle file extensions icons, only via CSS no JS no PHP

This is the quickest way to put different icons for downloadable files, via CSS, no JS or PHP needed.


  a.download-link:before{
    content: url('default.gif');
    margin-right: 6px;
    vertical-align: middle;
  }

  a.download-link[href$='.pdf']:before{
    content: url('pdf.gif');
  }

  a.download-link[href$='.doc']:before,
  a.download-link[href$='.rtf']:before,
  a.download-link[href$='.txt']:before  {
    content: url('doc.gif');
  }

  a.download-link[href$='.docx']:before {
    content: url('docx.gif');
  }

  a.download-link[href$='.xls']:before {
    content: url('xls.gif');
  }

  a.download-link[href$='.xlsx']:before  {
    content: url('xlsx.gif');
  }

RealURL replace segments encode and decode

Funzioni di replace nel RealURL, inserire le seguenti righe nel file realurl_userconf.php

// put this two function at the begin of realurl_userconf.php file

function user_encodeSpURL_postProc(&$params, &$ref) {
//   $params['URL'] = str_replace('calendar/location/tx_cal_location/location/', 'calendar/location/', $params['URL']);
//   $params['URL'] = str_replace('calendar/organizer/tx_cal_organizer/organizer/', 'calendar/organizer/', $params['URL']);
//   $params['URL'] = str_replace('calendar/tx_cal_phpicalendar/event/2011/', 'calendar/2011/', $params['URL']);
//   $params['URL'] = str_replace('calendar/tx_cal_phpicalendar/event/2012/', 'calendar/2012/', $params['URL']);
//   $params['URL'] = str_replace('calendar/tx_cal_phpicalendar/event/2013/', 'calendar/2013/', $params['URL']);
  $params['URL'] = str_replace('event/tx_cal_phpicalendar/', 'evento/', $params['URL']);
  $params['URL'] = str_replace('news/news-detail/news/', 'dettaglio-news/', $params['URL']);
}
function user_decodeSpURL_preProc(&$params, &$ref) {
//   $params['URL'] = str_replace('calendar/location/', 'calendar/location/tx_cal_location/location/', $params['URL']);
//   $params['URL'] = str_replace('calendar/organizer/', 'calendar/organizer/tx_cal_organizer/organizer/', $params['URL']);
//   $params['URL'] = str_replace('calendar/2011/', 'calendar/tx_cal_phpicalendar/event/2011/', $params['URL']);
//   $params['URL'] = str_replace('calendar/2012/', 'calendar/tx_cal_phpicalendar/event/2012/', $params['URL']);
//   $params['URL'] = str_replace('calendar/2013/', 'calendar/tx_cal_phpicalendar/event/2013/', $params['URL']);
  $params['URL'] = str_replace('evento/', 'event/tx_cal_phpicalendar/', $params['URL']);
  $params['URL'] = str_replace('dettaglio-news/', 'news/news-detail/news/', $params['URL']);
}


$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['realurl']=array (
// put this two encode/decode at the begin of realurl conf array
  'encodeSpURL_postProc' => array('user_encodeSpURL_postProc'),
  'decodeSpURL_preProc' => array('user_decodeSpURL_preProc'),
// begin of default realurl conf array
  '_DEFAULT' =&gt; 
...

news list tx_news RealURL configuration paginate widget

News list realurl configuration, here the official doc:

http://docs.typo3.org/typo3cms/extensions/news/Main/Administration/Realurl/Index.html

if you want to add paginate realurl configuration see the example in advanced example and add this piece in postVarSets:

'postVarSets' => array(
        '_DEFAULT' => array(
                //put this after controller and dateFilter...
                'pag' => array(
                        array(
                                'GETvar' => 'tx_news_pi1[@widget_0][currentPage]',
                                //'noMatch' => 'bypass'
                        )
                )
        ),
),

MySQL signed unix_timestamp per convertire date precedenti al 1-1-1970

su TYPO3 le date sono salvate come unix_timestamp, un numero intero positivo se successive al 1-1-1970, negativo se precendenti.

MySQL ha una funzione UNIX_TIMESTAMP che restituisce zero per le date precedenti al 1-1-1970, quindi è sufficiente dichiarare una funzione SIGNED_UNIX_TIMESTAMP e usarla:

DELIMITER |
CREATE FUNCTION SIGNED_UNIX_TIMESTAMP (d DATETIME)
RETURNS BIGINT
 DETERMINISTIC
  BEGIN
    DECLARE tz VARCHAR(100);
    DECLARE ts BIGINT;
    SET tz = @@time_zone;
    SET time_zone = '+00:00';
    SELECT DATEDIFF(d, FROM_UNIXTIME(0)) * 86400 +
    TIME_TO_SEC(
      TIMEDIFF(
        d,
        DATE_ADD(MAKEDATE(YEAR(d), DAYOFYEAR(d)), INTERVAL 0 HOUR)
      )
    ) INTO ts;
    SET time_zone = tz;
    return ts;
  END|
DELIMITER ;

Poi usata ad esempio così:

UPDATE fe_users SET
`date_of_birth` = SIGNED_UNIX_TIMESTAMP('1955-10-21'),
WHERE 1

Nota: il campo date_of_birth è aggiunto dall’estensione sr_feuser_register

TYPO3 Content PageBrowser ws_contentpagebrowser

Mostrare i contenuti con un page-browser ecco come grazie a ws_contentpagebrowser

sul repository: Content with PageBrowser ws_contentpagebrowser – typo3.org.

Un esempio reale:

http://www.cerviaintavola.it/ristoranti-pizzerie-cervia-milano-marittima/

e

http://www.cerviaintavola.it/numeri-utili/

con un po’ di TypoScript


[globalVar = TSFE:id = 78]
plugin.tx_pagebrowse_pi1 = USER
plugin.tx_pagebrowse_pi1 {
  templateFile = fileadmin/template/pagebrowse.html
  pagesBefore = 5
  pagesAfter = 5
  pageParameterName = tx_wscontentpagebrowser_pi1|page
  enableMorePages = 0
  enableLessPages = 0
}

plugin.tx_wscontentpagebrowser_pi1 {
  limit = 1
  content = CONTENT
  content {
    table = tt_content
    select {
      pidInList = this
      orderBy = sorting
      languageField = sys_language_uid
      where = CType IN ("text","textpic","image","multimedia","media")
    }
  }
}

page.10.subparts.content < plugin.tx_wscontentpagebrowser_pi1
[global]

Menu sitemap con un semplice TypoScript, estesa a tutti i livelli e ristretto su una base di partenza

Capita frequentemente di voler generare una pagina “mappa del sito” con tutti i livelli, la soluzione è mettere un contenuto di tipo “sitemap”.

Questo però ha il difetto di mostrare tutte le pagine, a volte è necessario non mostrare un intero ramo.

Quindi è conveniente adottare la “mappa delle sottopagine”, selezionando le pagine desiderate, che però si estende ad un solo livello.

Aggiungendo un veloce TypoScript si può estendere il numero di livelli:


tt_content.menu.20.1.1.expAll = 1
tt_content.menu.20.1.2 < tt_content.menu.20.1.1
tt_content.menu.20.1.2.wrap = <ul>|</ul>
tt_content.menu.20.1.3 < tt_content.menu.20.1.1
tt_content.menu.20.1.3.wrap = <ul>|</ul>
tt_content.menu.20.1.4 < tt_content.menu.20.1.1
tt_content.menu.20.1.4.wrap = <ul>|</ul>