Getting Fancy with FOP

Getting Fancy with FOP

ebster’s Dictionary defines a fop as being synonymous with a “dandy,” a person (usually male) who spends an inordinate amount of time and effort on dress and appearance, sometimes to ludicrous extremes. Think of the gold-chain-festooned white-polyester clad lounge lizard of the 1970s and you’ll get the basic idea. However, as with so many other terms, FOP has resurfaced with a different meaning?as an acronym for the Formatting-Object Processor, part of the Open Source Apache Project. The FOP processor performs an interesting stunt: it converts an XSL-FO file into an Adobe Postscript Description Format (PDF) file.

XSLT and XSL focus on data-centric and document-centric transformations, respectively, but they are related; You need both to create efficient document-to-print transformations. How do XSLT, XSL, and XSL-Formatting Objects (XSL-FO) fit together?

XSL-FO is a page description language. It’s a language specifically designed for working with fairly sophisticated page content; consequently, it can be surprisingly difficult to master well. Rather than coding XSL-FO documents manually it’s far better to create an XSLT document that will handle the transformation for you.

A Little XSL History
PDF files encode detailed information, font content and graphics within a single file, and have become a standard for document display, just as Postscript has become integral in the area of document printing.

The XSL-FO part, on the other hand, requires a little more explanation, as it is a format that many people think they know but really don’t. In the late 1990’s, as the XML standard was coming together, the W3C Stylesheet working group wanted to create a generalized page description language that would be able to convert an XML document into a presentation. Unfortunately HTML, even as XHTML, isn’t apt at detailed presentations, because the very features that make web browser displays convenient, such aslong scrolling panes of information, don’t fare especially well when split into individual pages.

For example, even simple elements such as headers and footers are problematic. Columns are difficult to format effectively. Specifying print dimensions can be frustrating, because the concept of “width” in a web page is very different from the same concept in most printed output. Finally, HTML is very imprecise, even using CSS positioning, therefore you must add proprietary extensions if you want the output to do more than vaguely resemble the quality of print-only media.

Therefore, the stylesheet group recommended an Extensible Stylesheet Language (or XSL) that would include two components – a descriptive language for formatting specific content, and a transformative language for converting XML into the descriptive language. As it turned out, the simpler of the two languages ended up being the transformation language, which, because it was originally deemed the less essential of the two tasks, was given the name Extensible Stylesheet Language for Transformations, or XSLT. However, as XML has become more data-centric, the role of XSLT as a mechanism for general transformations has become much, much more prominent, while the rest of the XSL specification was relegated to the background.

Eventually though, the XSL recommendation was released, in October, 2001?nearly two years after the XSLT recommendation. Because of the extreme prominence that XSLT has achieved, even though the recommendation is titled Extensible Stylesheet Language (XSL), the page-description portion of XSL is commonly called XSL-FO, where FO stands for Formatting Objects (hence FOP).

A Short XSL-FO Primer
XSL-FO is a page description language. It’s a language specifically designed for working with fairly sophisticated page content; consequently, it can be surprisingly difficult to master well. You won’t be throwing away your copy of Quark or Pagemaker any time soon?but don’t be surprised to see Pagemaker?also an Adobe product?generating XSL-FO eventually. Adobe is perhaps the prime mover behind XSL-FO, though IBM, Sun, Xerox, and other companies also helped author of the XSL Recommendation.

XSL-FO uses the fo: namespace, xmlns:fo = “http://www.w3.org/1999/XSL/Format”, to identify fo: elements contained within a element that acts something akin to HTML’s tag. The document then defines a set of “layout masters”, which can be thought of as templates for different page types, which set the dimensions and general characteristics of each specific type of page. For example, you could create two masters, one for the left page and one for the right, because such pages generally are mirror symmetric in terms of margins. A third master page might define a title page.

I created a very simplified (ad hoc) XML schema to describing the sample document included with this article (although you could easily use something like DocBook to do much the same thing). The schema isn’t the formatting code; it’s just a simple “logical” breakdown of the document (see Listing 1).

Author Note:: The sample document contains an early version of this article?there may be minor differences between the sample document and the final version.

The XSL-FO markup for this document can look a little intimidating, but it’s actually pretty straightforward. All XSL-FO documents begin with a that contains the markup and declares the fo: namespace

The next element should be a layout master set. This is a collection of masters that the document requires. For the current article, the name of this simple page master is (not surprisingly) “mainPage”, but it could be pretty much anything?the master-name attribute just provides a value to refer to the page master:

   

The page master defines the height and width of the page, as well as the dimensions of the margins. Note that the units involved can be any standard CSS units: inches (in), centimeters (cm), millimeters (mm), points (pt), etc. These dimensions are printer page dimensions?if you wanted to print to an 11×17 broadside, for example, you’d specify a page-height of “17in” and a page-width of “11in”. The margins define the actual “printable” area on that page, given as an offset from the page itself along the respective axis.

The page itself is then broken into three distinct areas?the region-before, used to set header information (such as the title of the article), the region-after, which holds footer information such as page numbers, and the region-body, which is the active area where the process inserts the body of the text. The margins here work relative to the margins defined by the page itself, with the extents giving the amount before or after the body that the headers or footers extend respectively.:

         

This defines one master, but it doesn’t tell the order that the master appears. You do that in the page sequence master, which can describe both single instances and repeating collections of pages. The “simpleDoc” sequence master in the following example consists of nothing but repeating page masters named “mainPage.”

            

After defining the page sequence master, you can begin adding content. For a given page sequence adding content involves both defining static content?content such as footers or headers that either do not change or change predictably (such as page numbers) across multiple pages?and flow content, which consists of the main body of the article. You should declare the static content for the header first:

         XML 10 Minute Solution: Getting Fancy With FOP      

The master-name attribute in the element indicates that the page sequence should use the page master defined under page-sequence block just given. The element in turn sets the contents for the header (flow-name=”xsl-region-before”) or the footer (flow-name=”xsl-region-after”). Perhaps the most pervasive element in XSL-FO documents is the element. The element defines a block region, which is analogous to a block within CSS or a

element within HTML. A block defines a rectangular region of text, whether as a paragraph, a collection of paragraphs, a sidebar, a headline or any other layout element that has a bounding rectangle. The opposite of a element is an element, which places the contents of this block within the current flow structure. An element can be thought of as being analogous to an HTML element, or the CSS inline property.

A note about attributes. Many of the attributes you’ll see within both and elements may seem familiar if you’re used to CSS. A big reason for this is that these tags are CSS based, whenever possible. One useful way to envision XSL-FO is to see it a framework for applying CSS in a purely XML environment. The XSL-FO elements define specific entities?parts of pages, regions, or even sections within text?while the attributes basically provide the media description about how those parts look and act.

The footer demonstrates that static content isn’t really all that static:

      Copyright 2001 Cagle Communications --    Page       

The footer content includes the element, which updates from one iteration to the next. The page-number is quite customizable, by the way, employing the same formatting convention that XSLT uses. For example, if you wanted to number elements by capital Roman numerals you’d add the format attribute to the element (note that you don’t add it to the element). Doing that would number the pages in the sequence I, II, III, IV, V, VI, etc., inserting the number at the position of the element.

The final (and arguably most important) part of the document is the region. This contains, for each page sequence, the region into which the template flows the body of text. Unlike static content, which you explicitly set to reside on a given page, the flow content flows from one page to the next, creating new pages when there’s insufficient space on the previous page. The vast majority of the contents within a element will consist of elements.

