Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(examples): Add 'Sitefinity CMS' Example #39537

Merged
merged 25 commits into from Oct 1, 2022
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
ab15ad6
wip
Gebov Aug 12, 2022
80637e2
update readme
Gebov Aug 12, 2022
98c5225
linting
Gebov Aug 12, 2022
c6e49ff
Merge branch 'canary' into gebov/sitefinity
Gebov Aug 12, 2022
3933afa
Merge branch 'canary' into gebov/sitefinity
Gebov Aug 12, 2022
e2559af
remove variable
Gebov Aug 12, 2022
28df570
Merge branch 'canary' into gebov/sitefinity
Gebov Aug 15, 2022
fa12fbb
Merge branch 'canary' into gebov/sitefinity
Gebov Aug 19, 2022
cb0b0da
Merge branch 'canary' into gebov/sitefinity
Gebov Aug 22, 2022
bf73f79
Merge branch 'canary' into gebov/sitefinity
Gebov Aug 26, 2022
ff8daed
Update examples/cms-sitefinity/package.json
Gebov Sep 30, 2022
f007de4
replace urls for blog
Gebov Sep 30, 2022
221f544
Merge branch 'canary' into gebov/sitefinity
Gebov Sep 30, 2022
54fb74c
Delete _document.tsx
balazsorban44 Sep 30, 2022
eebf6ae
Delete .editorconfig
balazsorban44 Sep 30, 2022
65c72bd
Delete launch.json
balazsorban44 Sep 30, 2022
7a32899
Apply suggestions from code review
balazsorban44 Sep 30, 2022
20046a8
Merge branch 'canary' into gebov/sitefinity
Gebov Sep 30, 2022
3d7316d
Merge branch 'canary' into gebov/sitefinity
balazsorban44 Sep 30, 2022
51a2d99
Update package.json
balazsorban44 Oct 1, 2022
0745e14
fix lint issues
balazsorban44 Oct 1, 2022
bfb2b41
Merge branch 'gebov/sitefinity' of github.com:Gebov/next.js into gebo…
balazsorban44 Oct 1, 2022
96a3ac8
Merge branch 'canary' into gebov/sitefinity
balazsorban44 Oct 1, 2022
f51ac39
fix lint
Gebov Oct 1, 2022
7ef531e
Merge branch 'canary' into gebov/sitefinity
Gebov Oct 1, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions examples/cms-sitefinity/.env.local.example
@@ -0,0 +1,2 @@
SF_API_URL=
SF_URL=
36 changes: 36 additions & 0 deletions examples/cms-sitefinity/.gitignore
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
103 changes: 103 additions & 0 deletions examples/cms-sitefinity/README.md
@@ -0,0 +1,103 @@
# A statically generated blog example using Next.js and Sitefinity CMS

