In the first part we have prepared our page.
After reading the comments, I want to make a small digression: I’m not saying that this approach is perfect, or everyone should follow and now write just this way. I know about the availability of programs for this. But the essence of the article was to share thoughts on how to do it yourself, and at the same time to understand different technologies. It is always interesting to look for new ways, even if they are incorrect, or too long, but they teach us something new, even if we passed them with mistakes.
Imitation base, as I have already written in the comments, is json files with the content of the desired text. Question: "Why is Vue here? If it can be written on scripts?". To be honest - for the beauty of html layout. Well, learn new technologies.
Let's get started!
On this page, the separation is not at all necessary, because there are not so many variables here, but I prefer to divide everything into different parts. We will have a component responsible for the header, content & footer (will appear later).
First, we create json files, I create a "data" folder and in it create two files "ru.json" and "en.json". In them, respectively, the names will be our text. Next, open our html and make substitutions for the future, trying to name the variables so that they fully reflect the meaning of the text in them. In my case it was like this:
<header class="transition tr-header" id="header"> <div class="container"> <div class="nav-holder"> <nav class="scroll-nav"> <ul> // <li class="actscroll"><a href="#sec1">{{main}} </a></li> <li><a href="#sec2">{{aboutCompany}}</a></li> <li><a href="#sec3">{{product}}</a></li> <li><a href="#sec4">{{equipment}}</a></li> <li><a href="#sec5">{{whereBuy}}</a></li> <li><a href="#sec6">{{service}}</a></li> <li><a href="#sec7">{{partners}}</a></li> <li><a href="#sec8">{{contacts}}</a></li> </ul> </nav> <div class="lang-dropdown"> <div class="flag-with-menu" id="flag-menu"> <div class="flag flag-ru" lang-value="ru-RU"></div> </div> <div id="lang-menu" class="lang-menu lang-first-init"> <div class="flag flag-us" lang-value="en-US"></div> </div> </div> </div> </div> </header> <!-- End header --> <!--================= Photo home ================--> <section class="is_overlay page-title-bg" id="sec1" name="sec1"> <div class="bg bg-parallax run-par2" style="background-image: url(images/paraplan.jpg) "></div> <div class="overlay over-op6"></div> </section> <!-- section end --> <div id="contentPage"> // <section class="align-text" id="sec2" name="sec2"> <div class="content"> <div class="container"> <div class="row"> <div class="col-md-6 "> <h3>{{aboutCompanyHeader}}</h3> <div class="clearfix"></div> <div class="separator color-separator flt-l"></div> <div class="clearfix"></div> <p>{{aboutCompanyText}}</p> </div> <div class="col-md-6 "> <h3>{{ourMissionHeader}}</h3> <div class="clearfix"></div> <div class="separator color-separator flt-l"></div> <div class="clearfix"></div> <p>{{ourMissionText}}</p> </div> </div> </div> </div> </section> // , div </div>
Go to the language files: (it was possible to add everything to one array or one object, but it’s more convenient for me when the text is broken in this way). "ru.json"
[ { "main": "" }, { "aboutCompany": " " }, { "product": " " }, { "equipment": " " }, { "whereBuy": " " }, { "service": "" }, { "partners": "" }, { "contacts": "" }, {"aboutCompanyHeader": " "}, { "aboutCompanyText": [ "«» — IT-, «». ", " 2006- «» ", " , 8 .", "«» , , ", " , , , IT — .", " «» - — Geektimes, ", " , ." ] }, { "ourMissionHeader": " " }, { "ourMissionText": [ " ", ". , ", " . , , ", " . . ", " . ", " , , ." ] } ]
Well, you yourself hope to cope with the translation of this text into English!
After checking, the menu with languages stopped working normally for me, so if you encounter a similar problem, here’s a quick fix: "multilanguage.js"
replaceElementAndSelect(userLanguage); // $(document).on('click', '.flag ', function () { if (!isMenuClicked && !$(this).hasClass('select-flag')) { var newLang = $(this).attr('lang-value'); language = newLang; setCookie("language", language); languageChange(newLang); hideMenu(); } isMenuClicked = false; }); // $(document).on('click', "#flag-menu", function () { isMenuClicked = true; showOrHideMenu(); }); // menu $('#lang-menu'). : menu.hasClass('lang-first-init') $('#lang-menu').hasClass('lang-first-init'). .
In the folder "scripts" add the new "main-function.js". And we add a couple of methods to it (because in my case they were reused later):
// json function findInArray(langArray, component) { $.each(langArray, function (index, value) { Object.keys(value).forEach(function (key) { var val = value[key]; if ($.isArray(val)) { component[key] = val.join(", "); } else { component[key] = value[key]; } }); }); } // function getArrayFromJson(url) { return $.ajax({ url: url, dataType: 'json' }); }
In the folder "scripts" add the new "index.js". And parse it
$(document).ready(function () { var language = getCookie("language") || navigator.language || navigator.browserLanguage; // . // var ruUrl = location.origin + '/data/ru.json'; var enUrl = location.origin + '/data/en.json'; // , Vue var en = [], ru = []; var vm, vmHeader; initialize(); // , $(document).on('onLanguageChange', function (e, eventInfo) { setPageTemplateByLanguage(eventInfo); }); function initialize() { // Vue createMainComponent(); // json $.when(getArrayFromJson(ruUrl), getArrayFromJson(enUrl)) .done(function (a1, a2) { ru = a1[0]; en = a2[0]; setPageTemplateByLanguage(language); // }); } function createMainComponent() { // , , vm = new Vue({ el: '#contentPage', data: { siteHeader: "", siteSubHeader: "", aboutCompanyHeader: "", aboutCompanyText: "", ourMissionHeader: "", ourMissionText: "" }, // , "". . updated: function () { this.$nextTick(function () { // createCarusel(); }); } }); vmHeader = new Vue({ el: '#header', data: { aboutCompany: "", product: "", equipment: "", whereBuy: "", service: "", partners: "", contacts: "" } }); } // function setPageTemplateByLanguage(lang) { switch (lang) { case "en-US": findInArray(en, vmHeader); findInArray(en, vm); break; case "ru-RU": findInArray(ru, vmHeader); findInArray(ru, vm); break; default: findInArray(ru, vmHeader); findInArray(ru, vm); break; } } });
Now it remains to add it to our page, and do not forget to download vue.min.js in the "scripts" folder
<script src="scripts/jquery.min.js"></script> <script src="scripts/vue.min.js"></script> <script src="scripts/cookie.js"></script> <script src="scripts/multilanguage.js"></script> <script src="scripts/main-function.js"></script> <script src="scripts/index.js"></script>
Basically, that's all, quite a bit of code for a beautiful solution!
But I want to go a little further and add a couple of Vue components (for example). Maybe someone will benefit from this. Of the new components, this will be the footer and the title of the site, otherwise our picture looks empty.
Create two files in the "data" folder: "footer_ru.json" and "footer_en.json"
[ {"getInTouch": ""}, {"region": ", -"}, {"street": " , 13 / 7" }, {"phone": "8 (812) 666-66-66"}, {"mobilePhone": "+7 (966) 666-66-66"}, {"email": "ivanov@mail.ru"}, {"secondEmail": "info@gmai.com"}, {"findUs": " "}, {"firstLine": ""}, {"secondLine": " "}, {"firstPartLastLine": "2014 OOO "}, {"colorPartLastLine": " "}, {"thirdPartLastLine": " "} ]
I take it to a file with common functions, because I reuse it in my room. Add to "main-function.js"
// var ruFooterUrl = location.origin + '/data/footer_ru.json'; var enFooterUrl = location.origin + '/data/footer_en.json'; var vueFooter; var ruFooterInfo = [], enFooterInfo = []; // $(document).on('onLanguageChange', function (e, eventInfo) { setPageTemplateByLanguageMain(eventInfo); }); // Vue.component('habr-footer', { props: ['get-in-touch', 'region', 'street', 'email', 'second-email', 'phone', 'mobile-phone', 'find-us', 'first-line', 'second-line', 'first-part-last-line', 'color-part-last-line', 'third-part-last-line'], template: `<div> <section class="page-widgets-holder"> <div class="content"> <div class="container"> <div class="row"> <div class="col-md-4 "> <h3>{{getInTouch}}</h3> <div class="contact-info"> <ul> <li><a class="ci-adress">{{region}}<br> {{street}}</a></li> <li><a class="ci-mail"> {{email}}</a></li> <li><a class="ci-mail"> {{secondEmail}}</a></li> <li> <a v-bind:href="'tel:' + phone" class="ci-phone"> {{phone}} </a></li> <li> <a v-bind:href="'tel:' + mobilePhone" class="ci-phone"> {{mobilePhone}} </a></li> </ul> </div> </div> <div class="col-md-4 "> </div> <div class="col-md-4 "> <h3>{{findUs}}</h3> <div class="social-links"> <ul> <li><a href="#" target="_blank" class="transition"><i class="fa fa-facebook"></i></a></li> <li><a href="#" target="_blank" class="transition"><i class="fa fa-vk"></i></a></li> <li><a href="#" target="_blank" class="transition"><i class="fa fa-twitter"></i></a></li> <li><a href="#" target="_blank" class="transition"><i class="fa fa-youtube"></i></a></li> <li><a href="#" target="_blank" class="transition"><i class="fa fa-instagram"></i></a></li> </ul> </div> </div> </div> </div> </div> </section> <!-- section end --> <!--================= footer ================--> <section class="page-widgets-holder footer"> <div class="container"> <div class="row"> <div class="col-md-3 "> <h4>{{firstLine}}</h4> <h5>{{secondLine}}</h5> </div> <div class="col-md-9"> <div class="policy-box"> <p>{{firstPartLastLine}} <span>{{colorPartLastLine}} </span> {{thirdPartLastLine}}</p> </div> </div> </div> </div> </section> </div>` }); // function createFooterComponent() { vueFooter = new Vue({ el: '#vueFooter', data: { footerInfo: { getInTouch: "", region: "", street: "", email: "", secondEmail: "", phone: "", mobilePhone: "", findUs: "", firstLine: "", secondLine: "", firstPartLastLine: "", colorPartLastLine: "", thirdPartLastLine: "" } }, created: function () { this.loadData(); }, methods: { loadData() { $.when(getArrayFromJson(ruFooterUrl), getArrayFromJson(enFooterUrl) ).done(function (a1, a2) { ruFooterInfo = a1[0]; enFooterInfo = a2[0]; setPageTemplateByLanguageMain(); }); } } }); } // function setPageTemplateByLanguageMain(lang) { var userLanguage = lang || getCookie("language") || language; switch (userLanguage) { case "en-US": findInArray(enFooterInfo, vueFooter.footerInfo); break; case "ru-RU": findInArray(ruFooterInfo, vueFooter.footerInfo); break; default: findInArray(ruFooterInfo, vueFooter.footerInfo); break; } }
To make it all beautiful, download Font Awesome and add it to the "css" folder.
In our "style.css" we add classes for a beautiful display:
.page-widgets-holder { border-top:1px solid #ccc; } .page-widgets-holder h3 { font-size:14px; text-align:center; color:#666; font-family: 'Montserrat', sans-serif; text-transform:uppercase; margin-bottom:40px; position:relative; } .page-widgets-holder h3:before { content:''; position:absolute; width:40px; height:2px; background:#ccc; bottom:-10px; left:50%; margin-left:-20px; } .contact-info li { float:left; width:100%; margin-bottom:12px; } .contact-info li a { font-family: 'Montserrat', sans-serif; } .ci-adress { text-transform:uppercase; font-size:14px; text-align:left; color:#000; line-height:20px; } .ci-mail { font-size:14px; text-align:left; } .ci-phone { color:#666; line-height:20px; } .social-links { padding-bottom:58px; } .social-links li { display:inline-block; margin:0 1px; box-sizing:border-box; } .social-links li a { width:50px; height:50px; background:#eee; border-radius:100%; line-height:50px; float:left; color:#666; font-size:20px; box-shadow:0 0 0 20px transparent; } .social-links li a:hover { box-shadow:0 0 0 0 rgba(0,0,0,0.1); } .fa { margin-left: 0.75em; margin-top: 0.75em; }
Add the "initialize ()" method to "index.js":
function initialize() { createFooterComponent(); // createMainComponent(); $.when(getArrayFromJson(ruUrl), getArrayFromJson(enUrl)) .done(function (a1, a2) { ........ }); }
And in "index.html" add:
<link rel="stylesheet" href="css/font-awesome-4.7.0/css/font-awesome.min.css" media="all"> ...... <body> <!--================= main start ================--> <div id="main"> <div id="wrapper"> <div class="content-holder"> <!--================= Header ================--> <header class="transition tr-header" id="header"> ........... </header> <!-- End header --> <!--================= Photo home ================--> <section class="is_overlay page-title-bg" id="sec1" name="sec1"> ........ </section> <!-- section end --> <div id="contentPage"> ........ </div> <!-- --> <div id="vueFooter"> <habr-footer v-bind="footerInfo"></habr-footer> </div> </div> </div> </div> </body>
Well, the final component, this is the header of the site, I add it to the "main-function.js":
var vmPageHeader, vueFooter;// var ruFooterInfo = [], enFooterInfo = []; var ruHeaderInfo = [], enHeaderInfo = []; // Vue.component('habr-header', { props: ['site-header', 'site-sub-header'], template: `<div class="container"> <div class= "page-title-bg-holder hero-wrapper"> <h2>{{ siteHeader }}</h2> <p>{{siteSubHeader}}</p> </div> </div>` }); // 2 , , function createHeaderComponent(ruUrl, enUrl) { vmPageHeader = new Vue({ el: '#vueHeader', data: { siteSubHeader: "", siteHeader: "" }, created: function () { this.loadData(); }, methods: { loadData() { $.when( getArrayFromJson(ruUrl), getArrayFromJson(enUrl)) .done(function (a1, a2) { ruHeaderInfo = a1[0]; enHeaderInfo = a2[0]; setPageTemplateByLanguageMain(); }); } } }); } function setPageTemplateByLanguageMain(lang) { var userLanguage = lang || getCookie("language") || language; switch (userLanguage) { case "en-US": findInArray(enHeaderInfo, vmPageHeader);// findInArray(enFooterInfo, vueFooter.footerInfo); break; case "ru-RU": findInArray(ruHeaderInfo, vmPageHeader);// findInArray(ruFooterInfo, vueFooter.footerInfo); break; default: findInArray(ruHeaderInfo, vmPageHeader);// findInArray(ruFooterInfo, vueFooter.footerInfo); break; } }
In the "en.json" and "ru.json" add the data:
[ { "siteHeader": "«»" }, { "siteSubHeader": " " }, .......... ]
Add the "initialize ()" method to "index.js":
function initialize() { createFooterComponent(); createMainComponent(); createHeaderComponent(ruUrl, enUrl);// $.when(getArrayFromJson(ruUrl), getArrayFromJson(enUrl)) .done(function (a1, a2) { ........ }); }
And in "index.html" add:
<link rel="stylesheet" href="css/font-awesome-4.7.0/css/font-awesome.min.css" media="all"> ...... <body> <!--================= main start ================--> <div id="main"> <div id="wrapper"> <div class="content-holder"> <!--================= Header ================--> <header class="transition tr-header" id="header"> ........... </header> <!-- End header --> <!--================= Photo home ================--> <section class="is_overlay page-title-bg" id="sec1" name="sec1"> <div class="bg bg-parallax run-par2" style="background-image: url(images/paraplan.jpg) "></div> <div class="overlay over-op6"></div> <!-- --> <div class="content" id="vueHeader"> <habr-header :site-header="siteHeader" :site-sub-header="siteSubHeader"></habr-header> </div> </section> <!-- section end --> <div id="contentPage"> ........ </div> <div id="vueFooter"> ........ </div> </div> </div> </div> </body>
That's basically it!
Source code can be found HERE .
Just carefully follow the paths to the json-files, they may differ from you.
Source: https://habr.com/ru/post/349532/
All Articles