Rozwijane menu

Najpierw budujemy strukturę html. Wszystko jest robione w scss, js w wersji ES6 i gulp
Do ES6 używam gulp-babel aby przekonwertować js do es2015

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<div class="container">

    <div id="accorions">
        <div class="accordion">Section 1</div>
        <div class="panel">
            <p>Sauerkraut can be garnished with cored avocado, also try decorateing the cake with hollandaise sauce.
                Asparagus can be marinateed with crushed lettuce, also try flavoring the loaf with salsa verde.
                with lobsters drink cream.</p>
        </div>

        <div class="accordion">Section 2</div>
        <div class="panel">
            <p>Aww, raid me parrot, ye dead landlubber! Swashbuckling, coal-black whales cowardly vandalize a mighty, gutless scabbard.
                Scabbards sing on booty at port degas! Small, dead tobaccos darkly fight a black, lively dagger.
                seashells fall with love.</p>
        </div>

        <div class="accordion">Section 3</div>
        <div class="panel">
            <p>Turbulence at the bridge was the adventure of mineral, lowered to a gravimetric mermaid.
                Moon at the universe was the mystery of coordinates, feeded to a real planet.
                wisely handle a processor.</p>
        </div>
    </div>

</div>

Dodajemy trochę css, na początku importuję normalize

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
@import "normalize";

.container {
    max-width: 500px;
    margin: 200px auto;

}

.accordion {
    background-color: #eee;
    color: #444;
    cursor: pointer;
    padding: 18px;
    width: 100%;
    border: none;
    text-align: left;
    outline: none;
    font-size: 15px;
    transition: 0.4s;
    &:after {
        content: '\002B';
        color: #777;
        font-weight: bold;
        float: left;
        margin-right: 5px;
    }
    &:hover {
        background-color: #ddd;
    }
    &.active {
        background-color: #ddd;
        &:after {
            content: "\2212";
        }
    }
}

.panel {
    padding: 0 18px;
    background-color: white;
    max-height: 0;
    overflow: hidden;
    transition: max-height 0.2s ease-out;
    li {
        list-style: none;
    }
}

Teraz najważniejsza część, dodajemy js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
"use strict";

class Accordion {

    constructor(options) {
        this.options = options;
        this.type = options.type;
    }

    creatAccordion() {
        let that = this;
        let acc = this.getAccordionName();
        let i;

        for (i = 0; i < acc.length; i++) {
            acc[i].onclick = function() {
                if(options.type === true && !this.classList.contains(options.activeName)) {
                    that.removeActiveAndPanelHeight();
                }
                this.classList.toggle(options.activeName);
                let panel = this.nextElementSibling;
                if (panel.style.maxHeight){
                    panel.style.maxHeight = null;
                } else {
                    panel.style.maxHeight = panel.scrollHeight + "px";
                }
            }
        }
    }

    getAccordionName() {
        return document.getElementsByClassName(options.accordionName);
    }

    removeActiveAndPanelHeight() {
        const currentActive = document.querySelectorAll("."+ options.activeName);
        const heightPanel = document.querySelectorAll("." + options.panelName);

        Array.prototype.forEach.call(currentActive, function (el) {
            el.classList.remove(options.activeName);
        });

        Array.prototype.forEach.call(heightPanel, function (el) {
            el.removeAttribute("style");
        });
    }
}

const options = {
    'accordionName': 'accordion',
    'activeName': 'active',
    'panelName': 'panel',
    'type': true
};

const accordion = new Accordion(options);
accordion.creatAccordion();

Przykład można zobaczyć pod tym adresem

Ostatni parametr w options czyli ‚type’: true lub false umożliwia sterowaniem zwijania menu, true powoduje że każde kliknięcie na menu zwija inne rozwinięte zaś false pozostawia rozwinięte każde kliknięcie.
Oczywiście options można przenieść do html aby z tego miejsca sterować nie musi być ten obiekt umieszczony w js.

Całość włącznie z gulpem można zobaczyć na github

Duża rozdzielczość ustawienia Visual Studio Code

