Home > Web Front-end > JS Tutorial > Transforming Starlight into PDF: experience and insights

Transforming Starlight into PDF: experience and insights

Mary-Kate Olsen
Release: 2025-01-15 10:24:42
Original
713 people have browsed it

Imagine you are given a task: create a new documentation website in a week. It should be visually appealing, fast, and easy to navigate. You’re handed a pile of *.docs files, images, and screenshots, with the instruction to "get it done".

There are many excellent tools to choose from, such as Docusaurus, Nextra, VitePress, Docus, and others. Previously, I had a great experience building a documentation website with Starlight, so it was my choice for this task. However, I discovered a missing feature: the ability to generate a PDF from the documentation. And it was one of the requirements. "Sounds like a nice side project," I thought for myself.

Tackling the task

At first, it seemed straightforward: fetch the pages, parse the HTML, group the content, and voila!

Starlight powered websites have a Next button to navigate through the documentation. As PDF essentially is an array of pages, it seemed logical to parse them one by one, using this Next button. Since the website generates static pages, I quickly wrote a script to fetch the HTML, query the necessary parts, and combine everything together. However, generating a PDF that retained the website's styles proved to be more complex. After some brainstorming, I realized Puppeteer was the best solution.

Now the process became clear:

  1. Identify the starting page. This is the first page with a Next button.
  2. Navigate through the pages. Extract the heading and main content from each page and at the same time build a table of contents.
  3. Combine the content. Add page breaks and additional styles.
  4. Prepare the final HTML. Rewrite the of the initial page with the resulting HTML.
  5. Load resources. Scroll the page to the bottom to load all the images.
  6. Generate the PDF. Puppeteer's Page.pdf() method nails it.
  7. Done!

This is how starlight-to-pdf works. Following this pattern, you can build similar tools for other documentation frameworks lacking PDF export functionality.

Next steps

Once the basic functionality was ready, it was time to add some extras. Below are the most interesting and challenging features.

Adding headers and footers