For example, Listing 2 contains a flow object that shows the title, subtitle, author, and the first paragraph of the article itself

   Getting Fancy With FOP         Creating Adobe Acrobat Files from XSLT and XSL-FO         by Kurt Cagle         Webster's Dictionary defines a fop as being synonymous    with a "dandy," a person (usually male) who spends an    inordinate amount of time and effort on dress and    appearance, sometimes to ludicrous extremes. Think of    the gold-chain-festooned white-polyester clad lounge    lizard of the 1970s and you'll get the basic idea.    However, as with so many other terms, FOP has    resurfaced with a different meaning—as an acronym for    the Formatting-Object Processor, part of the Open    Source Apache Project. The FOP processor performs an    interesting stunt: it converts an XSL-FO file into an    Adobe Postscript Description Format  (PDF) file.         

Finally, the blocks may potentially contain in-line elements. An inline element, as mentioned earlier, is an element that is part of the flow of text. For example, in HTML the element is an inline element that sets the font-weight of the enclosed text to “bold”. In the article, rather than creating and elements, which give no real clue as to why they are bold or italic, I have instead three distinct inline elements: , for emphasis, and to easily create an angle bracketed element. For example, the document presents the element visually as:

   <tag>   

Note that the example given here is very simple?the full XSL-FO specification is more than 300 printed pages in length, and can be extraordinarily complicated. However, that size makes it robust enough to handle a wide variety of applications.

Creating XSL-FO Using XSLT
The full code to describe even a relatively simple XSL-FO document like this one can easily be overwhelming if you attempt to write the XSL-FO code by hand, especially because there’s a great deal of repetition. Ideally, rather than coding a FO document manually (which you should do once, but only once) it’s far better to create an XSLT document that will handle the transformation for you. Fortunately, such transformations are fairly easy to generate.

For example, the file createFOP.xsl contains the transformation for this document. The element declaring the stylesheet namespaces requires two namespaces?one for XML-FO and one for XSLT:

  

Additionally, set the method attribute of the so the stylesheet generates xml output (method=”xml”) and so the result has elements indented, and does not include the XML declaration.

   

The next step to create any kind of document navigator is to figure out how to handle unspecified children. For instance, while the stylesheet uses both the and elements, the XSLT handles them directly in the template that matches the element. To ensure that the content of these elements don’t just “spill out” to the output stream, the stylesheet supports a template matching otherwise untrapped elements or attributes and simply fails to pass them to the output stream. Text elements, on the other hand, usually do need to be passed to the output stream. The following set of match templates handles both of these problems:

            

The template match puts in most of the boilerplate code, including the page dimension definitions and the footer, header and body region. It attempts to match elements in the order that they are encountered (more or less) in the source document, though in general it’s a good idea to explicitly declare the ordering in the stylesheet itself.

                                                                                                                                                               :                                                                         Copyright  - Page                                                                                  

Much of the remainder of the stylesheet generates the appropriate

elements with the prerequisite attributes, and generally have the form:

                           

The element instructs the XSLT processor to find all child elements, attributes and text blocks for the current node and apply the relevant transformation to them. Because the code for handling unknown XML elements already exists, if the stylesheet doesn’t explicitly handle a child element in the source, it simply passes the text of that unknown element into the output stream.

The one single contentious area in this stylesheet involved displaying XML code. XSL-FO does not have an element analogous to the HTML

