← back to kpackk__curtains-world

Function bodies 36 total

All specs Real LLM only Function bodies
t843_setHeight function · javascript · L6-L8 (3 LOC)
assets/js/tilda-blocks-page61146805.min.js
function t843_setHeight(recId){var rec=document.querySelector('#rec'+recId);if(!rec)return;var container=rec.querySelector('.t843');if(!container)return;var blockImages=rec.querySelectorAll('.t843__blockimg');var isLoaded=!0;for(var i=0;i<blockImages.length;i++){var blockImage=blockImages[i];var width=blockImage.getAttribute('data-image-width');var height=blockImage.getAttribute('data-image-height');var ratio=height/width;var padding=ratio*100;blockImage.style.paddingBottom=padding+'%';if(!blockImage.classList.contains('loaded')){isLoaded=!1}}
if(window.innerWidth>960){var textWraps=rec.querySelectorAll('.t843__textwrapper');var deskImages=rec.querySelectorAll('.t843__desktopimg');for(var i=0;i<textWraps.length;i++){textWraps[i].style.height=deskImages[i].clientHeight+'px'}}
if(!isLoaded){if(window.lazy==='y'||document.getElementById('allrecords').getAttribute('data-tilda-lazy')==='yes'){t_onFuncLoad('t_lazyload_update',function(){t_lazyload_update()})}}}
t778__showMore function · javascript · L12-L16 (5 LOC)
assets/js/tilda-blocks-page61146805.min.js
function t778__showMore(recid){var rec=document.querySelector('#rec'+recid+' .t778');if(!rec)return;var cardsShowLimit=parseInt(rec.getAttribute('data-show-count'),10);if(isNaN(cardsShowLimit)||cardsShowLimit<=0)return;var showMoreButton=rec.querySelector('.t778__showmore');if(!showMoreButton)return;const showMoreTextContainer=showMoreButton.querySelector('.js-btn-txt');if(showMoreTextContainer){showMoreTextContainer.textContent=t778__dict()}
showMoreButton.style.removeProperty('display');var allProductCards=rec.querySelectorAll('.t778__col');Array.prototype.forEach.call(allProductCards,function(productCard){productCard.style.display='none'});var cardsNumber=allProductCards.length;t778__showSeparator(rec,cardsShowLimit);for(var i=0;i<cardsShowLimit;i++){if(allProductCards[i]){allProductCards[i].style.display='inline-block'}}
showMoreButton.addEventListener('click',function(){var currentColumns=rec.querySelectorAll('.t778__col');var currentColumnsShowed=0;Array.prototype.forEach.call(cu
t778_initPopup function · javascript · L23-L31 (9 LOC)
assets/js/tilda-blocks-page61146805.min.js
function t778_initPopup(recid){var rec=document.getElementById('rec'+recid);if(!rec)return;var allPopupLinks=rec.querySelectorAll('[href^="#prodpopup"]');if(!allPopupLinks.length)return;var popup=rec.querySelector('.t-popup');popup.addEventListener('mousedown',function(event){var windowWidth=window.innerWidth;var maxScrollBarWidth=17;var windowWithoutScrollBar=windowWidth-maxScrollBarWidth;if(event.clientX>windowWithoutScrollBar){return}
if(event.target===this){t778_closePopup(document.body,popup)}});Array.prototype.forEach.call(allPopupLinks,function(popupLink){var product=popupLink.closest('.js-product');var productLid=product.getAttribute('data-product-lid');var productLinks=document.querySelectorAll('.r a[href$="#!/tproduct/'+recid+'-'+productLid+'"]');Array.prototype.forEach.call(productLinks,function(productLink){productLink.addEventListener('click',function(){if(rec.querySelector('[data-product-lid="'+productLid+'"]')){var linkToPopup=product.querySelector('[href^="#prodpopup"]'
t778_fixedPopupButton function · javascript · L38-L43 (6 LOC)
assets/js/tilda-blocks-page61146805.min.js
function t778_fixedPopupButton(recId){var rec=document.getElementById('rec'+recId);if(!rec)return;var MOBILE_MAX_WIDTH=560;var popup=rec.querySelector('.t-popup');var popupContainer=popup.querySelector('.t-popup__container');var btnWrappers=rec.querySelectorAll('.t778__btn-wrapper');Array.prototype.forEach.call(btnWrappers,function(el){el.classList.add('t778__btn-wrapper-fixed')});function addStyle(){popupContainer.style.paddingBottom='90px';popupContainer.style.cssText+=';transform:none !important;'}
function resetStyle(){popupContainer.style.paddingBottom='';popupContainer.style.transform=''}
function handleResize(){if(window.innerWidth>MOBILE_MAX_WIDTH){resetStyle();return}
addStyle()}
if(window.isMobile){window.addEventListener('orientationchange',handleResize)}
popup.addEventListener(t778_POPUP_SHOWED_EVENT_NAME,function(){setTimeout(function(){handleResize()})});popup.addEventListener(t778_POPUP_CLOSED_EVENT_NAME,function(){resetStyle()});window.addEventListener('resize',handleRe
t270_smoothScrollTo function · javascript · L54-L56 (3 LOC)
assets/js/tilda-blocks-page61146805.min.js
function t270_smoothScrollTo(targetY,duration=500){var body=document.body;var startY=window.scrollY||window.pageYOffset;var deltaY=targetY-startY;var startTime=performance.now();function easeInOutQuad(t){return Math.pow(t,2)}
function scroll(){var currentTime=performance.now();var elapsedTime=Math.min((currentTime-startTime)/duration,1);var ease=easeInOutQuad(elapsedTime);window.scrollTo(0,startY+deltaY*ease);if(elapsedTime<1){requestAnimationFrame(scroll)}else{body.removeAttribute('data-scroll');body.removeAttribute('data-scrollable');window.scrollTo(0,targetY)}}
body.setAttribute('data-scroll','true');body.setAttribute('data-scrollable','true');requestAnimationFrame(scroll)}
t270_getTarget function · javascript · L57-L59 (3 LOC)
assets/js/tilda-blocks-page61146805.min.js
function t270_getTarget(hash,offset){var target;try{if(hash.substring(0,1)==='#'){target=document.getElementById(hash.substring(1))}else{target=document.querySelector(hash)}}catch(event){console.log('Exception t270: '+event.message);return}
if(!target){target=document.querySelector('a[name="'+hash.substr(1)+'"], div[id="'+hash.substr(1)+'"]');if(!target)return}
target=parseInt(target.getBoundingClientRect().top+window.pageYOffset-offset,10);target=Math.max(target,0);return target}
t228__init function · javascript · L60-L64 (5 LOC)
assets/js/tilda-blocks-page61146805.min.js
function t228__init(recid){var rec=document.getElementById('rec'+recid);if(!rec)return;var menuBlock=rec.querySelector('.t228');var mobileMenu=rec.querySelector('.t228__mobile');var menuSubLinkItems=rec.querySelectorAll('.t-menusub__link-item');var rightBtn=rec.querySelector('.t228__right_buttons_but .t-btn');var mobileMenuPosition=mobileMenu?mobileMenu.style.position||window.getComputedStyle(mobileMenu).position:'';var mobileMenuDisplay=mobileMenu?mobileMenu.style.display||window.getComputedStyle(mobileMenu).display:'';var isFixedMobileMenu=mobileMenuPosition==='fixed'&&mobileMenuDisplay==='block';var overflowEvent=document.createEvent('Event');var noOverflowEvent=document.createEvent('Event');overflowEvent.initEvent('t228_overflow',!0,!0);noOverflowEvent.initEvent('t228_nooverflow',!0,!0);if(menuBlock){menuBlock.addEventListener('t228_overflow',function(){t228_checkOverflow(recid)});menuBlock.addEventListener('t228_nooverflow',function(){t228_checkNoOverflow(recid)})}
rec.addEventLis
Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
t228_setWidth function · javascript · L67-L69 (3 LOC)
assets/js/tilda-blocks-page61146805.min.js
function t228_setWidth(recid){var rec=document.getElementById('rec'+recid);if(!rec)return;var menuCenterSideList=rec.querySelectorAll('.t228__centerside');Array.prototype.forEach.call(menuCenterSideList,function(menuCenterSide){menuCenterSide.classList.remove('t228__centerside_hidden')});if(window.innerWidth<=980)return;var menuBlocks=rec.querySelectorAll('.t228');Array.prototype.forEach.call(menuBlocks,function(menu){var maxWidth;var centerWidth=0;var paddingWidth=40;var leftSide=menu.querySelector('.t228__leftside');var rightSide=menu.querySelector('.t228__rightside');var menuList=menu.querySelector('.t228__list');var mainContainer=menu.querySelector('.t228__maincontainer');var leftContainer=menu.querySelector('.t228__leftcontainer');var rightContainer=menu.querySelector('.t228__rightcontainer');var centerContainer=menu.querySelector('.t228__centercontainer');var centerContainerLi=centerContainer?centerContainer.querySelectorAll('li'):[];var leftContainerWidth=t228_getFullWidth(leftC
t843_setHeight function · javascript · L6-L8 (3 LOC)
assets/tilda-blocks-page61146805.min.js
function t843_setHeight(recId){var rec=document.querySelector('#rec'+recId);if(!rec)return;var container=rec.querySelector('.t843');if(!container)return;var blockImages=rec.querySelectorAll('.t843__blockimg');var isLoaded=!0;for(var i=0;i<blockImages.length;i++){var blockImage=blockImages[i];var width=blockImage.getAttribute('data-image-width');var height=blockImage.getAttribute('data-image-height');var ratio=height/width;var padding=ratio*100;blockImage.style.paddingBottom=padding+'%';if(!blockImage.classList.contains('loaded')){isLoaded=!1}}
if(window.innerWidth>960){var textWraps=rec.querySelectorAll('.t843__textwrapper');var deskImages=rec.querySelectorAll('.t843__desktopimg');for(var i=0;i<textWraps.length;i++){textWraps[i].style.height=deskImages[i].clientHeight+'px'}}
if(!isLoaded){if(window.lazy==='y'||document.getElementById('allrecords').getAttribute('data-tilda-lazy')==='yes'){t_onFuncLoad('t_lazyload_update',function(){t_lazyload_update()})}}}
t778__showMore function · javascript · L12-L16 (5 LOC)
assets/tilda-blocks-page61146805.min.js
function t778__showMore(recid){var rec=document.querySelector('#rec'+recid+' .t778');if(!rec)return;var cardsShowLimit=parseInt(rec.getAttribute('data-show-count'),10);if(isNaN(cardsShowLimit)||cardsShowLimit<=0)return;var showMoreButton=rec.querySelector('.t778__showmore');if(!showMoreButton)return;const showMoreTextContainer=showMoreButton.querySelector('.js-btn-txt');if(showMoreTextContainer){showMoreTextContainer.textContent=t778__dict()}
showMoreButton.style.removeProperty('display');var allProductCards=rec.querySelectorAll('.t778__col');Array.prototype.forEach.call(allProductCards,function(productCard){productCard.style.display='none'});var cardsNumber=allProductCards.length;t778__showSeparator(rec,cardsShowLimit);for(var i=0;i<cardsShowLimit;i++){if(allProductCards[i]){allProductCards[i].style.display='inline-block'}}
showMoreButton.addEventListener('click',function(){var currentColumns=rec.querySelectorAll('.t778__col');var currentColumnsShowed=0;Array.prototype.forEach.call(cu
t778_initPopup function · javascript · L23-L31 (9 LOC)
assets/tilda-blocks-page61146805.min.js
function t778_initPopup(recid){var rec=document.getElementById('rec'+recid);if(!rec)return;var allPopupLinks=rec.querySelectorAll('[href^="#prodpopup"]');if(!allPopupLinks.length)return;var popup=rec.querySelector('.t-popup');popup.addEventListener('mousedown',function(event){var windowWidth=window.innerWidth;var maxScrollBarWidth=17;var windowWithoutScrollBar=windowWidth-maxScrollBarWidth;if(event.clientX>windowWithoutScrollBar){return}
if(event.target===this){t778_closePopup(document.body,popup)}});Array.prototype.forEach.call(allPopupLinks,function(popupLink){var product=popupLink.closest('.js-product');var productLid=product.getAttribute('data-product-lid');var productLinks=document.querySelectorAll('.r a[href$="#!/tproduct/'+recid+'-'+productLid+'"]');Array.prototype.forEach.call(productLinks,function(productLink){productLink.addEventListener('click',function(){if(rec.querySelector('[data-product-lid="'+productLid+'"]')){var linkToPopup=product.querySelector('[href^="#prodpopup"]'
t778_checkUrl function · javascript · L32-L35 (4 LOC)
assets/tilda-blocks-page61146805.min.js
function t778_checkUrl(recid){if(window.catalogUrlProcessed)return;var currentUrl=window.location.href;var tprodIndex=(currentUrl.indexOf('#!/tproduct/')+1||currentUrl.indexOf('%23!/tproduct/')+1||currentUrl.indexOf('#%21%2Ftproduct%2F')+1||currentUrl.indexOf('#!%2Ftproduct%2F')+1||currentUrl.indexOf('%23%21%2Ftproduct%2F')+1)-1;if(tprodIndex!==-1){var currentUrl=currentUrl.substring(tprodIndex,currentUrl.length);var curProdLid=currentUrl.substring(currentUrl.indexOf('-')+1,currentUrl.length);if(curProdLid){var curProdLidMatch=curProdLid.match(/([0-9]+)/g);if(curProdLidMatch){curProdLid=curProdLidMatch[0]}}
if(currentUrl.indexOf(recid)===-1)return;var rec=document.getElementById('rec'+recid);if(!rec)return;if(currentUrl.indexOf(recid)!==0&&rec.querySelector('[data-product-lid="'+curProdLid+'"]')){var currentLink=rec.querySelector('[data-product-lid="'+curProdLid+'"] [href^="#prodpopup"]');var event=document.createEvent('HTMLEvents');event.initEvent('click',!0,!1);if(currentLink){curren
t778_fixedPopupButton function · javascript · L40-L45 (6 LOC)
assets/tilda-blocks-page61146805.min.js
function t778_fixedPopupButton(recId){var rec=document.getElementById('rec'+recId);if(!rec)return;var MOBILE_MAX_WIDTH=560;var popup=rec.querySelector('.t-popup');var popupContainer=popup.querySelector('.t-popup__container');var btnWrappers=rec.querySelectorAll('.t778__btn-wrapper');Array.prototype.forEach.call(btnWrappers,function(el){el.classList.add('t778__btn-wrapper-fixed')});function addStyle(){popupContainer.style.paddingBottom='90px';popupContainer.style.cssText+=';transform:none !important;'}
function resetStyle(){popupContainer.style.paddingBottom='';popupContainer.style.transform=''}
function handleResize(){if(window.innerWidth>MOBILE_MAX_WIDTH){resetStyle();return}
addStyle()}
if(window.isMobile){window.addEventListener('orientationchange',handleResize)}
popup.addEventListener(t778_POPUP_SHOWED_EVENT_NAME,function(){setTimeout(function(){handleResize()})});popup.addEventListener(t778_POPUP_CLOSED_EVENT_NAME,function(){resetStyle()});window.addEventListener('resize',handleRe
t270_smoothScrollTo function · javascript · L56-L58 (3 LOC)
assets/tilda-blocks-page61146805.min.js
function t270_smoothScrollTo(targetY,duration=500){var body=document.body;var startY=window.scrollY||window.pageYOffset;var deltaY=targetY-startY;var startTime=performance.now();function easeInOutQuad(t){return Math.pow(t,2)}
function scroll(){var currentTime=performance.now();var elapsedTime=Math.min((currentTime-startTime)/duration,1);var ease=easeInOutQuad(elapsedTime);window.scrollTo(0,startY+deltaY*ease);if(elapsedTime<1){requestAnimationFrame(scroll)}else{body.removeAttribute('data-scroll');body.removeAttribute('data-scrollable');window.scrollTo(0,targetY)}}
body.setAttribute('data-scroll','true');body.setAttribute('data-scrollable','true');requestAnimationFrame(scroll)}
t270_getTarget function · javascript · L59-L61 (3 LOC)
assets/tilda-blocks-page61146805.min.js
function t270_getTarget(hash,offset){var target;try{if(hash.substring(0,1)==='#'){target=document.getElementById(hash.substring(1))}else{target=document.querySelector(hash)}}catch(event){console.log('Exception t270: '+event.message);return}
if(!target){target=document.querySelector('a[name="'+hash.substr(1)+'"], div[id="'+hash.substr(1)+'"]');if(!target)return}
target=parseInt(target.getBoundingClientRect().top+window.pageYOffset-offset,10);target=Math.max(target,0);return target}
Repobility — the code-quality scanner for AI-generated software · https://repobility.com
t228__init function · javascript · L62-L66 (5 LOC)
assets/tilda-blocks-page61146805.min.js
function t228__init(recid){var rec=document.getElementById('rec'+recid);if(!rec)return;var menuBlock=rec.querySelector('.t228');var mobileMenu=rec.querySelector('.t228__mobile');var menuSubLinkItems=rec.querySelectorAll('.t-menusub__link-item');var rightBtn=rec.querySelector('.t228__right_buttons_but .t-btn');var mobileMenuPosition=mobileMenu?mobileMenu.style.position||window.getComputedStyle(mobileMenu).position:'';var mobileMenuDisplay=mobileMenu?mobileMenu.style.display||window.getComputedStyle(mobileMenu).display:'';var isFixedMobileMenu=mobileMenuPosition==='fixed'&&mobileMenuDisplay==='block';var overflowEvent=document.createEvent('Event');var noOverflowEvent=document.createEvent('Event');overflowEvent.initEvent('t228_overflow',!0,!0);noOverflowEvent.initEvent('t228_nooverflow',!0,!0);if(menuBlock){menuBlock.addEventListener('t228_overflow',function(){t228_checkOverflow(recid)});menuBlock.addEventListener('t228_nooverflow',function(){t228_checkNoOverflow(recid)})}
rec.addEventLis
t228_setWidth function · javascript · L69-L71 (3 LOC)
assets/tilda-blocks-page61146805.min.js
function t228_setWidth(recid){var rec=document.getElementById('rec'+recid);if(!rec)return;var menuCenterSideList=rec.querySelectorAll('.t228__centerside');Array.prototype.forEach.call(menuCenterSideList,function(menuCenterSide){menuCenterSide.classList.remove('t228__centerside_hidden')});if(window.innerWidth<=980)return;var menuBlocks=rec.querySelectorAll('.t228');Array.prototype.forEach.call(menuBlocks,function(menu){var maxWidth;var centerWidth=0;var paddingWidth=40;var leftSide=menu.querySelector('.t228__leftside');var rightSide=menu.querySelector('.t228__rightside');var menuList=menu.querySelector('.t228__list');var mainContainer=menu.querySelector('.t228__maincontainer');var leftContainer=menu.querySelector('.t228__leftcontainer');var rightContainer=menu.querySelector('.t228__rightcontainer');var centerContainer=menu.querySelector('.t228__centercontainer');var centerContainerLi=centerContainer?centerContainer.querySelectorAll('li'):[];var leftContainerWidth=t228_getFullWidth(leftC
get_filename function · python · L11-L31 (21 LOC)
clone_page.py
def get_filename(url, content_type=None):
    parsed = urlparse(url)
    path = parsed.path
    filename = os.path.basename(path)
    
    if not filename or filename == 'css2': 
        # Handle cases like /css2 or empty filename
        if 'css2' in path:
            return "fonts.css"
        return "resource" 

    if '?' in filename:
        filename = filename.split('?')[0]
    
    # Add extension if missing and we know the content type
    if not os.path.splitext(filename)[1] and content_type:
        ext = mimetypes.guess_extension(content_type)
        if ext:
            filename += ext
    
    return filename
download_file function · python · L33-L43 (11 LOC)
clone_page.py
def download_file(url, local_path):
    try:
        response = requests.get(url, stream=True)
        response.raise_for_status()
        with open(local_path, 'wb') as f:
            for chunk in response.iter_content(chunk_size=8192):
                f.write(chunk)
        return True
    except Exception as e:
        print(f"Failed to download {url}: {e}")
        return False
main function · python · L45-L114 (70 LOC)
clone_page.py
def main():
    if not os.path.exists(ASSETS_DIR):
        os.makedirs(ASSETS_DIR)

    print(f"Fetching {BASE_URL}...")
    try:
        response = requests.get(BASE_URL)
        response.raise_for_status()
    except Exception as e:
        print(f"Failed to fetch page: {e}")
        return

    soup = BeautifulSoup(response.content, 'html.parser')

    # Helper to process attributes
    def process_attribute(tag, attr):
        if not tag.has_attr(attr): return
        url = tag[attr]
        if not url: return

        full_url = urljoin(BASE_URL, url)
        
        # skip data URIs
        if full_url.startswith('data:'): return

        filename = get_filename(full_url)
        local_path = os.path.join(ASSETS_DIR, filename)
        
        # Download if not exists (or specific files)
        if not os.path.exists(local_path) or filename == "fonts.css":
            print(f"Downloading {filename} from {full_url}...")
            download_file(full_url, local_path)
        
   
build_nav_links_html function · python · L1616-L1624 (9 LOC)
generate_pages.py
def build_nav_links_html(current_slug):
    """Build the list of navigation links, excluding the current page."""
    links = ['<li><a href="home.html">Главная</a></li>']
    for slug, label in ALL_LANDING_PAGES:
        if slug == current_slug:
            links.append(f'<li><a href="{slug}.html" aria-current="page"><strong>{escape(label)}</strong></a></li>')
        else:
            links.append(f'<li><a href="{slug}.html">{escape(label)}</a></li>')
    return "\n              ".join(links)
build_faq_html function · python · L1627-L1637 (11 LOC)
generate_pages.py
def build_faq_html(faq_items):
    """Build the FAQ section HTML."""
    items_html = []
    for item in faq_items:
        items_html.append(f"""          <details class="lp-faq__item">
            <summary class="lp-faq__question">{escape(item["q"])}</summary>
            <div class="lp-faq__answer">
              <p>{escape(item["a"])}</p>
            </div>
          </details>""")
    return "\n".join(items_html)
build_faq_schema function · python · L1640-L1657 (18 LOC)
generate_pages.py
def build_faq_schema(faq_items):
    """Build the FAQPage JSON-LD schema."""
    entities = []
    for item in faq_items:
        entities.append({
            "@type": "Question",
            "name": item["q"],
            "acceptedAnswer": {
                "@type": "Answer",
                "text": item["a"],
            },
        })
    schema = {
        "@context": "https://schema.org",
        "@type": "FAQPage",
        "mainEntity": entities,
    }
    return json.dumps(schema, ensure_ascii=False, indent=2)
Hi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
build_breadcrumb_schema function · python · L1660-L1680 (21 LOC)
generate_pages.py
def build_breadcrumb_schema(page):
    """Build the BreadcrumbList JSON-LD schema."""
    schema = {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": [
            {
                "@type": "ListItem",
                "position": 1,
                "name": "Главная",
                "item": f"{BASE_URL}/",
            },
            {
                "@type": "ListItem",
                "position": 2,
                "name": page["breadcrumb_name"],
                "item": f"{BASE_URL}/{page['slug']}",
            },
        ],
    }
    return json.dumps(schema, ensure_ascii=False, indent=2)
build_content_html function · python · L1683-L1687 (5 LOC)
generate_pages.py
def build_content_html(paragraphs):
    """Build the content paragraphs HTML."""
    return "\n".join(
        f"          <p>{escape(p)}</p>" for p in paragraphs
    )
build_cross_links function · python · L1690-L1698 (9 LOC)
generate_pages.py
def build_cross_links(current_slug):
    """Build the cross-links section for related pages."""
    links = []
    for slug, label in ALL_LANDING_PAGES:
        if slug != current_slug:
            links.append(
                f'          <li><a href="{slug}.html">{escape(label)}</a></li>'
            )
    return "\n".join(links)
build_blog_content_html function · python · L1701-L1709 (9 LOC)
generate_pages.py
def build_blog_content_html(sections):
    """Build the article content HTML from sections with h2/h3 headings."""
    parts = []
    for section in sections:
        tag = f"h{section['level']}"
        parts.append(f"    <{tag}>{escape(section['heading'])}</{tag}>")
        for p in section["paragraphs"]:
            parts.append(f"    <p>{escape(p)}</p>")
    return "\n".join(parts)
build_article_schema function · python · L1712-L1736 (25 LOC)
generate_pages.py
def build_article_schema(article):
    """Build the Article JSON-LD schema."""
    schema = {
        "@context": "https://schema.org",
        "@type": "Article",
        "headline": article["h1"],
        "description": article["description"],
        "author": {
            "@type": "Organization",
            "name": "Curtains World",
            "url": BASE_URL,
        },
        "publisher": {
            "@type": "Organization",
            "name": "Curtains World",
            "url": BASE_URL,
        },
        "datePublished": article["date_published"],
        "image": f"{BASE_URL}/assets/img_2024-02-07_14131410.webp",
        "mainEntityOfPage": {
            "@type": "WebPage",
            "@id": f"{BASE_URL}/{article['slug']}",
        },
    }
    return json.dumps(schema, ensure_ascii=False, indent=2)
build_blog_breadcrumb_schema function · python · L1739-L1765 (27 LOC)
generate_pages.py
def build_blog_breadcrumb_schema(article):
    """Build the BreadcrumbList JSON-LD schema for blog articles (3 levels)."""
    schema = {
        "@context": "https://schema.org",
        "@type": "BreadcrumbList",
        "itemListElement": [
            {
                "@type": "ListItem",
                "position": 1,
                "name": "Главная",
                "item": f"{BASE_URL}/",
            },
            {
                "@type": "ListItem",
                "position": 2,
                "name": "Блог",
                "item": f"{BASE_URL}/blog",
            },
            {
                "@type": "ListItem",
                "position": 3,
                "name": article["breadcrumb_name"],
                "item": f"{BASE_URL}/{article['slug']}",
            },
        ],
    }
    return json.dumps(schema, ensure_ascii=False, indent=2)
build_blog_cross_links function · python · L1768-L1776 (9 LOC)
generate_pages.py
def build_blog_cross_links(current_slug):
    """Build the cross-links section for related blog articles."""
    links = []
    for slug, label in ALL_BLOG_ARTICLES:
        if slug != current_slug:
            links.append(
                f'          <li><a href="{slug}.html">{escape(label)}</a></li>'
            )
    return "\n".join(links)
build_related_blog_links function · python · L1779-L1789 (11 LOC)
generate_pages.py
def build_related_blog_links(product_slug):
    """Build links to related blog articles for a product page."""
    articles = PRODUCT_BLOG_RELATED.get(product_slug, [])
    if not articles:
        return ""
    links = []
    for slug, label in articles:
        links.append(
            f'          <li><a href="{slug}.html">{escape(label)}</a></li>'
        )
    return "\n".join(links)
Powered by Repobility — scan your code at https://repobility.com
build_related_product_links function · python · L1792-L1802 (11 LOC)
generate_pages.py
def build_related_product_links(blog_slug):
    """Build links to related product pages for a blog article."""
    products = BLOG_PRODUCT_RELATED.get(blog_slug, [])
    if not products:
        return ""
    links = []
    for slug, label in products:
        links.append(
            f'          <li><a href="{slug}.html">{escape(label)}</a></li>'
        )
    return "\n".join(links)
build_footer_html function · python · L1805-L1845 (41 LOC)
generate_pages.py
def build_footer_html():
    """Build the shared footer HTML used by both product and blog pages."""
    blog_links = "\n".join(
        f'          <li><a href="{slug}.html">{escape(label)}</a></li>'
        for slug, label in ALL_BLOG_ARTICLES
    )
    return f"""  <!-- Footer -->
  <footer class="lp-footer">
    <div class="lp-footer__inner">
      <div class="lp-footer__col">
        <h3>Curtains World</h3>
        <p>Шторы и занавески на заказ<br>в Дубае из натуральных тканей</p>
      </div>
      <div class="lp-footer__col">
        <h3>Контакты</h3>
        <p>
          <a href="{PHONE_LINK}">{PHONE}</a><br>
          <a href="mailto:{EMAIL}">{EMAIL}</a><br>
          Warehouse 174 Jaddaf, Dubai
        </p>
      </div>
      <div class="lp-footer__col">
        <h3>Каталог</h3>
        <ul>
          <li><a href="home.html">Главная</a></li>
          <li><a href="blackout-shtory-dubai.html">Блэкаут шторы</a></li>
          <li><a href="tyul-na-zakaz-dubai.html">Тюль на зака
main function · python · L3251-L3276 (26 LOC)
generate_pages.py
def main():
    script_dir = os.path.dirname(os.path.abspath(__file__))

    for page in PAGES:
        html = generate_page(page)
        filepath = os.path.join(script_dir, page["filename"])
        with open(filepath, "w", encoding="utf-8") as f:
            f.write(html)
        print(f"Generated: {page['filename']}")

    for article in BLOG_ARTICLES:
        html = generate_blog_article(article)
        filepath = os.path.join(script_dir, article["filename"])
        with open(filepath, "w", encoding="utf-8") as f:
            f.write(html)
        print(f"Generated: {article['filename']}")

    # Blog index page
    blog_html = generate_blog_index()
    blog_filepath = os.path.join(script_dir, "blog.html")
    with open(blog_filepath, "w", encoding="utf-8") as f:
        f.write(blog_html)
    print("Generated: blog.html")

    total = len(PAGES) + len(BLOG_ARTICLES) + 1
    print(f"\nDone! Generated {len(PAGES)} landing pages + {len(BLOG_ARTICLES)} blog articles + 1 blog index 
get_image_files function · python · L8-L15 (8 LOC)
optimize_images.py
def get_image_files(directory):
    """Find all PNG and JPG files recursively."""
    images = []
    for root, dirs, files in os.walk(directory):
        for f in files:
            if f.lower().endswith(('.png', '.jpg', '.jpeg')) and not f.startswith('.'):
                images.append(os.path.join(root, f))
    return images
convert_to_webp function · python · L17-L43 (27 LOC)
optimize_images.py
def convert_to_webp(filepath, quality=QUALITY):
    """Convert image to WebP using Pillow."""
    webp_path = os.path.splitext(filepath)[0] + '.webp'
    if os.path.exists(webp_path):
        print(f"  SKIP {os.path.basename(filepath)} (WebP already exists)")
        return 0

    try:
        from PIL import Image
        img = Image.open(filepath)
        if img.mode in ('RGBA', 'LA', 'P'):
            img = img.convert('RGBA')
        else:
            img = img.convert('RGB')
        img.save(webp_path, 'WebP', quality=quality)
        original_size = os.path.getsize(filepath)
        webp_size = os.path.getsize(webp_path)
        savings = original_size - webp_size
        pct = (savings / original_size) * 100 if original_size > 0 else 0
        print(f"  {os.path.basename(filepath)}: {original_size//1024}KB -> {webp_size//1024}KB ({pct:.0f}% saved)")
        return savings
    except ImportError:
        print("ERROR: Pillow not installed. Run: pip3 install Pillow")
        sys.e