It's nice to have a page number and some additional information in the header or footer. Puppeteer's Page.pdf() method accepts headerTemplate and footerTemplate options. These options accept HTML strings. Puppeteer automatically injects values into the elements that have specific utility classes:

  • .date: formatted date;
  • .title: web page's tag value;</li> <li> .url: page's URL on which printing function was called;</li> <li> .pageNumber: current page number;</li> <li> .totalPages: total number of pages in the document.</li> </ul> <p>As we combine all the content on one page before printing, title and url don't have much value for us: the inserted value will always remain the same. However, other classes help a lot. Here’s an example footer template:<br> </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false"><style> .footer-container { --color: #000; display: flex; align-items: center; justify-content: space-between; border-block-start: 1px solid var(--color); color: var(--color); font-size: 10px; font-family: Arial, Helvetica, sans-serif; margin-inline: 1.5cm 1cm; padding-block: 0.25cm 0.5cm; width: 100%; } </style> <div> <p>To use this, do not forget to set the displayHeaderFooter property to true:<br> </p> <pre class="brush:php;toolbar:false">import puppeteer from 'puppeteer'; const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto('https://someUrl'); const footerTemplateStr = '<style>...<style><div>...</div>' // replace with the HTML string from the example above await page.pdf({ displayHeaderFooter: true, footerTemplate: footerTemplateStr }) </pre><div class="contentsignin">Copy after login</div></div> <p>Here are some findings that you should keep in mind:</p> </pre> <ul> <li>The template must be a valid HTML structure.</li> <li>Define font-size CSS property as Puppeteer's default value is 0.</li> <li>Use inline <style> tag to define your styles. Website styles are not available inside the templates.</li> <li>Images should be encoded as base64 strings.</li> <li>Use Puppeteer's margin option to achieve the desired layout.</li> </ul> <h3> What about CLI styles? </h3> <p>Everything works fine, the resulting PDF looks great, but the terminal messages feel bland. Attention to details separates the good from the great, isn’t it? Let's make our messages more colorful and easier to read.</p> <p>Here comes the magic of ANSI escape sequences. I decided that 4-bit colours would be enough for the job. Let's say you want to have a white text on red background <em>(that's what I used for my [ERROR]: prefix before error messages)</em>. Here is how you can achieve this look:<br> </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">console.log('\x1b[37;41m', 'White on red message'); </pre><div class="contentsignin">Copy after login</div></div> <p>Let's break it down:</p> <ul> <li> x1b[ is a hexadecimal escape code (you may also use u001b as the Unicode alternative);</li> <li> 37 is a foreground white color, where 3 stands for foreground and 7 for the white color;</li> <li> 41 is a background red color, where 4 stands for background and 1 for the red color.</li> </ul> <p>Everything is working, but now all of our console.log() output will be styled in this manner. To reset the style back to default, simply add the reset sequence x1b[0m at the end:<br> </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">console.log('\x1b[37;41m', 'White on red message', '\x1b[0m'); </pre><div class="contentsignin">Copy after login</div></div> <p>Much better. What if we want bold cyan text on a gray background <em>(bright black in the names of 4-bit colors)</em>? It's easy:<br> </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">console.log('\x1b[1;36;100m', 'Cyan on gray message in bold', '\x1b[0m'); </pre><div class="contentsignin">Copy after login</div></div> <p>Here’s what each part does:</p> <ul> <li> 1 after the escape code applies the bold effect;</li> <li> 36 sets the text color to cyan;</li> <li> 100 changes the background to bright black color, where 10 means <em>bright</em> and 0 is a code for <em>black</em>.</li> </ul> <p>Using this knowledge, you can make your CLI tool visually appealing. For example, I styled all URLs and file paths as underlined blue text in my project:<br> </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">console.log('\x1b[4;34m', './underlined/blue', '\x1b[0m') </pre><div class="contentsignin">Copy after login</div></div> <p>Check out this cheatsheet to learn more on the topic.</p> <h2> Wrapping up </h2> <p>You never know when a routine task might inspire a rewarding side project. Development of starlight-to-pdf provided valuable experience with Puppeteer and CLI styling, and a new tool emerged in the open source community. Here’s a quick demonstration:</p> <p><img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/000/000/173690789360353.jpg" class="lazy" alt="Transforming Starlight into PDF: experience and insights"></p> <p>The above is the detailed content of Transforming Starlight into PDF: experience and insights. For more information, please follow other related articles on the PHP Chinese website!</p> </div> </div> <div style="display: flex;"> <!-- <div style="display: inline-flex;float: right; color:#333333;">source:dev.to</div> --> </div> <div class="wzconOtherwz"> <a href="https://www.php.cn/faq/1796753817.html" title="Using LRU Cache in Node.js and TypeScript"> <span>Previous article:Using LRU Cache in Node.js and TypeScript</span> </a> <a href="https://www.php.cn/faq/1796753834.html" title="Don&#t copy/paste code you don&#t understand"> <span>Next article:Don&#t copy/paste code you don&#t understand</span> </a> </div> <div class="wzconShengming"> <div class="bzsmdiv">Statement of this Website</div> <div>The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn</div> </div> <ins class="adsbygoogle" style="display:block" data-ad-format="autorelaxed" data-ad-client="ca-pub-5902227090019525" data-ad-slot="2507867629"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> <div class="wzconZzwz"> <div class="wzconZzwztitle">Latest Articles by Author</div> <ul> </ul> </div> <div class="wzconZzwz"> <div class="wzconZzwztitle">Latest Issues</div> <div class="wdsyContent"> <div class="wdsyConDiv flexRow wdsyConDiv1"> <div class="wdcdContent flexColumn"> <a href="https://www.php.cn/wenda/176411.html" target="_blank" title="function_exists() cannot determine the custom function" class="wdcdcTitle">function_exists() cannot determine the custom function</a> <a href="https://www.php.cn/wenda/176411.html" class="wdcdcCons">Function test () {return true;} if (function_exists ('test')) {echo "test is function...</a> <div class="wdcdcInfo flexRow"> <div class="wdcdcileft"> <span class="wdcdciSpan"> From 2024-04-29 11:01:01</span> </div> <div class="wdcdciright flexRow"> <div class="wdcdcirdz flexRow ira"> <b class="wdcdcirdzi"></b>0 </div> <div class="wdcdcirpl flexRow ira"><b class="wdcdcirpli"></b>3</div> <div class="wdcdcirwatch flexRow ira"><b class="wdcdcirwatchi"></b>2789</div> </div> </div> </div> </div> <div class="wdsyConLine wdsyConLine2"></div> <div class="wdsyConDiv flexRow wdsyConDiv1"> <div class="wdcdContent flexColumn"> <a href="https://www.php.cn/wenda/176410.html" target="_blank" title="How to display the mobile version of Google Chrome" class="wdcdcTitle">How to display the mobile version of Google Chrome</a> <a href="https://www.php.cn/wenda/176410.html" class="wdcdcCons">Hello teacher, how can I change Google Chrome into a mobile version?</a> <div class="wdcdcInfo flexRow"> <div class="wdcdcileft"> <span class="wdcdciSpan"> From 2024-04-23 00:22:19</span> </div> <div class="wdcdciright flexRow"> <div class="wdcdcirdz flexRow ira"> <b class="wdcdcirdzi"></b>0 </div> <div class="wdcdcirpl flexRow ira"><b class="wdcdcirpli"></b>11</div> <div class="wdcdcirwatch flexRow ira"><b class="wdcdcirwatchi"></b>2922</div> </div> </div> </div> </div> <div class="wdsyConLine wdsyConLine2"></div> <div class="wdsyConDiv flexRow wdsyConDiv1"> <div class="wdcdContent flexColumn"> <a href="https://www.php.cn/wenda/176407.html" target="_blank" title="The child window operates the parent window, but the output does not respond." class="wdcdcTitle">The child window operates the parent window, but the output does not respond.</a> <a href="https://www.php.cn/wenda/176407.html" class="wdcdcCons">The first two sentences are executable, but the last sentence cannot be implemented.</a> <div class="wdcdcInfo flexRow"> <div class="wdcdcileft"> <span class="wdcdciSpan"> From 2024-04-19 15:37:47</span> </div> <div class="wdcdciright flexRow"> <div class="wdcdcirdz flexRow ira"> <b class="wdcdcirdzi"></b>0 </div> <div class="wdcdcirpl flexRow ira"><b class="wdcdcirpli"></b>1</div> <div class="wdcdcirwatch flexRow ira"><b class="wdcdcirwatchi"></b>2439</div> </div> </div> </div> </div> <div class="wdsyConLine wdsyConLine2"></div> <div class="wdsyConDiv flexRow wdsyConDiv1"> <div class="wdcdContent flexColumn"> <a href="https://www.php.cn/wenda/176406.html" target="_blank" title="There is no output in the parent window" class="wdcdcTitle">There is no output in the parent window</a> <a href="https://www.php.cn/wenda/176406.html" class="wdcdcCons">document.onclick = function(){ window.opener.document.write('I am the output of the child ...</a> <div class="wdcdcInfo flexRow"> <div class="wdcdcileft"> <span class="wdcdciSpan"> From 2024-04-18 23:52:34</span> </div> <div class="wdcdciright flexRow"> <div class="wdcdcirdz flexRow ira"> <b class="wdcdcirdzi"></b>0 </div> <div class="wdcdcirpl flexRow ira"><b class="wdcdcirpli"></b>1</div> <div class="wdcdcirwatch flexRow ira"><b class="wdcdcirwatchi"></b>2348</div> </div> </div> </div> </div> <div class="wdsyConLine wdsyConLine2"></div> <div class="wdsyConDiv flexRow wdsyConDiv1"> <div class="wdcdContent flexColumn"> <a href="https://www.php.cn/wenda/176405.html" target="_blank" title="Where is the courseware about CSS mind mapping?" class="wdcdcTitle">Where is the courseware about CSS mind mapping?</a> <a href="https://www.php.cn/wenda/176405.html" class="wdcdcCons">Courseware</a> <div class="wdcdcInfo flexRow"> <div class="wdcdcileft"> <span class="wdcdciSpan"> From 2024-04-16 10:10:18</span> </div> <div class="wdcdciright flexRow"> <div class="wdcdcirdz flexRow ira"> <b class="wdcdcirdzi"></b>0 </div> <div class="wdcdcirpl flexRow ira"><b class="wdcdcirpli"></b>0</div> <div class="wdcdcirwatch flexRow ira"><b class="wdcdcirwatchi"></b>2423</div> </div> </div> </div> </div> <div class="wdsyConLine wdsyConLine2"></div> </div> </div> <div class="wzconZt" > <div class="wzczt-title"> <div>Related Topics</div> <a href="https://www.php.cn/faq/zt" target="_blank">More> </a> </div> <div class="wzcttlist"> <ul> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/faq/netusermldezy"><img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/subject/202407/22/2024072212072139001.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="The function of net user command" /> </a> <a target="_blank" href="https://www.php.cn/faq/netusermldezy" class="title-a-spanl" title="The function of net user command"><span>The function of net user command</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/faq/netusemlyf"><img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/subject/202407/22/2024072214032119292.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="net use command usage" /> </a> <a target="_blank" href="https://www.php.cn/faq/netusemlyf" class="title-a-spanl" title="net use command usage"><span>net use command usage</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/faq/legacyqdssmys"><img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/subject/202407/22/2024072213354124361.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="What does legacy startup mean?" /> </a> <a target="_blank" href="https://www.php.cn/faq/legacyqdssmys" class="title-a-spanl" title="What does legacy startup mean?"><span>What does legacy startup mean?</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/faq/tpfymhfymqb"><img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/subject/202407/22/2024072213445996861.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="The difference between wildcard masking and unmasking" /> </a> <a target="_blank" href="https://www.php.cn/faq/tpfymhfymqb" class="title-a-spanl" title="The difference between wildcard masking and unmasking"><span>The difference between wildcard masking and unmasking</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/faq/pythoneval"><img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/subject/202407/22/2024072214251549631.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="python eval" /> </a> <a target="_blank" href="https://www.php.cn/faq/pythoneval" class="title-a-spanl" title="python eval"><span>python eval</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/faq/ltbjgjrhq"><img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/subject/202407/22/2024072213225410129.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="Litecoin price today" /> </a> <a target="_blank" href="https://www.php.cn/faq/ltbjgjrhq" class="title-a-spanl" title="Litecoin price today"><span>Litecoin price today</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/faq/yyzgng"><img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/subject/202407/22/2024072212330249663.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="What does Metaverse Concept Stock mean?" /> </a> <a target="_blank" href="https://www.php.cn/faq/yyzgng" class="title-a-spanl" title="What does Metaverse Concept Stock mean?"><span>What does Metaverse Concept Stock mean?</span> </a> </li> <li class="ul-li"> <a target="_blank" href="https://www.php.cn/faq/pingg4yy"><img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/subject/202407/22/2024072214431061826.jpg?x-oss-process=image/resize,m_fill,h_145,w_220" alt="iPhone 4 jailbreak" /> </a> <a target="_blank" href="https://www.php.cn/faq/pingg4yy" class="title-a-spanl" title="iPhone 4 jailbreak"><span>iPhone 4 jailbreak</span> </a> </li> </ul> </div> </div> </div> </div> <div class="phpwzright"> <ins class="adsbygoogle" style="display:block" data-ad-client="ca-pub-5902227090019525" data-ad-slot="3653428331" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> <div class="wzrOne"> <div class="wzroTitle">Popular Recommendations</div> <div class="wzroList"> <ul> <li> <div class="wzczzwzli"> <span class="layui-badge-dots wzrolr"></span> <a style="height: auto;" title="what does js mean" href="https://www.php.cn/faq/482163.html">what does js mean</a> </div> </li> <li> <div class="wzczzwzli"> <span class="layui-badge-dots wzrolr"></span> <a style="height: auto;" title="How to convert string to array in js?" href="https://www.php.cn/faq/461802.html">How to convert string to array in js?</a> </div> </li> <li> <div class="wzczzwzli"> <span class="layui-badge-dots wzrolr"></span> <a style="height: auto;" title="How to refresh the page using javascript" href="https://www.php.cn/faq/473330.html">How to refresh the page using javascript</a> </div> </li> <li> <div class="wzczzwzli"> <span class="layui-badge-dots wzrolr"></span> <a style="height: auto;" title="How to delete an item in js array" href="https://www.php.cn/faq/475790.html">How to delete an item in js array</a> </div> </li> <li> <div class="wzczzwzli"> <span class="layui-badge-dots wzrolr"></span> <a style="height: auto;" title="How to use sqrt function" href="https://www.php.cn/faq/415276.html">How to use sqrt function</a> </div> </li> </ul> </div> </div> <script src="https://sw.php.cn/hezuo/cac1399ab368127f9b113b14eb3316d0.js" type="text/javascript"></script> <div class="wzrThree"> <div class="wzrthree-title"> <div>Popular Tutorials</div> <a target="_blank" href="https://www.php.cn/course.html">More> </a> </div> <div class="wzrthreelist swiper2"> <div class="wzrthreeTab swiper-wrapper"> <div class="check tabdiv swiper-slide" data-id="one">Related Tutorials <div></div></div> <div class="tabdiv swiper-slide" data-id="two">Popular Recommendations<div></div></div> <div class="tabdiv swiper-slide" data-id="three">Latest courses<div></div></div> </div> <ul class="one"> <li> <a target="_blank" href="https://www.php.cn/course/812.html" title="The latest ThinkPHP 5.1 world premiere video tutorial (60 days to become a PHP expert online training course)" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/041/620debc3eab3f377.jpg" alt="The latest ThinkPHP 5.1 world premiere video tutorial (60 days to become a PHP expert online training course)"/> </a> <div class="wzrthree-right"> <a target="_blank" title="The latest ThinkPHP 5.1 world premiere video tutorial (60 days to become a PHP expert online training course)" href="https://www.php.cn/course/812.html">The latest ThinkPHP 5.1 world premiere video tutorial (60 days to become a PHP expert online training course)</a> <div class="wzrthreerb"> <div>1433779 <b class="kclbcollectb"></b></div> <div class="courseICollection" data-id="812"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/74.html" title="PHP introductory tutorial one: Learn PHP in one week" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/068/6253d1e28ef5c345.png" alt="PHP introductory tutorial one: Learn PHP in one week"/> </a> <div class="wzrthree-right"> <a target="_blank" title="PHP introductory tutorial one: Learn PHP in one week" href="https://www.php.cn/course/74.html">PHP introductory tutorial one: Learn PHP in one week</a> <div class="wzrthreerb"> <div>4289403 <b class="kclbcollectb"></b></div> <div class="courseICollection" data-id="74"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/286.html" title="JAVA Beginner's Video Tutorial" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/068/62590a2bacfd9379.png" alt="JAVA Beginner's Video Tutorial"/> </a> <div class="wzrthree-right"> <a target="_blank" title="JAVA Beginner's Video Tutorial" href="https://www.php.cn/course/286.html">JAVA Beginner's Video Tutorial</a> <div class="wzrthreerb"> <div>2630775 <b class="kclbcollectb"></b></div> <div class="courseICollection" data-id="286"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/504.html" title="Little Turtle's zero-based introduction to learning Python video tutorial" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/068/62590a67ce3a6655.png" alt="Little Turtle's zero-based introduction to learning Python video tutorial"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Little Turtle's zero-based introduction to learning Python video tutorial" href="https://www.php.cn/course/504.html">Little Turtle's zero-based introduction to learning Python video tutorial</a> <div class="wzrthreerb"> <div>514740 <b class="kclbcollectb"></b></div> <div class="courseICollection" data-id="504"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/2.html" title="PHP zero-based introductory tutorial" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/068/6253de27bc161468.png" alt="PHP zero-based introductory tutorial"/> </a> <div class="wzrthree-right"> <a target="_blank" title="PHP zero-based introductory tutorial" href="https://www.php.cn/course/2.html">PHP zero-based introductory tutorial</a> <div class="wzrthreerb"> <div>873799 <b class="kclbcollectb"></b></div> <div class="courseICollection" data-id="2"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> </ul> <ul class="two" style="display: none;"> <li> <a target="_blank" href="https://www.php.cn/course/812.html" title="The latest ThinkPHP 5.1 world premiere video tutorial (60 days to become a PHP expert online training course)" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/041/620debc3eab3f377.jpg" alt="The latest ThinkPHP 5.1 world premiere video tutorial (60 days to become a PHP expert online training course)"/> </a> <div class="wzrthree-right"> <a target="_blank" title="The latest ThinkPHP 5.1 world premiere video tutorial (60 days to become a PHP expert online training course)" href="https://www.php.cn/course/812.html">The latest ThinkPHP 5.1 world premiere video tutorial (60 days to become a PHP expert online training course)</a> <div class="wzrthreerb"> <div >1433779 times of learning</div> <div class="courseICollection" data-id="812"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/286.html" title="JAVA Beginner's Video Tutorial" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/068/62590a2bacfd9379.png" alt="JAVA Beginner's Video Tutorial"/> </a> <div class="wzrthree-right"> <a target="_blank" title="JAVA Beginner's Video Tutorial" href="https://www.php.cn/course/286.html">JAVA Beginner's Video Tutorial</a> <div class="wzrthreerb"> <div >2630775 times of learning</div> <div class="courseICollection" data-id="286"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/504.html" title="Little Turtle's zero-based introduction to learning Python video tutorial" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/068/62590a67ce3a6655.png" alt="Little Turtle's zero-based introduction to learning Python video tutorial"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Little Turtle's zero-based introduction to learning Python video tutorial" href="https://www.php.cn/course/504.html">Little Turtle's zero-based introduction to learning Python video tutorial</a> <div class="wzrthreerb"> <div >514740 times of learning</div> <div class="courseICollection" data-id="504"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/901.html" title="Quick introduction to web front-end development" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/067/64be28a53a4f6310.png" alt="Quick introduction to web front-end development"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Quick introduction to web front-end development" href="https://www.php.cn/course/901.html">Quick introduction to web front-end development</a> <div class="wzrthreerb"> <div >216799 times of learning</div> <div class="courseICollection" data-id="901"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/234.html" title="Master PS video tutorials from scratch" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/068/62611f57ed0d4840.jpg" alt="Master PS video tutorials from scratch"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Master PS video tutorials from scratch" href="https://www.php.cn/course/234.html">Master PS video tutorials from scratch</a> <div class="wzrthreerb"> <div >913170 times of learning</div> <div class="courseICollection" data-id="234"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> </ul> <ul class="three" style="display: none;"> <li> <a target="_blank" href="https://www.php.cn/course/1648.html" title="[Web front-end] Node.js quick start" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/067/662b5d34ba7c0227.png" alt="[Web front-end] Node.js quick start"/> </a> <div class="wzrthree-right"> <a target="_blank" title="[Web front-end] Node.js quick start" href="https://www.php.cn/course/1648.html">[Web front-end] Node.js quick start</a> <div class="wzrthreerb"> <div >9104 times of learning</div> <div class="courseICollection" data-id="1648"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/1647.html" title="Complete collection of foreign web development full-stack courses" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/067/6628cc96e310c937.png" alt="Complete collection of foreign web development full-stack courses"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Complete collection of foreign web development full-stack courses" href="https://www.php.cn/course/1647.html">Complete collection of foreign web development full-stack courses</a> <div class="wzrthreerb"> <div >7378 times of learning</div> <div class="courseICollection" data-id="1647"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/1646.html" title="Go language practical GraphQL" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/067/662221173504a436.png" alt="Go language practical GraphQL"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Go language practical GraphQL" href="https://www.php.cn/course/1646.html">Go language practical GraphQL</a> <div class="wzrthreerb"> <div >6238 times of learning</div> <div class="courseICollection" data-id="1646"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/1645.html" title="550W fan master learns JavaScript from scratch step by step" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/067/662077e163124646.png" alt="550W fan master learns JavaScript from scratch step by step"/> </a> <div class="wzrthree-right"> <a target="_blank" title="550W fan master learns JavaScript from scratch step by step" href="https://www.php.cn/course/1645.html">550W fan master learns JavaScript from scratch step by step</a> <div class="wzrthreerb"> <div >801 times of learning</div> <div class="courseICollection" data-id="1645"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> <li> <a target="_blank" href="https://www.php.cn/course/1644.html" title="Python master Mosh, a beginner with zero basic knowledge can get started in 6 hours" class="wzrthreelaimg"> <img class="lazy" src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/course/000/000/067/6616418ca80b8916.png" alt="Python master Mosh, a beginner with zero basic knowledge can get started in 6 hours"/> </a> <div class="wzrthree-right"> <a target="_blank" title="Python master Mosh, a beginner with zero basic knowledge can get started in 6 hours" href="https://www.php.cn/course/1644.html">Python master Mosh, a beginner with zero basic knowledge can get started in 6 hours</a> <div class="wzrthreerb"> <div >30912 times of learning</div> <div class="courseICollection" data-id="1644"> <b class="nofollow small-nocollect"></b> </div> </div> </div> </li> </ul> </div> <script> var mySwiper = new Swiper('.swiper2', { autoplay: false,//可选选项,自动滑动 slidesPerView : 'auto', }) $('.wzrthreeTab>div').click(function(e){ $('.wzrthreeTab>div').removeClass('check') $(this).addClass('check') $('.wzrthreelist>ul').css('display','none') $('.'+e.currentTarget.dataset.id).show() }) </script> </div> <div class="wzrFour"> <div class="wzrfour-title"> <div>Latest Downloads</div> <a href="https://www.php.cn/xiazai">More> </a> </div> <script> $(document).ready(function(){ var sjyx_banSwiper = new Swiper(".sjyx_banSwiperwz",{ speed:1000, autoplay:{ delay:3500, disableOnInteraction: false, }, pagination:{ el:'.sjyx_banSwiperwz .swiper-pagination', clickable :false, }, loop:true }) }) </script> <div class="wzrfourList swiper3"> <div class="wzrfourlTab swiper-wrapper"> <div class="check swiper-slide" data-id="onef">Web Effects <div></div></div> <div class="swiper-slide" data-id="twof">Website Source Code<div></div></div> <div class="swiper-slide" data-id="threef">Website Materials<div></div></div> <div class="swiper-slide" data-id="fourf">Front End Template<div></div></div> </div> <ul class="onef"> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="jQuery enterprise message form contact code" href="https://www.php.cn/toolset/js-special-effects/8071">[form button] jQuery enterprise message form contact code</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="HTML5 MP3 music box playback effects" href="https://www.php.cn/toolset/js-special-effects/8070">[Player special effects] HTML5 MP3 music box playback effects</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="HTML5 cool particle animation navigation menu special effects" href="https://www.php.cn/toolset/js-special-effects/8069">[Menu navigation] HTML5 cool particle animation navigation menu special effects</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="jQuery visual form drag and drop editing code" href="https://www.php.cn/toolset/js-special-effects/8068">[form button] jQuery visual form drag and drop editing code</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="VUE.JS imitation Kugou music player code" href="https://www.php.cn/toolset/js-special-effects/8067">[Player special effects] VUE.JS imitation Kugou music player code</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="Classic html5 pushing box game" href="https://www.php.cn/toolset/js-special-effects/8066">[html5 special effects] Classic html5 pushing box game</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="jQuery scrolling to add or reduce image effects" href="https://www.php.cn/toolset/js-special-effects/8065">[Picture special effects] jQuery scrolling to add or reduce image effects</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a target="_blank" title="CSS3 personal album cover hover zoom effect" href="https://www.php.cn/toolset/js-special-effects/8064">[Photo album effects] CSS3 personal album cover hover zoom effect</a> </div> </li> </ul> <ul class="twof" style="display:none"> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8328" title="Home Decor Cleaning and Repair Service Company Website Template" target="_blank">[Front-end template] Home Decor Cleaning and Repair Service Company Website Template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8327" title="Fresh color personal resume guide page template" target="_blank">[Front-end template] Fresh color personal resume guide page template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8326" title="Designer Creative Job Resume Web Template" target="_blank">[Front-end template] Designer Creative Job Resume Web Template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8325" title="Modern engineering construction company website template" target="_blank">[Front-end template] Modern engineering construction company website template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8324" title="Responsive HTML5 template for educational service institutions" target="_blank">[Front-end template] Responsive HTML5 template for educational service institutions</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8323" title="Online e-book store mall website template" target="_blank">[Front-end template] Online e-book store mall website template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8322" title="IT technology solves Internet company website template" target="_blank">[Front-end template] IT technology solves Internet company website template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8321" title="Purple style foreign exchange trading service website template" target="_blank">[Front-end template] Purple style foreign exchange trading service website template</a> </div> </li> </ul> <ul class="threef" style="display:none"> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-materials/3078" target="_blank" title="Cute summer elements vector material (EPS PNG)">[PNG material] Cute summer elements vector material (EPS PNG)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-materials/3077" target="_blank" title="Four red 2023 graduation badges vector material (AI EPS PNG)">[PNG material] Four red 2023 graduation badges vector material (AI EPS PNG)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-materials/3076" target="_blank" title="Singing bird and cart filled with flowers design spring banner vector material (AI EPS)">[banner picture] Singing bird and cart filled with flowers design spring banner vector material (AI EPS)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-materials/3075" target="_blank" title="Golden graduation cap vector material (EPS PNG)">[PNG material] Golden graduation cap vector material (EPS PNG)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-materials/3074" target="_blank" title="Black and white style mountain icon vector material (EPS PNG)">[PNG material] Black and white style mountain icon vector material (EPS PNG)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-materials/3073" target="_blank" title="Superhero silhouette vector material (EPS PNG) with different color cloaks and different poses">[PNG material] Superhero silhouette vector material (EPS PNG) with different color cloaks and different poses</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-materials/3072" target="_blank" title="Flat style Arbor Day banner vector material (AI+EPS)">[banner picture] Flat style Arbor Day banner vector material (AI+EPS)</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-materials/3071" target="_blank" title="Nine comic-style exploding chat bubbles vector material (EPS+PNG)">[PNG material] Nine comic-style exploding chat bubbles vector material (EPS+PNG)</a> </div> </li> </ul> <ul class="fourf" style="display:none"> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8328" target="_blank" title="Home Decor Cleaning and Repair Service Company Website Template">[Front-end template] Home Decor Cleaning and Repair Service Company Website Template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8327" target="_blank" title="Fresh color personal resume guide page template">[Front-end template] Fresh color personal resume guide page template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8326" target="_blank" title="Designer Creative Job Resume Web Template">[Front-end template] Designer Creative Job Resume Web Template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8325" target="_blank" title="Modern engineering construction company website template">[Front-end template] Modern engineering construction company website template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8324" target="_blank" title="Responsive HTML5 template for educational service institutions">[Front-end template] Responsive HTML5 template for educational service institutions</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8323" target="_blank" title="Online e-book store mall website template">[Front-end template] Online e-book store mall website template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8322" target="_blank" title="IT technology solves Internet company website template">[Front-end template] IT technology solves Internet company website template</a> </div> </li> <li> <div class="wzrfourli"> <span class="layui-badge-dots wzrflr"></span> <a href="https://www.php.cn/toolset/website-source-code/8321" target="_blank" title="Purple style foreign exchange trading service website template">[Front-end template] Purple style foreign exchange trading service website template</a> </div> </li> </ul> </div> <script> var mySwiper = new Swiper('.swiper3', { autoplay: false,//可选选项,自动滑动 slidesPerView : 'auto', }) $('.wzrfourlTab>div').click(function(e){ $('.wzrfourlTab>div').removeClass('check') $(this).addClass('check') $('.wzrfourList>ul').css('display','none') $('.'+e.currentTarget.dataset.id).show() }) </script> </div> </div> </div> <footer> <div class="footer"> <div class="footertop"> <img src="/static/imghw/logo.png" alt=""> <p>Public welfare online PHP training,Help PHP learners grow quickly!</p> </div> <div class="footermid"> <a href="https://www.php.cn/about/us.html">About us</a> <a href="https://www.php.cn/about/disclaimer.html">Disclaimer</a> <a href="https://www.php.cn/update/article_0_1.html">Sitemap</a> </div> <div class="footerbottom"> <p> © php.cn All rights reserved </p> </div> </div> </footer> <input type="hidden" id="verifycode" value="/captcha.html"> <script>layui.use(['element', 'carousel'], function () {var element = layui.element;$ = layui.jquery;var carousel = layui.carousel;carousel.render({elem: '#test1', width: '100%', height: '330px', arrow: 'always'});$.getScript('/static/js/jquery.lazyload.min.js', function () {$("img").lazyload({placeholder: "/static/images/load.jpg", effect: "fadeIn", threshold: 200, skip_invisible: false});});});</script> <script src="/static/js/common_new.js"></script> <script type="text/javascript" src="/static/js/jquery.cookie.js?1740146612"></script> <script src="https://vdse.bdstatic.com//search-video.v1.min.js"></script> <link rel='stylesheet' id='_main-css' href='/static/css/viewer.min.css?2' type='text/css' media='all'/> <script type='text/javascript' src='/static/js/viewer.min.js?1'></script> <script type='text/javascript' src='/static/js/jquery-viewer.min.js'></script> <script type="text/javascript" src="/static/js/global.min.js?5.5.53"></script> <!-- Matomo --> <script> var _paq = window._paq = window._paq || []; /* tracker methods like "setCustomDimension" should be called before "trackPageView" */ _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() { var u="https://tongji.php.cn/"; _paq.push(['setTrackerUrl', u+'matomo.php']); _paq.push(['setSiteId', '9']); var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s); })(); </script> <!-- End Matomo Code --> </body> </html>