</span>, which preserves the content and formatting of HTML and XML code. Consequently, to display large blocks of code, you must break each line into its own distinct <span class="pf"><fo:block></span>. Because it&#8217;s unlikely that you would want to wrap thousands of lines of code manually, a better solution is to automate the process, in this case with a named template called codeWrite:</p> <pre><code><xsl:template match="code"> <fo:block font-size="10pt" font-family="Courier" line-height="12pt" text-align="left" padding-left="0.5in" padding-right="0.5in" space-after.optimum="10pt" space-before.optimum="5pt"> <xsl:call-template name="codeWrite"> <xsl:with-param name="buffer" select="string(.)"/> </xsl:call-template> </fo:block> </xsl:template> <xsl:template name="codeWrite"> <xsl:param name="buffer"/> <xsl:variable name="bufferBefore" select="substring-before($buffer,'&#13;')"/> <!-- note that the <xsl:variable name="bufferTest" select="translate($bufferBefore, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvxyz1234567890-=_+& <xsl:variable name="spaceCount" select="string-length( substring-before($bufferTest,'#'))"/> <fo:block margin-left= "0.{number($spaceCount) * 5}in"> <xsl:value-of select="$bufferBefore"/> </fo:block> <xsl:variable name="newBuffer" select="substring-after ($buffer,'&#13;')"/> <xsl:choose> <xsl:when test="$newBuffer != ''"> <xsl:call-template name="codeWrite"> <xsl:with-param name="buffer" select="$newBuffer"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <fo:block> <xsl:value-of select="$newBuffer"/> </fo:block> </xsl:otherwise> </xsl:choose> </xsl:template></code></pre> <p>The <span class="pf">codeWrite</span> routine accepts a block of text and scans for carriage returns. After it finds and extracts the first part of the string, it then determines how much white space is at the beginning of the string (by turning everything else but spaces into hash characters and then retrieving the part of the string before the first encountered hash). The length of this whitespace is then converted into a margin value to indicate how far to indent the line of code.</p> <p>The routine then passes the remainder of the buffered text (after the first carriage return) as a parameter to a recursive <span class="pf">codeWrite</span> call, where the whole process repeats with the truncated string. Eventually, th routine can't retrieve any more strings and the recursive call ends. Because the buffer is written to the output stream each time, this scheme walks through each line of the code. Note that for this to work with XML code, the code must be in a CDATA element:</p> <pre><code> <code>< ![CDATA[ <text>Here is some text</text> ]] ></code></code></pre> <p>Just as with generating HTML from XML, XSLT transformations into XSL-FO can range from being relatively simple to downright Byzantine. The one major notable difference between HTML (especially with CSS) and XSL-FO stems from the fact that XSL-FO does not define the notion of a CSS-like class attribute. Thus, in general, the associations between a given tag (such as the <span class="pf"><code></span> element) and its rendering in XSL-FO tend to be considerably more redundant than HTML code. XSL-FO was intended primarily for print publication, so this redundancy actually makes a great deal of sense, because XSL-FO is intended to be a target of an XSLT transformation, not a hybrid logical/presentation/DOM structure like HTML.</p> <p><strong>Processing FOP</strong><br />XSL-FO by itself is simply a formatting standard?to do anything with it you need to have some kind of processor which will convert the contents of the file into a fully formatted page. Currently, there are few "native" processors for XSL-FO, the most notable one currently being the Antenna House XSL Formatter from Japan. The FOP project was essentially begun as a way to preview XSL-FO, and it has the added benefit of outputting content compatible with the Adobe Acrobat format, which currently is one of the mostly widely available page layout viewers in use on the web.</p> <p>The <a href="http://xml.apache.org/fop/" target="_blank">FOP project</a> is now a part of the <a href="http://xml.apache.org" target="_blank">Apache Open Source project</a>, so it's designed for use with Apache and Cocoon?a content management system that's also part of the work done with Apache.</p> <p>The FOP binary is a set of Java classes that you can invoke directly through the command line or via batch files. On Windows, the package also includes a command line .bat file which you can (with a little finagling) invoke anywhere. You can also integrate the FOP Java classes into Java applications or Servlets to generate PDF files on the fly.</p> <p>XSL-FO is an interesting technology. While it's arguably still trying to determine its true direction, it's also increasingly likely to fill the role of creating hard copy from information on the fly, a task at which HTML is not especially adept, because the onus of such work falls not on the language itself but the specific browser implementation.</p> </div> </div> <div class="elementor-element elementor-element-4f9883d elementor-widget elementor-widget-post-navigation" data-id="4f9883d" data-element_type="widget" data-widget_type="post-navigation.default"> <div class="elementor-widget-container"> <div class="elementor-post-navigation"> <div class="elementor-post-navigation__prev elementor-post-navigation__link"> <a href="https://www.devx.com/xml-zone/16757/" rel="prev"><span class="elementor-post-navigation__link__prev"><span class="post-navigation__prev--label">Previous</span></span></a> </div> <div class="elementor-post-navigation__next elementor-post-navigation__link"> <a href="https://www.devx.com/tip-bank/19368/" rel="next"><span class="elementor-post-navigation__link__next"><span class="post-navigation__next--label">Next</span></span></a> </div> </div> </div> </div> <div class="elementor-element elementor-element-2bf5b4bc elementor-widget elementor-widget-heading" data-id="2bf5b4bc" data-element_type="widget" data-widget_type="heading.default"> <div class="elementor-widget-container"> <span class="elementor-heading-title elementor-size-default">Share the Post:</span> </div> </div> <div class="elementor-element elementor-element-496b8f65 elementor-share-buttons--view-icon elementor-share-buttons--skin-minimal elementor-share-buttons--color-custom elementor-share-buttons--shape-square elementor-grid-0 elementor-widget elementor-widget-share-buttons" data-id="496b8f65" data-element_type="widget" data-widget_type="share-buttons.default"> <div class="elementor-widget-container"> <link rel="stylesheet" href="https://www.devx.com/wp-content/plugins/elementor-pro/assets/css/widget-share-buttons.min.css"> <div class="elementor-grid"> <div class="elementor-grid-item"> <div class="elementor-share-btn elementor-share-btn_facebook" role="button" tabindex="0" aria-label="Share on facebook" > <span class="elementor-share-btn__icon"> <i class="fab fa-facebook" aria-hidden="true"></i> </span> </div> </div> <div class="elementor-grid-item"> <div class="elementor-share-btn elementor-share-btn_twitter" role="button" tabindex="0" aria-label="Share on twitter" > <span class="elementor-share-btn__icon"> <i class="fab fa-twitter" aria-hidden="true"></i> </span> </div> </div> <div class="elementor-grid-item"> <div class="elementor-share-btn elementor-share-btn_linkedin" role="button" tabindex="0" aria-label="Share on linkedin" > <span class="elementor-share-btn__icon"> <i class="fab fa-linkedin" aria-hidden="true"></i> </span> </div> </div> </div> </div> </div> <div class="elementor-element elementor-element-39bd7056 elementor-grid-1 elementor-posts--thumbnail-right elementor-grid-tablet-2 elementor-grid-mobile-1 load-more-align-center elementor-widget elementor-widget-posts" data-id="39bd7056" data-element_type="widget" data-settings="{&quot;classic_columns&quot;:&quot;1&quot;,&quot;classic_row_gap&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:0,&quot;sizes&quot;:[]},&quot;pagination_type&quot;:&quot;load_more_on_click&quot;,&quot;classic_columns_tablet&quot;:&quot;2&quot;,&quot;classic_columns_mobile&quot;:&quot;1&quot;,&quot;classic_row_gap_tablet&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;classic_row_gap_mobile&quot;:{&quot;unit&quot;:&quot;px&quot;,&quot;size&quot;:&quot;&quot;,&quot;sizes&quot;:[]},&quot;load_more_spinner&quot;:{&quot;value&quot;:&quot;fas fa-spinner&quot;,&quot;library&quot;:&quot;fa-solid&quot;}}" data-widget_type="posts.classic"> <div class="elementor-widget-container"> <link rel="stylesheet" href="https://www.devx.com/wp-content/plugins/elementor-pro/assets/css/widget-posts.min.css"> <div class="elementor-posts-container elementor-posts elementor-posts--skin-classic elementor-grid"> <article class="elementor-post elementor-grid-item post-25678 post type-post status-publish format-standard has-post-thumbnail hentry category-tech-trends category-technology tag-keyboards tag-mechanical-keyboards"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/tech-trends/the-best-mechanical-keyboards-for-programmers-where-to-find-them/" > <div class="elementor-post__thumbnail"><img width="1920" height="1280" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25998 ewww_webp" alt="Where to find the Best Mechanical Keyboards for Programmers" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/pexels-karol-d-841228.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/pexels-karol-d-841228.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1280" src="https://www.devx.com/wp-content/uploads/pexels-karol-d-841228.jpg" class="elementor-animation-grow attachment-full size-full wp-image-25998" alt="Where to find the Best Mechanical Keyboards for Programmers" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/tech-trends/the-best-mechanical-keyboards-for-programmers-where-to-find-them/" > The Best Mechanical Keyboards For Programmers: Where To Find Them </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 29, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>When it comes to programming, a good mechanical keyboard can make all the difference. Naturally, you would want one of the best mechanical keyboards for programmers. But with so many</p> </div> </div> </article> <article class="elementor-post elementor-grid-item post-26000 post type-post status-publish format-standard has-post-thumbnail hentry category-devx-daily-news tag-big-brother"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/devx-daily-news/the-digital-panopticon-is-big-brother-always-watching-us-online/" > <div class="elementor-post__thumbnail"><img width="1920" height="1280" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-26001 ewww_webp" alt="The Digital Panopticon: Is Big Brother Always Watching Us Online?" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/marvin-meyer-SYTO3xs06fU-unsplash-1.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/marvin-meyer-SYTO3xs06fU-unsplash-1.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1280" src="https://www.devx.com/wp-content/uploads/marvin-meyer-SYTO3xs06fU-unsplash-1.jpg" class="elementor-animation-grow attachment-full size-full wp-image-26001" alt="The Digital Panopticon: Is Big Brother Always Watching Us Online?" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/devx-daily-news/the-digital-panopticon-is-big-brother-always-watching-us-online/" > The Digital Panopticon: Is Big Brother Always Watching Us Online? </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 26, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>In the age of digital transformation, the internet has become a ubiquitous part of our lives. From socializing, shopping, and learning to more sensitive activities such as banking and healthcare,</p> </div> </div> </article> <article class="elementor-post elementor-grid-item post-25983 post type-post status-publish format-standard has-post-thumbnail hentry category-artificial-intelligence-ai"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/artificial-intelligence-ai/embracing-change-how-ai-is-revolutionizing-the-developers-role/" > <div class="elementor-post__thumbnail"><img width="1920" height="1440" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25984 ewww_webp" alt="web developer" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/web-developer.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/web-developer.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1440" src="https://www.devx.com/wp-content/uploads/web-developer.jpg" class="elementor-animation-grow attachment-full size-full wp-image-25984" alt="web developer" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/artificial-intelligence-ai/embracing-change-how-ai-is-revolutionizing-the-developers-role/" > Embracing Change: How AI Is Revolutionizing the Developer&#8217;s Role </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 25, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>The world of software development is changing drastically with the introduction of Artificial Intelligence and Machine Learning technologies. In the past, software developers were in charge of the entire development</p> </div> </div> </article> <article class="elementor-post elementor-grid-item post-25978 post type-post status-publish format-standard has-post-thumbnail hentry category-security"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/security/the-benefits-of-using-xdr-solutions/" > <div class="elementor-post__thumbnail"><img width="512" height="342" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25979 ewww_webp" alt="XDR solutions" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/XDR-solutions.jpeg" data-src-webp="https://www.devx.com/wp-content/uploads/XDR-solutions.jpeg.webp" data-eio="j" /><noscript><img width="512" height="342" src="https://www.devx.com/wp-content/uploads/XDR-solutions.jpeg" class="elementor-animation-grow attachment-full size-full wp-image-25979" alt="XDR solutions" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/security/the-benefits-of-using-xdr-solutions/" > The Benefits of Using XDR Solutions </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 24, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>Cybercriminals constantly adapt their strategies, developing newer, more powerful, and intelligent ways to attack your network. Since security professionals must innovate as well, more conventional endpoint detection solutions have evolved</p> </div> </div> </article> <article class="elementor-post elementor-grid-item post-25973 post type-post status-publish format-standard has-post-thumbnail hentry category-artificial-intelligence-ai category-security"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/artificial-intelligence-ai/how-ai-is-revolutionizing-fraud-detection/" > <div class="elementor-post__thumbnail"><img width="512" height="341" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25975 ewww_webp" alt="AI is revolutionizing fraud detection" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/AI-is-revolutionizing-fraud-detection.jpeg" data-src-webp="https://www.devx.com/wp-content/uploads/AI-is-revolutionizing-fraud-detection.jpeg.webp" data-eio="j" /><noscript><img width="512" height="341" src="https://www.devx.com/wp-content/uploads/AI-is-revolutionizing-fraud-detection.jpeg" class="elementor-animation-grow attachment-full size-full wp-image-25975" alt="AI is revolutionizing fraud detection" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/artificial-intelligence-ai/how-ai-is-revolutionizing-fraud-detection/" > How AI is Revolutionizing Fraud Detection </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 23, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>Artificial intelligence &#8211; commonly known as AI &#8211; means a form of technology with multiple uses. As a result, it has become extremely valuable to a number of businesses across</p> </div> </div> </article> <article class="elementor-post elementor-grid-item post-25410 post type-post status-publish format-standard has-post-thumbnail hentry category-artificial-intelligence-ai"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/artificial-intelligence-ai/companies-leading-ai-innovation-in-2023/" > <div class="elementor-post__thumbnail"><img width="1920" height="1440" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25968 ewww_webp" alt="AI innovation" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/AI-innovation.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/AI-innovation.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1440" src="https://www.devx.com/wp-content/uploads/AI-innovation.jpg" class="elementor-animation-grow attachment-full size-full wp-image-25968" alt="AI innovation" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/artificial-intelligence-ai/companies-leading-ai-innovation-in-2023/" > Companies Leading AI Innovation in 2023 </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 22, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>Artificial intelligence (AI) has been transforming industries and revolutionizing business operations. AI&#8217;s potential to enhance efficiency and productivity has become crucial to many businesses. As we move into 2023, several</p> </div> </div> </article> <article class="elementor-post elementor-grid-item post-25406 post type-post status-publish format-standard has-post-thumbnail hentry category-enterprise category-uncategorized category-small-business category-tools"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/small-business/step-by-step-guide-to-properly-copyright-your-website/" > <div class="elementor-post__thumbnail"><img width="1920" height="1277" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25961 ewww_webp" alt="copyright your website" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/copyright-your-website.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/copyright-your-website.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1277" src="https://www.devx.com/wp-content/uploads/copyright-your-website.jpg" class="elementor-animation-grow attachment-full size-full wp-image-25961" alt="copyright your website" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/small-business/step-by-step-guide-to-properly-copyright-your-website/" > Step-by-Step Guide to Properly Copyright Your Website </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 18, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>Creating a website is not easy, but protecting your website is equally important. Implementing copyright laws ensures that the substance of your website remains secure and sheltered. Copyrighting your website</p> </div> </div> </article> <article class="elementor-post elementor-grid-item post-25417 post type-post status-publish format-standard has-post-thumbnail hentry category-data-access category-software"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/software/fivetran-pricing-explained/" > <div class="elementor-post__thumbnail"><img width="1920" height="1281" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25942 ewww_webp" alt="data fivetran pricing" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/data-fivetran-pricing.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/data-fivetran-pricing.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1281" src="https://www.devx.com/wp-content/uploads/data-fivetran-pricing.jpg" class="elementor-animation-grow attachment-full size-full wp-image-25942" alt="data fivetran pricing" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/software/fivetran-pricing-explained/" > Fivetran Pricing Explained </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 17, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>One of the biggest trends of the 21st century is the massive surge in analytics. Analytics is the process of utilizing data to drive future decision-making. With so much of</p> </div> </div> </article> <article class="elementor-post elementor-grid-item post-25936 post type-post status-publish format-standard has-post-thumbnail hentry category-software"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/software/kubernetes-logging/" > <div class="elementor-post__thumbnail"><img width="512" height="341" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25938 ewww_webp" alt="kubernetes logging" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/kubernetes-logging.jpeg" data-src-webp="https://www.devx.com/wp-content/uploads/kubernetes-logging.jpeg.webp" data-eio="j" /><noscript><img width="512" height="341" src="https://www.devx.com/wp-content/uploads/kubernetes-logging.jpeg" class="elementor-animation-grow attachment-full size-full wp-image-25938" alt="kubernetes logging" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/software/kubernetes-logging/" > Kubernetes Logging: What You Need to Know </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 16, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>Kubernetes from Google is one of the most popular open-source and free container management solutions made to make managing and deploying applications easier. It has a solid architecture that makes</p> </div> </div> </article> <article class="elementor-post elementor-grid-item post-25930 post type-post status-publish format-standard has-post-thumbnail hentry category-ransomware"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/ransomware/why-is-ransomware-such-a-major-threat/" > <div class="elementor-post__thumbnail"><img width="1920" height="1280" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25933 ewww_webp" alt="ransomware cyber attack" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/ransomware-cyber-attack.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/ransomware-cyber-attack.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1280" src="https://www.devx.com/wp-content/uploads/ransomware-cyber-attack.jpg" class="elementor-animation-grow attachment-full size-full wp-image-25933" alt="ransomware cyber attack" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/ransomware/why-is-ransomware-such-a-major-threat/" > Why Is Ransomware Such a Major Threat? </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 15, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>One of the most significant cyber threats faced by modern organizations is a ransomware attack. Ransomware attacks have grown in both sophistication and frequency over the past few years, forcing</p> </div> </div> </article> <article class="elementor-post elementor-grid-item post-25404 post type-post status-publish format-standard has-post-thumbnail hentry category-data-access-and-management"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/data-access-and-management/tools-you-need-to-make-a-data-dictionary/" > <div class="elementor-post__thumbnail"><img width="1920" height="1440" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-25923 ewww_webp" alt="data dictionary" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/data-dictionary.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/data-dictionary.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1440" src="https://www.devx.com/wp-content/uploads/data-dictionary.jpg" class="elementor-animation-grow attachment-full size-full wp-image-25923" alt="data dictionary" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/data-access-and-management/tools-you-need-to-make-a-data-dictionary/" > Tools You Need to Make a Data Dictionary </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 12, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>Data dictionaries are crucial for organizations of all sizes that deal with large amounts of data. they are centralized repositories of all the data in organizations, including metadata such as</p> </div> </div> </article> <article class="elementor-post elementor-grid-item post-22419 post type-post status-publish format-standard has-post-thumbnail hentry category-web-development-zone"> <a class="elementor-post__thumbnail__link" href="https://www.devx.com/web-development-zone/10-software-development-tips/" > <div class="elementor-post__thumbnail"><img width="1920" height="1080" src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==" class="elementor-animation-grow attachment-full size-full wp-image-23554 ewww_webp" alt="developing enterprise software" loading="lazy" data-src-img="https://www.devx.com/wp-content/uploads/developing-enterprise-software.jpg" data-src-webp="https://www.devx.com/wp-content/uploads/developing-enterprise-software.jpg.webp" data-eio="j" /><noscript><img width="1920" height="1080" src="https://www.devx.com/wp-content/uploads/developing-enterprise-software.jpg" class="elementor-animation-grow attachment-full size-full wp-image-23554" alt="developing enterprise software" loading="lazy" /></noscript></div> </a> <div class="elementor-post__text"> <h3 class="elementor-post__title"> <a href="https://www.devx.com/web-development-zone/10-software-development-tips/" > 10 Software Development Tips to Get Early Funding for your Startup </a> </h3> <div class="elementor-post__meta-data"> <span class="elementor-post-date"> May 11, 2023 </span> </div> <div class="elementor-post__excerpt"> <p>If you’re thinking about a startup, it’s likely you need to raise an initial round of funding for your venture. This article covers some of the very early development techniques</p> </div> </div> </article> </div> <span class="e-load-more-spinner"> <i aria-hidden="true" class="fas fa-spinner"></i> </span> <div class="e-load-more-anchor" data-page="1" data-max-page="1499" data-next-page="https://www.devx.com/get-help/20353/2/"></div> <div class="elementor-button-wrapper"> <a href="#" class="elementor-button-link elementor-button elementor-animation-grow" role="button"> <span class="elementor-button-content-wrapper"> <span class="elementor-button-text">Show More</span> </span> </a> </div> <div class="e-load-more-message"></div> </div> </div> </div> </div> </div> </section> </div> </div> <div class="elementor-column elementor-col-20 elementor-top-column elementor-element elementor-element-270dc71" data-id="270dc71" data-element_type="column"> <div class="elementor-widget-wrap"> </div> </div> <div class="elementor-column elementor-col-20 elementor-top-column elementor-element elementor-element-8905b95 elementor-hidden-tablet" data-id="8905b95" data-element_type="column"> <div class="elementor-widget-wrap elementor-element-populated"> <div class="elementor-element elementor-element-46d69df elementor-widget elementor-widget-html" data-id="46d69df" data-element_type="widget" data-widget_type="html.default"> <div class="elementor-widget-container"> <iframe id="JotFormIFrame-230167013128041" title="Daily Technology News Straight to Your Inbox" onload="window.parent.scrollTo(0,0)" allowtransparency="true" allowfullscreen="true" allow="geolocation; microphone; camera" src="https://form.jotform.com/230167013128041" frameborder="0" style=" min-width: 100%; height:539px; border:none;" scrolling="no" > </iframe> <script type="text/javascript"> var ifr = document.getElementById("JotFormIFrame-230167013128041"); if (ifr) { var src = ifr.src; var iframeParams = []; if (window.location.href && window.location.href.indexOf("?") > -1) { iframeParams = iframeParams.concat(window.location.href.substr(window.location.href.indexOf("?") + 1).split('&')); } if (src && src.indexOf("?") > -1) { iframeParams = iframeParams.concat(src.substr(src.indexOf("?") + 1).split("&")); src = src.substr(0, src.indexOf("?")) } iframeParams.push("isIframeEmbed=1"); ifr.src = src + "?" + iframeParams.join('&'); } window.handleIFrameMessage = function(e) { if (typeof e.data === 'object') { return; } var args = e.data.split(":"); if (args.length > 2) { iframe = document.getElementById("JotFormIFrame-" + args[(args.length - 1)]); } else { iframe = document.getElementById("JotFormIFrame"); } if (!iframe) { return; } switch (args[0]) { case "scrollIntoView": iframe.scrollIntoView(); break; case "setHeight": iframe.style.height = args[1] + "px"; if (!isNaN(args[1]) && parseInt(iframe.style.minHeight) > parseInt(args[1])) { iframe.style.minHeight = args[1] + "px"; } break; case "collapseErrorPage": if (iframe.clientHeight > window.innerHeight) { iframe.style.height = window.innerHeight + "px"; } break; case "reloadPage": window.location.reload(); break; case "loadScript": if( !window.isPermitted(e.origin, ['jotform.com', 'jotform.pro']) ) { break; } var src = args[1]; if (args.length > 3) { src = args[1] + ':' + args[2]; } var script = document.createElement('script'); script.src = src; script.type = 'text/javascript'; document.body.appendChild(script); break; case "exitFullscreen": if (window.document.exitFullscreen) window.document.exitFullscreen(); else if (window.document.mozCancelFullScreen) window.document.mozCancelFullScreen(); else if (window.document.mozCancelFullscreen) window.document.mozCancelFullScreen(); else if (window.document.webkitExitFullscreen) window.document.webkitExitFullscreen(); else if (window.document.msExitFullscreen) window.document.msExitFullscreen(); break; } var isJotForm = (e.origin.indexOf("jotform") > -1) ? true : false; if(isJotForm && "contentWindow" in iframe && "postMessage" in iframe.contentWindow) { var urls = {"docurl":encodeURIComponent(document.URL),"referrer":encodeURIComponent(document.referrer)}; iframe.contentWindow.postMessage(JSON.stringify({"type":"urls","value":urls}), "*"); } }; window.isPermitted = function(originUrl, whitelisted_domains) { var url = document.createElement('a'); url.href = originUrl; var hostname = url.hostname; var result = false; if( typeof hostname !== 'undefined' ) { whitelisted_domains.forEach(function(element) { if( hostname.slice((-1 * element.length - 1)) === '.'.concat(element) || hostname === element ) { result = true; } }); return result; } }; if (window.addEventListener) { window.addEventListener("message", handleIFrameMessage, false); } else if (window.attachEvent) { window.attachEvent("onmessage", handleIFrameMessage); } </script> </div> </div> <div class="elementor-element elementor-element-7c9513d elementor-widget elementor-widget-html" data-id="7c9513d" data-element_type="widget" data-settings="{&quot;sticky_offset&quot;:10,&quot;sticky_parent&quot;:&quot;yes&quot;,&quot;sticky&quot;:&quot;top&quot;,&quot;sticky_on&quot;:[&quot;desktop&quot;,&quot;tablet&quot;,&quot;mobile&quot;],&quot;sticky_effects_offset&quot;:0}" data-widget_type="html.default"> <div class="elementor-widget-container"> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-1183579825777021" crossorigin="anonymous"></script> <!-- devx top --> <ins class="adsbygoogle" style="display:inline-block;width:300px;height:600px" data-ad-client="ca-pub-1183579825777021" data-ad-slot="2250810506"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script> </div> </div> </div> </div> </div> </section> <section class="elementor-section elementor-top-section elementor-element elementor-element-7ef94119 elementor-hidden-mobile elementor-hidden-tablet elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="7ef94119" data-element_type="section"> <div class="elementor-container elementor-column-gap-default"> <div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-cb0d3b5" data-id="cb0d3b5" data-element_type="column"> <div class="elementor-widget-wrap"> </div> </div> <div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-dcd3813" data-id="dcd3813" data-element_type="column"> <div class="elementor-widget-wrap"> </div> </div> </div> </section> </div> <footer data-elementor-type="footer" data-elementor-id="23300" class="elementor elementor-23300 elementor-location-footer"> <footer class="elementor-section elementor-top-section elementor-element elementor-element-1588a538 elementor-section-height-min-height elementor-section-content-middle elementor-section-full_width elementor-section-height-default elementor-section-items-middle" data-id="1588a538" data-element_type="section" data-settings="{&quot;background_background&quot;:&quot;classic&quot;}"> <div class="elementor-container elementor-column-gap-no"> <div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-9d2a788" data-id="9d2a788" data-element_type="column"> <div class="elementor-widget-wrap"> </div> </div> <div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-2e0ce949" data-id="2e0ce949" data-element_type="column"> <div class="elementor-widget-wrap elementor-element-populated"> <div class="elementor-element elementor-element-4f9ec08 elementor-widget-divider--view-line elementor-widget elementor-widget-divider" data-id="4f9ec08" data-element_type="widget" data-widget_type="divider.default"> <div class="elementor-widget-container"> <style>/*! elementor - v3.12.2 - 23-04-2023 */ .elementor-widget-divider{--divider-border-style:none;--divider-border-width:1px;--divider-color:#0c0d0e;--divider-icon-size:20px;--divider-element-spacing:10px;--divider-pattern-height:24px;--divider-pattern-size:20px;--divider-pattern-url:none;--divider-pattern-repeat:repeat-x}.elementor-widget-divider .elementor-divider{display:flex}.elementor-widget-divider .elementor-divider__text{font-size:15px;line-height:1;max-width:95%}.elementor-widget-divider .elementor-divider__element{margin:0 var(--divider-element-spacing);flex-shrink:0}.elementor-widget-divider .elementor-icon{font-size:var(--divider-icon-size)}.elementor-widget-divider .elementor-divider-separator{display:flex;margin:0;direction:ltr}.elementor-widget-divider--view-line_icon .elementor-divider-separator,.elementor-widget-divider--view-line_text .elementor-divider-separator{align-items:center}.elementor-widget-divider--view-line_icon .elementor-divider-separator:after,.elementor-widget-divider--view-line_icon .elementor-divider-separator:before,.elementor-widget-divider--view-line_text .elementor-divider-separator:after,.elementor-widget-divider--view-line_text .elementor-divider-separator:before{display:block;content:"";border-bottom:0;flex-grow:1;border-top:var(--divider-border-width) var(--divider-border-style) var(--divider-color)}.elementor-widget-divider--element-align-left .elementor-divider .elementor-divider-separator>.elementor-divider__svg:first-of-type{flex-grow:0;flex-shrink:100}.elementor-widget-divider--element-align-left .elementor-divider-separator:before{content:none}.elementor-widget-divider--element-align-left .elementor-divider__element{margin-left:0}.elementor-widget-divider--element-align-right .elementor-divider .elementor-divider-separator>.elementor-divider__svg:last-of-type{flex-grow:0;flex-shrink:100}.elementor-widget-divider--element-align-right .elementor-divider-separator:after{content:none}.elementor-widget-divider--element-align-right .elementor-divider__element{margin-right:0}.elementor-widget-divider:not(.elementor-widget-divider--view-line_text):not(.elementor-widget-divider--view-line_icon) .elementor-divider-separator{border-top:var(--divider-border-width) var(--divider-border-style) var(--divider-color)}.elementor-widget-divider--separator-type-pattern{--divider-border-style:none}.elementor-widget-divider--separator-type-pattern.elementor-widget-divider--view-line .elementor-divider-separator,.elementor-widget-divider--separator-type-pattern:not(.elementor-widget-divider--view-line) .elementor-divider-separator:after,.elementor-widget-divider--separator-type-pattern:not(.elementor-widget-divider--view-line) .elementor-divider-separator:before,.elementor-widget-divider--separator-type-pattern:not([class*=elementor-widget-divider--view]) .elementor-divider-separator{width:100%;min-height:var(--divider-pattern-height);-webkit-mask-size:var(--divider-pattern-size) 100%;mask-size:var(--divider-pattern-size) 100%;-webkit-mask-repeat:var(--divider-pattern-repeat);mask-repeat:var(--divider-pattern-repeat);background-color:var(--divider-color);-webkit-mask-image:var(--divider-pattern-url);mask-image:var(--divider-pattern-url)}.elementor-widget-divider--no-spacing{--divider-pattern-size:auto}.elementor-widget-divider--bg-round{--divider-pattern-repeat:round}.rtl .elementor-widget-divider .elementor-divider__text{direction:rtl}.e-con-inner>.elementor-widget-divider,.e-con>.elementor-widget-divider{width:var(--container-widget-width,100%);--flex-grow:var(--container-widget-flex-grow)}</style> <div class="elementor-divider"> <span class="elementor-divider-separator"> </span> </div> </div> </div> <section class="elementor-section elementor-inner-section elementor-element elementor-element-73a9986 elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="73a9986" data-element_type="section"> <div class="elementor-container elementor-column-gap-default"> <div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-7f08930" data-id="7f08930" data-element_type="column"> <div class="elementor-widget-wrap elementor-element-populated"> <div class="elementor-element elementor-element-269b367 elementor-nav-menu__align-center elementor-nav-menu--dropdown-tablet elementor-nav-menu__text-align-aside elementor-nav-menu--toggle elementor-nav-menu--burger elementor-widget elementor-widget-nav-menu" data-id="269b367" data-element_type="widget" data-settings="{&quot;layout&quot;:&quot;horizontal&quot;,&quot;submenu_icon&quot;:{&quot;value&quot;:&quot;&lt;i class=\&quot;fas fa-caret-down\&quot;&gt;&lt;\/i&gt;&quot;,&quot;library&quot;:&quot;fa-solid&quot;},&quot;toggle&quot;:&quot;burger&quot;}" data-widget_type="nav-menu.default"> <div class="elementor-widget-container"> <nav class="elementor-nav-menu--main elementor-nav-menu__container elementor-nav-menu--layout-horizontal e--pointer-underline e--animation-fade"> <ul id="menu-1-269b367" class="elementor-nav-menu"><li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-home menu-item-23808"><a href="https://www.devx.com/" class="elementor-item">Home</a></li> <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-23809"><a href="https://www.devx.com/advertise/" class="elementor-item">Advertise</a></li> <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-23816"><a href="https://www.devx.com/about/" class="elementor-item">About</a></li> </ul> </nav> <div class="elementor-menu-toggle" role="button" tabindex="0" aria-label="Menu Toggle" aria-expanded="false"> <i aria-hidden="true" role="presentation" class="elementor-menu-toggle__icon--open eicon-menu-bar"></i><i aria-hidden="true" role="presentation" class="elementor-menu-toggle__icon--close eicon-close"></i> <span class="elementor-screen-only">Menu</span> </div> <nav class="elementor-nav-menu--dropdown elementor-nav-menu__container" aria-hidden="true"> <ul id="menu-2-269b367" class="elementor-nav-menu"><li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-home menu-item-23808"><a href="https://www.devx.com/" class="elementor-item" tabindex="-1">Home</a></li> <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-23809"><a href="https://www.devx.com/advertise/" class="elementor-item" tabindex="-1">Advertise</a></li> <li class="menu-item menu-item-type-post_type menu-item-object-page menu-item-23816"><a href="https://www.devx.com/about/" class="elementor-item" tabindex="-1">About</a></li> </ul> </nav> </div> </div> </div> </div> <div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-21928d3" data-id="21928d3" data-element_type="column"> <div class="elementor-widget-wrap"> </div> </div> <div class="elementor-column elementor-col-33 elementor-inner-column elementor-element elementor-element-869862d" data-id="869862d" data-element_type="column"> <div class="elementor-widget-wrap elementor-element-populated"> <div class="elementor-element elementor-element-5d5f4dc5 e-grid-align-left elementor-shape-rounded elementor-grid-0 elementor-widget elementor-widget-social-icons" data-id="5d5f4dc5" data-element_type="widget" data-widget_type="social-icons.default"> <div class="elementor-widget-container"> <style>/*! elementor - v3.12.2 - 23-04-2023 */ .elementor-widget-social-icons.elementor-grid-0 .elementor-widget-container,.elementor-widget-social-icons.elementor-grid-mobile-0 .elementor-widget-container,.elementor-widget-social-icons.elementor-grid-tablet-0 .elementor-widget-container{line-height:1;font-size:0}.elementor-widget-social-icons:not(.elementor-grid-0):not(.elementor-grid-tablet-0):not(.elementor-grid-mobile-0) .elementor-grid{display:inline-grid}.elementor-widget-social-icons .elementor-grid{grid-column-gap:var(--grid-column-gap,5px);grid-row-gap:var(--grid-row-gap,5px);grid-template-columns:var(--grid-template-columns);justify-content:var(--justify-content,center);justify-items:var(--justify-content,center)}.elementor-icon.elementor-social-icon{font-size:var(--icon-size,25px);line-height:var(--icon-size,25px);width:calc(var(--icon-size, 25px) + (2 * var(--icon-padding, .5em)));height:calc(var(--icon-size, 25px) + (2 * var(--icon-padding, .5em)))}.elementor-social-icon{--e-social-icon-icon-color:#fff;display:inline-flex;background-color:#69727d;align-items:center;justify-content:center;text-align:center;cursor:pointer}.elementor-social-icon i{color:var(--e-social-icon-icon-color)}.elementor-social-icon svg{fill:var(--e-social-icon-icon-color)}.elementor-social-icon:last-child{margin:0}.elementor-social-icon:hover{opacity:.9;color:#fff}.elementor-social-icon-android{background-color:#a4c639}.elementor-social-icon-apple{background-color:#999}.elementor-social-icon-behance{background-color:#1769ff}.elementor-social-icon-bitbucket{background-color:#205081}.elementor-social-icon-codepen{background-color:#000}.elementor-social-icon-delicious{background-color:#39f}.elementor-social-icon-deviantart{background-color:#05cc47}.elementor-social-icon-digg{background-color:#005be2}.elementor-social-icon-dribbble{background-color:#ea4c89}.elementor-social-icon-elementor{background-color:#d30c5c}.elementor-social-icon-envelope{background-color:#ea4335}.elementor-social-icon-facebook,.elementor-social-icon-facebook-f{background-color:#3b5998}.elementor-social-icon-flickr{background-color:#0063dc}.elementor-social-icon-foursquare{background-color:#2d5be3}.elementor-social-icon-free-code-camp,.elementor-social-icon-freecodecamp{background-color:#006400}.elementor-social-icon-github{background-color:#333}.elementor-social-icon-gitlab{background-color:#e24329}.elementor-social-icon-globe{background-color:#69727d}.elementor-social-icon-google-plus,.elementor-social-icon-google-plus-g{background-color:#dd4b39}.elementor-social-icon-houzz{background-color:#7ac142}.elementor-social-icon-instagram{background-color:#262626}.elementor-social-icon-jsfiddle{background-color:#487aa2}.elementor-social-icon-link{background-color:#818a91}.elementor-social-icon-linkedin,.elementor-social-icon-linkedin-in{background-color:#0077b5}.elementor-social-icon-medium{background-color:#00ab6b}.elementor-social-icon-meetup{background-color:#ec1c40}.elementor-social-icon-mixcloud{background-color:#273a4b}.elementor-social-icon-odnoklassniki{background-color:#f4731c}.elementor-social-icon-pinterest{background-color:#bd081c}.elementor-social-icon-product-hunt{background-color:#da552f}.elementor-social-icon-reddit{background-color:#ff4500}.elementor-social-icon-rss{background-color:#f26522}.elementor-social-icon-shopping-cart{background-color:#4caf50}.elementor-social-icon-skype{background-color:#00aff0}.elementor-social-icon-slideshare{background-color:#0077b5}.elementor-social-icon-snapchat{background-color:#fffc00}.elementor-social-icon-soundcloud{background-color:#f80}.elementor-social-icon-spotify{background-color:#2ebd59}.elementor-social-icon-stack-overflow{background-color:#fe7a15}.elementor-social-icon-steam{background-color:#00adee}.elementor-social-icon-stumbleupon{background-color:#eb4924}.elementor-social-icon-telegram{background-color:#2ca5e0}.elementor-social-icon-thumb-tack{background-color:#1aa1d8}.elementor-social-icon-tripadvisor{background-color:#589442}.elementor-social-icon-tumblr{background-color:#35465c}.elementor-social-icon-twitch{background-color:#6441a5}.elementor-social-icon-twitter{background-color:#1da1f2}.elementor-social-icon-viber{background-color:#665cac}.elementor-social-icon-vimeo{background-color:#1ab7ea}.elementor-social-icon-vk{background-color:#45668e}.elementor-social-icon-weibo{background-color:#dd2430}.elementor-social-icon-weixin{background-color:#31a918}.elementor-social-icon-whatsapp{background-color:#25d366}.elementor-social-icon-wordpress{background-color:#21759b}.elementor-social-icon-xing{background-color:#026466}.elementor-social-icon-yelp{background-color:#af0606}.elementor-social-icon-youtube{background-color:#cd201f}.elementor-social-icon-500px{background-color:#0099e5}.elementor-shape-rounded .elementor-icon.elementor-social-icon{border-radius:10%}.elementor-shape-circle .elementor-icon.elementor-social-icon{border-radius:50%}</style> <div class="elementor-social-icons-wrapper elementor-grid"> <span class="elementor-grid-item"> <a class="elementor-icon elementor-social-icon elementor-social-icon-linkedin elementor-repeater-item-5c0ce3c" href="https://www.linkedin.com/company/devx" target="_blank"> <span class="elementor-screen-only">Linkedin</span> <i class="fab fa-linkedin"></i> </a> </span> <span class="elementor-grid-item"> <a class="elementor-icon elementor-social-icon elementor-social-icon-twitter elementor-repeater-item-828f132" href="https://twitter.com/DevX_Com" target="_blank"> <span class="elementor-screen-only">Twitter</span> <i class="fab fa-twitter"></i> </a> </span> </div> </div> </div> </div> </div> </div> </section> <div class="elementor-element elementor-element-6963de5 elementor-widget-divider--view-line elementor-widget elementor-widget-divider" data-id="6963de5" data-element_type="widget" data-widget_type="divider.default"> <div class="elementor-widget-container"> <div class="elementor-divider"> <span class="elementor-divider-separator"> </span> </div> </div> </div> </div> </div> </div> </footer> <section class="elementor-section elementor-top-section elementor-element elementor-element-a4f01a6 elementor-section-boxed elementor-section-height-default elementor-section-height-default" data-id="a4f01a6" data-element_type="section"> <div class="elementor-container elementor-column-gap-default"> <div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-a1bc5b1" data-id="a1bc5b1" data-element_type="column"> <div class="elementor-widget-wrap"> </div> </div> <div class="elementor-column elementor-col-50 elementor-top-column elementor-element elementor-element-e4f110b" data-id="e4f110b" data-element_type="column"> <div class="elementor-widget-wrap elementor-element-populated"> <div class="elementor-element elementor-element-4a914653 elementor-widget elementor-widget-heading" data-id="4a914653" data-element_type="widget" data-widget_type="heading.default"> <div class="elementor-widget-container"> <p class="elementor-heading-title elementor-size-default">©2023 Copyright DevX - All Rights Reserved. Registration or use of this site constitutes acceptance of our Terms of Service and Privacy Policy.</p> </div> </div> <div class="elementor-element elementor-element-d2cf216 elementor-widget elementor-widget-text-editor" data-id="d2cf216" data-element_type="widget" data-widget_type="text-editor.default"> <div class="elementor-widget-container"> <style>/*! elementor - v3.12.2 - 23-04-2023 */ .elementor-widget-text-editor.elementor-drop-cap-view-stacked .elementor-drop-cap{background-color:#69727d;color:#fff}.elementor-widget-text-editor.elementor-drop-cap-view-framed .elementor-drop-cap{color:#69727d;border:3px solid;background-color:transparent}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap{margin-top:8px}.elementor-widget-text-editor:not(.elementor-drop-cap-view-default) .elementor-drop-cap-letter{width:1em;height:1em}.elementor-widget-text-editor .elementor-drop-cap{float:left;text-align:center;line-height:1;font-size:50px}.elementor-widget-text-editor .elementor-drop-cap-letter{display:inline-block}</style> <p><strong><a href="https://www.devx.com/sitemap/">Sitemap</a></strong></p> </div> </div> </div> </div> </div> </section> </footer> <link rel='stylesheet' id='elementor-icons-fa-regular-css' href='https://www.devx.com/wp-content/plugins/elementor/assets/lib/font-awesome/css/regular.min.css?ver=5.15.3' type='text/css' media='all' /> <link rel='stylesheet' id='e-animations-css' href='https://www.devx.com/wp-content/plugins/elementor/assets/lib/animations/animations.min.css?ver=3.12.2' type='text/css' media='all' /> <script type='text/javascript' src='https://www.devx.com/wp-content/themes/devxnew/assets/js/hello-frontend.min.js?ver=1.0.0' id='hello-theme-frontend-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor-pro/assets/lib/smartmenus/jquery.smartmenus.min.js?ver=1.0.1' id='smartmenus-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-includes/js/imagesloaded.min.js?ver=4.1.4' id='imagesloaded-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor-pro/assets/js/webpack-pro.runtime.min.js?ver=3.12.3' id='elementor-pro-webpack-runtime-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor/assets/js/webpack.runtime.min.js?ver=3.12.2' id='elementor-webpack-runtime-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor/assets/js/frontend-modules.min.js?ver=3.12.2' id='elementor-frontend-modules-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-includes/js/dist/vendor/wp-polyfill-inert.min.js?ver=3.1.2' id='wp-polyfill-inert-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-includes/js/dist/vendor/regenerator-runtime.min.js?ver=0.13.11' id='regenerator-runtime-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-includes/js/dist/vendor/wp-polyfill.min.js?ver=3.15.0' id='wp-polyfill-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-includes/js/dist/hooks.min.js?ver=4169d3cf8e8d95a3d6d5' id='wp-hooks-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-includes/js/dist/i18n.min.js?ver=9e794f35a71bb98672ae' id='wp-i18n-js'></script> <script type='text/javascript' id='wp-i18n-js-after'> wp.i18n.setLocaleData( { 'text direction\u0004ltr': [ 'ltr' ] } ); </script> <script type='text/javascript' id='elementor-pro-frontend-js-before'> var ElementorProFrontendConfig = {"ajaxurl":"https:\/\/www.devx.com\/wp-admin\/admin-ajax.php","nonce":"cf90036b3f","urls":{"assets":"https:\/\/www.devx.com\/wp-content\/plugins\/elementor-pro\/assets\/","rest":"https:\/\/www.devx.com\/wp-json\/"},"shareButtonsNetworks":{"facebook":{"title":"Facebook","has_counter":true},"twitter":{"title":"Twitter"},"linkedin":{"title":"LinkedIn","has_counter":true},"pinterest":{"title":"Pinterest","has_counter":true},"reddit":{"title":"Reddit","has_counter":true},"vk":{"title":"VK","has_counter":true},"odnoklassniki":{"title":"OK","has_counter":true},"tumblr":{"title":"Tumblr"},"digg":{"title":"Digg"},"skype":{"title":"Skype"},"stumbleupon":{"title":"StumbleUpon","has_counter":true},"mix":{"title":"Mix"},"telegram":{"title":"Telegram"},"pocket":{"title":"Pocket","has_counter":true},"xing":{"title":"XING","has_counter":true},"whatsapp":{"title":"WhatsApp"},"email":{"title":"Email"},"print":{"title":"Print"}},"facebook_sdk":{"lang":"en_US","app_id":""},"lottie":{"defaultAnimationUrl":"https:\/\/www.devx.com\/wp-content\/plugins\/elementor-pro\/modules\/lottie\/assets\/animations\/default.json"}}; </script> <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor-pro/assets/js/frontend.min.js?ver=3.12.3' id='elementor-pro-frontend-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor/assets/lib/waypoints/waypoints.min.js?ver=4.0.2' id='elementor-waypoints-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-includes/js/jquery/ui/core.min.js?ver=1.13.2' id='jquery-ui-core-js'></script> <script type='text/javascript' id='elementor-frontend-js-before'> var elementorFrontendConfig = {"environmentMode":{"edit":false,"wpPreview":false,"isScriptDebug":false},"i18n":{"shareOnFacebook":"Share on Facebook","shareOnTwitter":"Share on Twitter","pinIt":"Pin it","download":"Download","downloadImage":"Download image","fullscreen":"Fullscreen","zoom":"Zoom","share":"Share","playVideo":"Play Video","previous":"Previous","next":"Next","close":"Close"},"is_rtl":false,"breakpoints":{"xs":0,"sm":480,"md":768,"lg":1025,"xl":1440,"xxl":1600},"responsive":{"breakpoints":{"mobile":{"label":"Mobile Portrait","value":767,"default_value":767,"direction":"max","is_enabled":true},"mobile_extra":{"label":"Mobile Landscape","value":880,"default_value":880,"direction":"max","is_enabled":false},"tablet":{"label":"Tablet Portrait","value":1024,"default_value":1024,"direction":"max","is_enabled":true},"tablet_extra":{"label":"Tablet Landscape","value":1200,"default_value":1200,"direction":"max","is_enabled":false},"laptop":{"label":"Laptop","value":1366,"default_value":1366,"direction":"max","is_enabled":false},"widescreen":{"label":"Widescreen","value":2400,"default_value":2400,"direction":"min","is_enabled":false}}},"version":"3.12.2","is_static":false,"experimentalFeatures":{"e_dom_optimization":true,"e_optimized_assets_loading":true,"e_optimized_css_loading":true,"a11y_improvements":true,"additional_custom_breakpoints":true,"theme_builder_v2":true,"hello-theme-header-footer":true,"landing-pages":true,"page-transitions":true,"notes":true,"loop":true,"form-submissions":true,"e_scroll_snap":true},"urls":{"assets":"https:\/\/www.devx.com\/wp-content\/plugins\/elementor\/assets\/"},"swiperClass":"swiper-container","settings":{"page":[],"editorPreferences":[]},"kit":{"body_background_background":"classic","active_breakpoints":["viewport_mobile","viewport_tablet"],"global_image_lightbox":"yes","lightbox_enable_counter":"yes","lightbox_enable_fullscreen":"yes","lightbox_enable_zoom":"yes","lightbox_enable_share":"yes","lightbox_title_src":"title","lightbox_description_src":"description","hello_header_logo_type":"logo","hello_header_menu_layout":"horizontal","hello_footer_logo_type":"logo"},"post":{"id":11031,"title":"Getting%20Fancy%20with%20FOP%20-%20DevX","excerpt":"","featuredImage":"https:\/\/www.devx.com\/wp-content\/uploads\/2022\/02\/thumbnail.jpg"}}; </script> <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor/assets/js/frontend.min.js?ver=3.12.2' id='elementor-frontend-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor-pro/assets/js/elements-handlers.min.js?ver=3.12.3' id='pro-elements-handlers-js'></script> <script type='text/javascript' src='https://www.devx.com/wp-content/plugins/elementor-pro/assets/lib/sticky/jquery.sticky.min.js?ver=3.12.3' id='e-sticky-js'></script> </body> </html> <!-- Dynamic page generated in 1.458 seconds. --> <!-- Cached page generated by WP-Super-Cache on 2023-05-30 13:34:38 --> <!-- Compression = gzip -->