Hugo를 위한 부동산업자 테마 개발: 1단계 페이지 구축

43523 단어 htmlcssjavascript

소개



우리 도시의 많은 부동산업자들이 여전히 워드프레스를 사용하고 있고 그들을 위한 대안을 만들고 싶었기 때문에 나는 우리 도시의 부동산업자들을 위한 테마를 개발하기로 결정했습니다.

계획



게임 계획은 다음과 같습니다.
  • 작동할 SSG 찾기
  • HTML, SASS 및 JS에서 먼저 페이지를 구축합니다
  • .
  • 템플릿 구축
  • 테마 및 SSG와 함께 작동할 CMS 찾기

  • 이 기사에서는 SSG와 페이지를 다룰 것입니다.

    SSG



    정적 사이트 생성기의 경우 Hugo를 사용하기로 결정했습니다. 사용이 간편하고 템플릿 엔진이 굉장합니다! 문서를 읽은 후 필요한 것과 함께 작동한다고 생각합니다.

    페이지 구축



    따라서 필요한 기본 페이지는 다음과 같습니다.
  • 리스팅
  • 목록
  • 직원 페이지
  • 문의하기

  • 홈페이지



    목록



    목록 페이지의 경우 필터링 가능한 갤러리를 설정해야 합니다.

    갤러리



    나는 이 스타일의 갤러리와 함께 가기로 결정했다. 나는 그것이 멋져 보인다고 생각한다. 필터링을 추가하려면 다음으로



    필터




    // File#: _3_advanced-filter
    // Usage: codyhouse.co/license
    (function() {
      // the AdvFilter object is used to handle: 
      // - number of results
      // - form reset
      // - filtering sections label (to show a preview of the option selected by the users)
      var AdvFilter = function(element) {
        this.element = element; 
        this.form = this.element.getElementsByClassName('js-adv-filter__form');
        this.resultsList = this.element.getElementsByClassName('js-adv-filter__gallery')[0];
        this.resultsCount = this.element.getElementsByClassName('js-adv-filter__results-count');
        initAdvFilter(this);
      };
    
      function initAdvFilter(filter) {
        if(filter.form.length > 0) {
          // reset form
          filter.form[0].addEventListener('reset', function(event){
            setTimeout(function(){
              resetFilters(filter);
              resetGallery(filter);
            });
          });
          // update section labels on form change
          filter.form[0].addEventListener('change', function(event){
            var section = event.target.closest('.js-adv-filter__item');
            if(section) resetSelection(filter, section);
            else if( Util.is(event.target, '.js-adv-filter__form') ) {
              // reset the entire form lables
              var sections = filter.form[0].getElementsByClassName('js-adv-filter__item');
              for(var i = 0; i < sections.length; i++) resetSelection(filter, sections[i]);
            }
          });
        }
    
        // reset results count
        if(filter.resultsCount.length > 0) {
          filter.resultsList.addEventListener('filter-selection-updated', function(event){
            updateResultsCount(filter);
          });
        }
      };
    
      function resetFilters(filter) {
        // check if there are custom form elemets - reset appearance
        // custom select
        var customSelect = filter.element.getElementsByClassName('js-select');
        if(customSelect.length > 0) {
          for(var i = 0; i < customSelect.length; i++) customSelect[i].dispatchEvent(new CustomEvent('select-updated'));
        }
        // custom slider
        var customSlider = filter.element.getElementsByClassName('js-slider');
        if(customSlider.length > 0) {
          for(var i = 0; i < customSlider.length; i++) customSlider[i].dispatchEvent(new CustomEvent('slider-updated'));
        }
      };
    
      function resetSelection(filter, section) {
        // change label value based on input types
        var labelSelection = section.getElementsByClassName('js-adv-filter__selection');
        if(labelSelection.length == 0) return;
        // select
        var select = section.getElementsByTagName('select');
        if(select.length > 0) {
          labelSelection[0].textContent = getSelectLabel(section, select[0]);
          return;
        }
        // input number
        var number = section.querySelectorAll('input[type="number"]');
        if(number.length > 0) {
          labelSelection[0].textContent = getNumberLabel(section, number);
          return;
        }
        // input range
        var slider = section.querySelectorAll('input[type="range"]');
        if(slider.length > 0) {
          labelSelection[0].textContent = getSliderLabel(section, slider);
          return;
        }
        // radio/checkboxes
        var radio = section.querySelectorAll('input[type="radio"]'),
          checkbox = section.querySelectorAll('input[type="checkbox"]');
        if(radio.length > 0) {
          labelSelection[0].textContent = getInputListLabel(section, radio);
          return;
        } else if(checkbox.length > 0) {
          labelSelection[0].textContent = getInputListLabel(section, checkbox);
          return;
        }
      };
    
      function getSelectLabel(section, select) {
        if(select.multiple) {
          var label = '',
            counter = 0;
          for (var i = 0; i < select.options.length; i++) {
            if(select.options[i].selected) {
              label = label + '' + select.options[i].text;
              counter = counter + 1;
            } 
            if(counter > 1) label = section.getAttribute('data-multi-select-text').replace('{n}', counter);
          }
          return label;
        } else {
          return select.options[select.selectedIndex].text;
        }
      };
    
      function getNumberLabel(section, number) {
        var counter = 0;
        for(var i = 0; i < number.length; i++) {
          if(number[i].value != number[i].min) counter = counter + 1;
        }
        if(number.length > 1) { // multiple input number in this section
          if(counter > 0) {
            return section.getAttribute('data-multi-select-text').replace('{n}', counter);
          } else {
            return section.getAttribute('data-default-text');
          }
    
        } else {
          if(number[0].value == number[0].min) return section.getAttribute('data-default-text');
          else return section.getAttribute('data-number-format').replace('{n}', number[0].value);
        }
      };
    
      function getSliderLabel(section, slider) {
        var label = '',
          labelFormat = section.getAttribute('data-number-format');
        for(var i = 0; i < slider.length; i++) {
          if(i != 0 ) label = label+' - ';
          label = label + labelFormat.replace('{n}', slider[i].value);
        }
        return label;
      };
    
      function getInputListLabel(section, inputs) {
        var counter = 0;
          label = '';
        for(var i = 0; i < inputs.length; i++) {
          if(inputs[i].checked) {
            var labelElement = inputs[i].parentNode.getElementsByTagName('label');
            if(labelElement.length > 0) label = labelElement[0].textContent;
            counter = counter + 1;
          }
        }
        if(counter > 1) return section.getAttribute('data-multi-select-text').replace('{n}', counter);
        else if(counter == 0 ) return section.getAttribute('data-default-text');
        else return label;
      };
    
      function resetGallery(filter) {
        // emit change event + reset filtering 
        filter.form[0].dispatchEvent(new CustomEvent('change'));
        filter.resultsList.dispatchEvent(new CustomEvent('update-filter-results'));
      };
    
      function updateResultsCount(filter) {
        var resultItems = filter.resultsList.children,
          counter = 0;
        for(var i = 0; i < resultItems.length; i++) {
          if(isVisible(resultItems[i])) counter = counter + 1;
        }
        filter.resultsCount[0].textContent = counter;
      };
    
      function isVisible(element) {
            return (element.offsetWidth || element.offsetHeight || element.getClientRects().length);
        };
    
      //initialize the AdvFilter objects
        var advFilter = document.getElementsByClassName('js-adv-filter');
        if( advFilter.length > 0 ) {
            for( var i = 0; i < advFilter.length; i++) {
                (function(i){new AdvFilter(advFilter[i]);})(i);
            }
      }
    
      // Remove the code below if you want to use a custom filtering function (e.g., you need to fetch your results from a database)
    
      // The code below is used for filtering of page content (animation of DOM elements, no fetching results from database).  
      // It uses the Filter component (https://codyhouse.co/ds/components/app/filter) - you can modify the custom filtering functions based on your needs
      // Check the info page of the component for info on how to use it: https://codyhouse.co/ds/components/info/filter
      var gallery = document.getElementById('adv-filter-gallery');
      if(gallery) {
        new Filter({
          element: gallery, // this is your gallery element
          priceRange: function(items){ // this is the price custom function
            var filteredArray = [],
              minVal = document.getElementById('slider-min-value').value,
              maxVal = document.getElementById('slider-max-value').value;
            for(var i = 0; i < items.length; i++) {
              var price = parseInt(items[i].getAttribute('data-price'));
              filteredArray[i] = (price >= minVal) && (price <= maxVal);
            } 
            return filteredArray;
          },
          indexValue: function(items){ // this is the index custom function
            var filteredArray = [],
              value = document.getElementById('index-value').value;
            for(var i = 0; i < items.length; i++) {
              var index = parseInt(items[i].getAttribute('data-sort-index'));
              filteredArray[i] = index >= value;
            } 
            return filteredArray;
          }
        });
      }
    }());
    


    목록



    이미지







    목록에 대한 모든 주요 콘텐츠를 호스팅하도록 일부 탭을 설정했습니다. 이것이 모든 것을 분리하고 사용자가 탐색하기 쉽게 만드는 데 도움이 될 것이라고 생각합니다.



    정보



    목록에 들어가는 많은 정보가 있습니다. 그래서 FAQ 섹션에 대한 템플릿을 사용하고 그 안에 있는 모든 정보를 분리했습니다.

    좋은 웹페이지 즐겨찾기