Niestety duże monitory mają to do siebie że niektóre programy nie wyglądają za dobrze, zbyt małe czcionki itp. problemy.
Używam monitora z matrycą 2560×1440 i tutaj postanowiłem lekko zmodyfikować Visual Studio Code.
Do konfiguracji wchodzę przez ctrl+, otwiera się okno settings.json a tam dwa panele jedna z Defaults settings a z prawej strony z naszymi przyszłymi ustawieniami.
Podstawowa moja konfiguracja wygląda tak:

1
2
3
4
5
6
7
{
    "window.zoomLevel": 1,
    "editor.renderWhitespace": "all",
    "editor.fontSize": 14,
    "editor.wordWrap": "true",
    "workbench.iconTheme": "material-icon-theme"
}

Ostatni parametr pochodzi z „Material Icon Theme” polecam bardzo ładne ikonki używam także „1337 Theme”
A tak mniej więcej się prezentuje. vsc.

Nowy sposób serwowania ikon SVG

Sposób ten działa nawet w starszych przeglądarkach takich jak IE9.
Jednym z pierwszych możliwości jest budowa zestawu ikon które umieszczam od razu za „body” dla czego tutaj a nie na dole strony przed zamknięciem „/body” otóż gdy strona jest zbyt złożona i renderuje się dość wolno lub otwieramy stronę na telefonie i to w dodatku na słabym internecie np. 2G to ikony nie są widoczne od razu tylko renderują się dopiero po jakimś czasie. Sprawdzone i przetestowane.

1
2
3
4
5
6
7
8
9
10
<svg xmlns="http://www.w3.org/2000/svg" style="width: 0; height: 0; display: none;">
<symbol id="icon-home" viewBox="0 0 32 32">
<title>home</title>
<path d="M32 18.451l-16-12.42-16 12.42v-5.064l16-12.42 16 12.42zM28 18v12h-8v-8h-8v8h-8v-12l12-9z"></path>
</symbol>
<symbol id="icon-pencil" viewBox="0 0 32 32">
<title>pencil</title>
<path d="M27 0c2.761 0 5 2.239 5 5 0 1.126-0.372 2.164-1 3l-2 2-7-7 2-2c0.836-0.628 1.874-1 3-1zM2 23l-2 9 9-2 18.5-18.5-7-7-18.5 18.5zM22.362 11.362l-14 14-1.724-1.724 14-14 1.724 1.724z"></path>
</symbol>
</svg>

Teraz w miejscu w którym chcemy umieścić ikonę

1
2
3
<svg class="icon icon-home">
   <use xlink:href="#icon-home"></use>
</svg>

Oczywiście nie obejdzie się bez dodania odpowiedniego stylu dla icon 🙂

1
2
3
4
5
6
7
8
.icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  stroke-width: 0;
  stroke: currentColor;
  fill: currentColor;
}

Oczywiście ikony można kolorować dodając fill dla konkretnej ikony

1
2
3
.icon-home {
  fill: red;
}

Innym sposobem jest umieszczenie ikon w osobnym pliku np. symbol.svg
Do ikon dostajemy się w ten sposób symbol.svg#icon-home
Pełny przykład poniżej.

1
2
3
<svg class="icon icon-home">
   <use xlink:href="symbol.svg#icon-home"></use>
</svg>

Ale żeby to wszystko zagrało w IE musimy sięgnąć po js – svgxuse.js
Js ten dodajemy na końcu strony przed zamknięciem „/body”

Polecam do budowania systemu icon a przynajmniej na początku żeby zobaczyć z czym to się „je” stronę icomoon.io system ikon

Tam można wybrać interesujące nas ikony, a na dole na belce jest Generate SVG & More. Po kliknięciu tego napisu zapisuje się nasz wybrany zestaw icon powiedzmy na pulpicie, rozpakowujemy.

Często gdy dodaje własne ikony czy to z ilustratora czy innego programu do wektorów to najpierw optymalizuję ikony bo zawsze jest tak że te ikony które są zapisywane przez te programy mają nadmiar kodu. Dobrym przykładem takiej strony jest SVG optimizer
Czysty kod doklejam później do svg jako następny symbol.