This is the existing [cms-sitefinity](https://github.com/vercel/next.js/tree/canary/examples/cms-sitefinity) plus TypeScript.
This example showcases [Next.js's Static Generation feature](https://nextjs.org/docs/basic-features/pages) using Sitefinity CMS as the data source.

## Demo

[https://next-cms-sitefinity.vercel.app/](https://next-cms-sitefinity.vercel.app/)

## Deploy your own

Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/cms-sitefinity)

[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/cms-sitefinity&project-name=cms-sitefinity&repository-name=cms-sitefinity)

### Related examples

- [WordPress](/examples/cms-wordpress)
- [DatoCMS](/examples/cms-datocms)
- [Sanity](/examples/cms-sanity)
- [TakeShape](/examples/cms-takeshape)
- [Prismic](/examples/cms-prismic)
- [Contentful](/examples/cms-contentful)
- [Strapi](/examples/cms-strapi)
- [Agility CMS](/examples/cms-agilitycms)
- [Cosmic](/examples/cms-cosmic)
- [ButterCMS](/examples/cms-buttercms)
- [Storyblok](/examples/cms-storyblok)
- [GraphCMS](/examples/cms-graphcms)
- [Kontent](/examples/cms-kontent)
- [Umbraco Heartcore](/examples/cms-umbraco-heartcore)
- [Builder.io](/examples/cms-builder-io)
- [TinaCMS](/examples/cms-tina/)

## How to use

Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example:

```bash
npx create-next-app --example cms-sitefinity cms-sitefinity-app
```

```bash
yarn create next-app --example cms-sitefinity cms-sitefinity-app
```

```bash
pnpm create next-app --example cms-sitefinity cms-sitefinity-app
```

## Configuration

### Step 1. Setup the CMS locally (version >=14.27922)

First, [install](https://www.progress.com/documentation/sitefinity-cms/install-sitefinity) and run the CMS Locally.

### Step 2. Import the ready to use dynamic module 'Posts'

For the purpose of this demo a ready to use dynamic module was build containing two types - 'Post' and 'Author'.

In order to install it:

1. Open the CMS Administration under (/Sitefinity)
2. Open the Export/Import screen under (/Sitefinity/Administration/Packaging)
3. Click on Import Zip file and import the file from the [sitefinity folder](./sitefinity/SitefinityExport.zip)

### Step 3. Enable the web service

By default the web services are not allowed for anonymous users, so the yhave to be enabled.

Go to /sitefinity/Administration/WebServices and edit the 'Default' web service to allow it to be accessible by 'Everyone'

### Step 4. Install the GraphQL package

1. Add the [Sitefinity CMS nugget source](https://www.progress.com/documentation/sitefinity-cms/sitefinity-cms-nuget-packages-repository)
2. Install the [Progress.Sitefinity.GraphQL](https://nuget.sitefinity.com/#/package/Progress.Sitefinity.GraphQL) package (enable prerelease filter).

### Step 5. Set up environment variables

Copy the `.env.local.example` file in this directory to `.env.local` (which will be ignored by Git):

```bash
cp .env.local.example .env.local
```

Then set each variable on `.env.local`

- `SF_API_URL` - This is the url of the 'Default' web service that we configured earlier. E.g. http://locahost/api/default/
- `SF_URL` - This is the URL of the CMS itself. E.g. http://localhost/

### Step 6. Run Next.js in development mode

```bash
npm install
npm run dev

# or

yarn
yarn dev
```

Your blog should be up and running on [http://localhost:3000](http://localhost:3000)! If it doesn't work, post on [GitHub discussions](https://github.com/vercel/next.js/discussions).
48 changes: 48 additions & 0 deletions examples/cms-sitefinity/components/alert.tsx
@@ -0,0 +1,48 @@
import Container from './container'
import cn from 'classnames'
import { EXAMPLE_PATH } from '../lib/constants'

type Props = {
preview?: boolean
}

const Alert = ({ preview }: Props) => {
return (
<div
className={cn('border-b', {
'bg-neutral-800 border-neutral-800 text-white': preview,
'bg-neutral-50 border-neutral-200': !preview,
})}
>
<Container>
<div className="py-2 text-center text-sm">
{preview ? (
<>
This page is a preview.{' '}
<a
href="/api/exit-preview"
className="underline hover:text-teal-300 duration-200 transition-colors"
>
Click here
</a>{' '}
to exit preview mode.
</>
) : (
<>
The source code for this blog is{' '}
<a
href={`https://github.com/vercel/next.js/tree/canary/examples/${EXAMPLE_PATH}`}
className="underline hover:text-blue-600 duration-200 transition-colors"
>
available on GitHub
</a>
.
</>
)}
</div>
</Container>
</div>
)
}

export default Alert
19 changes: 19 additions & 0 deletions examples/cms-sitefinity/components/avatar.tsx
@@ -0,0 +1,19 @@
type Props = {
name: string
picture: string
}

const Avatar = ({ name, picture }: Props) => {
return (
<div className="flex items-center">
<img
src={picture}
className="w-12 h-12 rounded-full mr-4"
alt={name}
/>
<div className="text-xl font-bold">{name}</div>
</div>
)
}

export default Avatar
9 changes: 9 additions & 0 deletions examples/cms-sitefinity/components/container.tsx
@@ -0,0 +1,9 @@
type Props = {
children?: React.ReactNode
}

const Container = ({ children }: Props) => {
return <div className="container mx-auto px-5">{children}</div>
}

export default Container
33 changes: 33 additions & 0 deletions examples/cms-sitefinity/components/cover-image.tsx
@@ -0,0 +1,33 @@
import cn from 'classnames'
import Link from 'next/link'

type Props = {
title: string
src: string
slug?: string
}

const CoverImage = ({ title, src, slug }: Props) => {
const image = (
<img
src={src}
alt={`Cover Image for ${title}`}
className={cn('shadow-sm', {
'hover:shadow-lg transition-shadow duration-200': slug,
})}
/>
)
return (
<div className="sm:mx-0">
{slug ? (
<Link as={`/posts${slug}`} href="/posts[slug]">
<a aria-label={title}>{image}</a>
</Link>
) : (
image
)}
</div>
)
}

export default CoverImage
12 changes: 12 additions & 0 deletions examples/cms-sitefinity/components/date-formatter.tsx
@@ -0,0 +1,12 @@
import { parseISO, format } from 'date-fns'

type Props = {
dateString: string
}

const DateFormatter = ({ dateString }: Props) => {
const date = parseISO(dateString)
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>
}

export default DateFormatter
32 changes: 32 additions & 0 deletions examples/cms-sitefinity/components/footer.tsx
@@ -0,0 +1,32 @@
import Container from './container'
import { EXAMPLE_PATH } from '../lib/constants'

const Footer = () => {
return (
<footer className="bg-neutral-50 border-t border-neutral-200">
<Container>
<div className="py-28 flex flex-col lg:flex-row items-center">
<h3 className="text-4xl lg:text-[2.5rem] font-bold tracking-tighter leading-tight text-center lg:text-left mb-10 lg:mb-0 lg:pr-4 lg:w-1/2">
Statically Generated with Next.js.
</h3>
<div className="flex flex-col lg:flex-row justify-center items-center lg:pl-4 lg:w-1/2">
<a
href="https://nextjs.org/docs/basic-features/pages"
className="mx-3 bg-black hover:bg-white hover:text-black border border-black text-white font-bold py-3 px-12 lg:px-8 duration-200 transition-colors mb-6 lg:mb-0"
>
Read Documentation
</a>
<a
href={`https://github.com/vercel/next.js/tree/canary/examples/${EXAMPLE_PATH}`}
className="mx-3 font-bold hover:underline"
>
View on GitHub
</a>
</div>
</div>
</Container>
</footer>
)
}

export default Footer
14 changes: 14 additions & 0 deletions examples/cms-sitefinity/components/header.tsx
@@ -0,0 +1,14 @@
import Link from 'next/link'

const Header = () => {
return (
<h2 className="text-2xl md:text-4xl font-bold tracking-tight md:tracking-tighter leading-tight mb-20 mt-8">
<Link href="/">
<a className="hover:underline">Blog</a>
</Link>
.
</h2>
)
}

export default Header
49 changes: 49 additions & 0 deletions examples/cms-sitefinity/components/hero-post.tsx
@@ -0,0 +1,49 @@
import Avatar from './avatar'
import DateFormatter from './date-formatter'
import CoverImage from './cover-image'
import Link from 'next/link'
import type Author from '../interfaces/author'

type Props = {
title: string
coverImage: string
date: string
excerpt: string
author: Author
slug: string
}

const HeroPost = ({
title,
coverImage,
date,
excerpt,
author,
slug,
}: Props) => {
return (
<section>
<div className="mb-8 md:mb-16">
<CoverImage title={title} src={coverImage} slug={slug} />
</div>
<div className="md:grid md:grid-cols-2 md:gap-x-16 lg:gap-x-8 mb-20 md:mb-28">
<div>
<h3 className="mb-4 text-4xl lg:text-5xl leading-tight">
<Link as={`/posts${slug}`} href="/posts[slug]">
<a className="hover:underline">{title}</a>
</Link>
</h3>
<div className="mb-4 md:mb-0 text-lg">
<DateFormatter dateString={date} />
</div>
</div>
<div>
<p className="text-lg leading-relaxed mb-4">{excerpt}</p>
<Avatar name={author.name} picture={author.picture} />
</div>
</div>
</section>
)
}

export default HeroPost
23 changes: 23 additions & 0 deletions examples/cms-sitefinity/components/intro.tsx
@@ -0,0 +1,23 @@
import { CMS_NAME } from '../lib/constants'

const Intro = () => {
return (
<section className="flex-col md:flex-row flex items-center md:justify-between mt-16 mb-16 md:mb-12">
<h1 className="text-5xl md:text-8xl font-bold tracking-tighter leading-tight md:pr-8">
Blog.
</h1>
<h4 className="text-center md:text-left text-lg mt-5 md:pl-8">
A statically generated blog example using{' '}
<a
href="https://nextjs.org/"
className="underline hover:text-blue-600 duration-200 transition-colors"
>
Next.js
</a>{' '}
and {CMS_NAME}.
</h4>
</section>
)
}

export default Intro