Listowanie folderu w node

Aby wylistować folder z plikami i zapisać listę plików jako json na potrzeby tej strony – blog.grzgorztomicki.pl należy oczywiście mieć najpierw zainstalowane nodejs

Tworzymy plik powiedzmy list_images.js

Najpierw używamy wbudowanej biblioteki fs – fs

1
2
3
4
5
6
7
8
9
10
11
12
const fs = require("fs");
const nameGallery = "chiny";
const name = "test";

const test = [];
const author = "Grzegorz Tomicki";

let now = new Date();
let date = now.getDate() + "." + (now.getMonth()+1) + "." + now.getFullYear();

let datePublished = new Date().toISOString().slice(0,10);
let dateModified = datePublished;

Czytamy folder z plikami jpg za pomocą fs.readdir

1
2
3
4
fs.readdir(`./sources/images/${nameGallery}/1200/`, function (err, files) {
if (err)
throw err;
for (let index in files) {

Tutaj używamy czegoś nowego z ES6 a mianowicie „template string”. Używamy do tego znaku obok jeden na klawiaturze ` a zmienne podajemy w postaci ${} coś wspaniałego 🙂
Poniżej są dwa przykłady użycia a mianowicie path jak i template – wiele linii jak widać nie trzeba sklejać za pomocą „+” cud malina 🙂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
let path = `{"path":"./images/${nameGallery}/","img":"${files[index]}","alt":""}`;
test.push("\r\n\t\t\t\t" + path);
}

const template = (`{
"head": {
"title": "",
"description": ""
},
"body": {
"title": "",
"date": "${date}",
"text": "",
"items": [${test}
]
},
"footer": {
"js": "../../build/js/boundle.min.js"
},
"schema": {
"datePublished": "${datePublished}",
"dateModified": "${dateModified}",
"author": "${author}"
}
}
`
);

Zapisujemy plik za pomocą fs.writeFile

1
2
fs.writeFile(`./sources/data/site/${name}.json`, template, function (err) {});
});

Aby oczywiście uruchomić ten plik należy go uruchomić przez komendę w konsoli node list_images.js
Cały proces tworzenia strony można znaleźć pod tym linkiem tutaj

Błąd w wordpress: Prawdopodobnie twój serwer ma wyłączoną funkcję mail()

Gdy wordpress zwraca błąd: Prawdopodobnie twój serwer ma wyłączoną funkcję mail()
( Possible reason: your host may have disabled the mail() function. )

oznacza, że prawdopodobnie admini serwera zablokowali wysyłkę maili funkcją mail, dla danej domeny na koncie hostingowym.

W lini 378 znajduje się poniższy kod, który zwraca link do odzyskiwania hasła:

1
2
$message = apply_filters( 'retrieve_password_message', $message, $key,
$user_login, $user_data );

echo $message, wyświetli link do odzyskiwania hasła i można go wkleić do przeglądarki

Przykład użycia funkcji GROUP_CONCAT

1
SELECT GROUP_CONCAT(kto ORDER BY kto ASC SEPARATOR ', ') FROM raport_ludzie_spotkania

Złączenie rekordów wątku do jednego stringa, wycinanie 80 znaków stringa:

1
2
3
4
5
6
7
8
9
SELECT t.ticket_id, t.created,
SUBSTRING(last_notes_title, 1, (80 + LOCATE(' ', last_notes_title, 80))) AS last_notes_title,
SUBSTRING(last_notes_body, 1, (80 + LOCATE(' ', last_notes_body, 80))) AS last_notes_body
FROM (
SELECT ticket_id, created,
GROUP_CONCAT(title ORDER BY created DESC SEPARATOR '|') AS last_notes_title,
GROUP_CONCAT(body ORDER BY created DESC SEPARATOR '|') AS last_notes_body
FROM ost_ticket_thread WHERE ticket_id IN (1,2,3,4,5) GROUP BY ticket_id
) AS t