Giter Club home page Giter Club logo

simpla's Introduction

Simpla

Test status Size (gzip) NPM version PRs welcome

Simpla is a modular content system for frontend developers, built on Web Components.

At a glance, it lets you:

  • Build with standard HTML & JS
  • Edit content (safely) inline
  • Use Github as your backend
  • Work in any stack or framework
  • Push everything as JSON data to a static CDN
  • Define content models in the DOM
  • Assemble your own lightweight CMS

It looks like this:

<!-- Block of editable richtext -->
<simpla-text path="/text"></simpla-text>

<!-- An editable image -->
<img is="simpla-img" path="/img">

<!-- Dynamic collection -->
<simpla-collection path="/gallery" as="photo">
  <template>
    <img is="simpla-img" path="/gallery/[photo]/img">
    <simpla-text path="/gallery/[photo]/caption"></simpla-text>
  </template>
</simpla-collection>

<!-- And many more components -->

Demo of Simpla

Installation

Simpla is available on NPM and Unpkg as simpla.

npm i simpla

Import the core library and an OAuth adapter, and call Simpla.init

// Import Simpla and OAuth adapter
import Simpla from 'simpla';
import SimplaNetlify from 'simpla/adapters/netlify';

// Init Simpla
Simpla.init({

  // Github repo to store content in
  repo: 'username/repo',

  // Adapter to authenticate users with Github
  auth: new SimplaNetlify({ site: 'mysite' }),

  // Public URL of your content (optional)
  source: 'https://mysite.netlify.com'

});

// Add Simpla to window global for components to access
window.Simpla = Simpla;

Simpla and its adapters export UMD modules, so you can also link to them with <script> tags and use the globals directly.

Simpla uses web components to manage content, the library itself is just a tiny (~4kb) core to an expansive ecosystem. Install and add components to your page with Bower and HTML imports (NPM/JS support coming soon). You can find components in the elements catalogue.

$ bower i simpla-text simpla-img simpla-admin --save
<link rel="import" href="/bower_components/simpla-text/simpla-text.html">
<link rel="import" href="/bower_components/simpla-img/simpla-img.html">
<link rel="import" href="/bower_components/simpla-admin/simpla-admin.html" async>

You should also include a web components polyfill for full cross-browser support (see the browsers Simpla supports).

<script src="https://unpkg.com/webcomponents.js@^0.7.24/webcomponents-lite.min.js" async></script>

See full documentation & API references

Contributing

There are lots of ways you can help push the Simpla project forward:

  • Reporting bugs. If you find a bug please report it! Open an issue against this repository for problems with the core library. For problems with elements, open an issue against the element's repository.

  • Submitting Pull Requests. We ❤️ PRs! Your PR should address an existing issue or have been discussed previously to ensure it gets merged.

  • Publishing new components Simpla is a community driven project, and the best way you can contribute is to build your own content components. The ecosystem is built on Web Components, but there's no reason you couldn't use Simpla in a component environment of your choice (React, etc).

Read the Contributing guidelines for more information.


MIT © 2017

simpla's People

Contributors

bedeoverend avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

simpla's Issues

Entering into placeholder and deleting all disables editing on that element

I can't tell if this is a new issue. This is the first time I've noticed it happening.

Using the sample template (on latest Chrome), when I enter text then delete the text in an element, I can't re-enter text into that same element. Placeholder text shows up but editing becomes disabled. The blinking cursor appears for a split second before disappearing. Saving also no longer works. Refreshing does not return elements to their original functional state. Only solution seems to log out and back in. No error logs in the console as far as I can tell!

Multi-user support

Now I just need to be able to setup a login (for a project) that is not my master login, so that content creators can create content, and I don't have to worry about them logging into my dashboard.

Make multiple build targets e.g. w/o Polyfills

Simpla shouldn't come with browser polyfills bundled. Right now, it will automatically check and only bring in the polyfills if needed, but users may want to use a different polyfill, or may be importing their own polyfills that may just not have loaded in time. This is weighed up against the speed of install - having a one line script import will be incredibly useful for a lot of users. The best solution is therefore having multiple build targets that users can boot Simpla with, one including polyfills, the other not.

Warn when offline

Simpla should show a warning banner when a user is in edit mode and have dropped their connection, and not allow them to try and save until they’re back online.

Can do this by either listening to online/offline window events, or using the network info API

// Online/offline events.
window.addEventListener('online', e => {
  console.assert(navigator.onLine)
});

window.addEventListener('offline', e => {
  console.assert(!navigator.onLine)
});

// Network Information API
navigator.connection.addEventListener('change', e => {
  console.log(navigator.connection.type,
              navigator.connection.downlinkMax);
});

Create ES module build

Currently the module field on package.json points to src/simpla.js but really it should point to a separate build, that's been transpiled, but not bundled. This means that whatever module bundling system consumers are using will still be used, but it won't need to be transpiled. As it currently stands, users can come up against this bug but more generally it'll require them to transpile our source, not just bundle it.

An interim measure would be to change where module points to - just the transpiled, bundled simpla.js in root. The main reason behind giving users an ES module target is so they can tree shake, but as we only have one default export, Simpla, this is pretty redundant.

Element imports shouldn't default to async

Currently Simpla imports its elements with the async, which makes their requests non-blocking. This is incorrect behaviour, and worsens the FOUC you get when Simpla's content 'pops' into place. They should instead default to be blocking, like styles and scripts in the head are, and if a user wants to have them async and handle the FOUC themselves, then they can import manually.

This also becomes redundant once #35 is shipped, as we'll be stripping out auto-imports (it will just become a matter of what we document as the recommended practice).

Document adapter interface

I'm submitting a

Feature request

Description

Simpla's adapter interfaces aren't currently documented, meaning that nobody can create their own adapters, making them somewhat pointless (especially until we create more bundled adapters ourselves).

Prereqs

Don't vulcanize components?

If we can leave our components unvulcanized we'd cut back a lot of complexity - it would mean our whole buildstep will just be a single process task, we wouldn't need to worry about shared element duplication, relative paths, etc.

We wouldn't see a perf hit if we then use HTTP2/SPDY. If anything, our components will become more performant because we'll be able to import shared elements only when needed, rather than lumping them all into one request. HTTP2 with a SPDY fallback covers almost all our target browsers, with IE10 being the exception (current usage 0.92%), which I think is acceptable.

The only problem I foresee is if the user wants to pull down the components and self-host on their own server for whatever reason. Then, if they're not using HTTP2 (which is a reasonable assumption), they'll see a massive perf hit. One possible fix is creating an optional buildstep that vulcanises everything. But that's really adding back all the complexity we want to get rid of...

Ensure imported polyfills are minified

Seems some of the polyfills that Simpla depends on aren't being minified (eg: promise-polyfill/Promise.js). Ensure we're pulling minified versions, or minify it ourselves in a buildstep.

Decouple edit mode from #edit

Right now the only way to make Simpla editable is to use #edit in the URL. This is both fragile (eg: SPAs that use hash nav, see #10) and needlessly opinionated. We should have a mechanism for disabling hash tracking, and a programatic way for developers to make Simpla editable.

Options for decoupling hashtracking:

  • Option in initialiser (hashtracking: false)
  • Move hashtracking plugin to custom element that is imported by default, which users can elect not to import.

Depends how 'core' we think #edit is.

<simpla-text> inside <a> tags

This comment is quite similar to @fracz about hashes urls, but a little more worrying because is not possible to edit "simpla-text" tags that are inside "a href=""..." of any kind...
Simply editing mode is lost trying to follow the link when you try to edit the text.

Otherwise I think it's very good tool and I will keep an eye on it ;)

Add revision history and draft support API

I'm submitting a

Feature request

Description

Now that Simpla uses Github as a backend, we have full version control baked in. We should create a JS API for navigating and restoring a past revision.

We should also create an API for saving as a draft, rather than publishing straight to master. Under the hood this would just create a branch and open a PR on the underlying repo.

Notes

  • #77 could impact this, as you wouldn't be tightly coupled to Github anymore. The adapter would need to specify whether it supports revisions and drafts or not, and give the appropriate hooks

  • This will also need UI in simpla-admin, but that can come later as a seperate issue

Simpla SDK v2 interface

Simpla's SDK currently has some MVP work around internal states built. We need to finalise this interface, document it, and make it public. We also need to settle on a new data schema that is easier to reason about.

What we have so far:

  • State properties 'editable': Boolean (whether Simpla is in edit mode), authenticated: Boolean (whether the Simpla client has a logged in user).
  • State getter getState(state: String) : Multiple
  • State observer observeState(state: String, callback: Function) : Function

What we need to finalise

  • We want to implement a 'data': Object state which would hold the entire set of Simpla data on a page, to make reasoning about content both at an element level and for project developers much easier. Need to finalise how this works - is it primary (CRUD methods operate only on the buffer, then save() sets back to the API) or secondary (CRUD methods talk directly to the API, and update the buffer on the way through)?
  • The function name for entering/exiting edit mode imperatively (part of: #29)
  • Reimplement get/set/remove methods
  • Add observe() method for observing content changes, makes authoring Simpla elements trivial.
  • Data schema. The current 'anything goes' approach was fine for early development, but we're already running into inconsistencies and dodgy outcomes - eg: getting a block should not return an array, when getting a leaf node returns an object. All UIDs should have standardised metadata.

Styling Images and content in general.

Just starting to test out simpla by using it with some basic bootstrap templates.
There are issues with content not loading css properties. I think part of this has to do with the content being out of scope and contained within the shadow root...

Are there any scss mixins or shouldn't there be, for say:

simpla-img# > .editor  > sm-img-canvas > img#source{
 //style the image
}

The problem right now with adding a class to simpla-img is that some styles are not applied correctly however, this could seemingly be less of a problem with a mixin like:

.this {
  @include simpla(img-container) { 
      width: 100%; 
   }
  @include simpla(img) { 
      border-radius: 50%;
   }
}

or in the compiled css:

.this simpla-img::shadow  > .editor {
      width: 100%; 
}

.this simpla-img::shadow  > .editor  > sm-img-canvas::shadow  > img#source{
       border-radius: 50%;
}

Here is an example:

[v2] Build to dist folder?

Marginally related to #63, should Simpla build transpiled/bundled files to dist/ rather than the root of the project? Purely a code organisation thing. Little cleaner, but would make linking in js file from the likes of Unpkg (which is the most common use-case, since that's what our snippet on simpla.io docs does) unnecessarily verbose.

Cannot use edit on a website that already uses hashes urls

I am trying to integrate simpla with Vaadin. It uses hashes in URLs to recognize pages, for example http://website.com/#!contact.

I have placed <simpla-text> there. I tried going to http://website.com/#edit or http://website.com/#!contact#edit and the simpla login form appearead correctly. However, Vaadin shows 404 error page for these URLs. When I go back to http://website.com/#!contact, I can not edit the contents.

IMHO, once I have authenticated in simpla by going to the #edit, there should be a button on every page that enables its editing without changing URL of the application.

Check if project ID belongs to user on login

Right now we don't check the project ID that Simpla() was initialised with when the user logs in. There's no security concern here (they still can't do anything if they don't own the project), but there are UX ramifications:

  • You can login (again, inertly) to projects you do not own
  • Simpla doesn't know if the project key is valid until the user tries to save something and it blows up in their face (see #15)

There is no valid use case for logging in with the Simpla SDK that has an invalid project key.

Replace API authentication with Auth0 SDK

Auth0 (our authentication backend provider) has released a clientside JS SDK. We should replace our abstracted auth methods in the Simpla SDK with theirs, so we don't touch authentication at all (less links to break).

To achieve this we can just bundle the Auth0 SDK with Simpla as a dependency, and remove the authentication endpoints on our own API.

This will also allow us to (very) easily implement social sign-on on both the Simpla platform and SDK.

Support prerendering

From #24

Publish an NPM module that bundles SDK to render content into Simpla elements, to be used in a build step.

In future, add support for simpla-paths by bundling in that tree walking logic for sid and gid properties.

Implicitly created hierarchies should hydrate from API

Scenario

Calling Simpla.set('foo.bar.baz', { ... }), before having calling set / get on either ancestor foo or foo.bar, may result in incorrect data being stored in the buffer for foo and foo.bar - meaning that calling Simpla.get on either may return incorrect data.

Expected behaviour

Calling Simpla.get('foo.bar') will always respond with the data previously saved and stored remotely, or, data that's been explicitly set locally via Simpla.set('foo.bar')

Actual behaviour

Simpla.get('foo.bar') may return blank data, even though data has been set to the API.

Analysis

Calling Simpla.set('foo.bar.baz', { ... }) will cause the SDK to ensure that foo and foo.bar exist in the buffer, even if just blank - to replicate the functionality of the remote API. Instead, if it doesn't exist in the buffer, it should check if it doesn't exist in the remote API, then should set blank data iff it doesn't exist there.

Fix creating implicit files

I'm submitting a

Bug report

Description

In v2, creating an object /foo/bar/baz would ensure /foo and /bar existed as empty objects (i.e. type null and data an empty object). In v3 this has been lost and needs to be restored, this means storage should create /foo.json and /foo/bar.json when creating /foo/bar

Move from Promises to Observables

Simpla currently uses promises and observer methods to react to data, eg:

Simpla.get('/foo').then(...);
Simpla.observe('/foo', () => { ... });

This has a few problems:

  • Duped logic between a one-time reaction (promise) and continued reactions (observer), when really these are the same thing

  • Handshake issues when both getting and observing a path while it's in transit and filling the buffer

  • Growing number of observer methods that all do the same thing to different pieces of data (observe, observeState, observeQuery once we reimplement indexes)

Instead, Simpla should return ES6 observables, using a library like RxJS or zen-observable.

The new API would look something like this

// Get data
Simpla.get('/foo')
  .subscribe(..., { once: true });

// Observe data changes
let foo = Simpla.get('/foo')
  .subscribe(...);

// Stop an observer
foo.unsubscribe();

Add prefetch method

Add a method to Simpla that mirrors what <link rel="prefetch" href="..."> does (ie: fetch resources you will likely need in future, lazily in idle cycle), but for our JSON data. This would be really useful for optimising performance of dynamic collections of content: eg - documentation on Simpla.io (where the idea came from).

Implementation would just be (very) light sugar around requestIdleCallback:

function prefetch(resource) {
  if (!window.requestIdleCallback) {
    return;
  }

  requestIdleCallback(() => {
    switch (typeof resource) {
    case 'string':
      Simpla.get(resource);
      break;
    case 'object':
      Simpla.query(resource);
      break
    default: 
      throw new Error('Invalid resource, can only prefetch paths or query objects');
    }
  }
}

Then future gets and queries (which the user would actually use/observe) would just read straight from buffer and be instant.

Would only work in Chrome and Firefox currently (http://caniuse.com/#feat=requestidlecallback), but it's progressive enhancement so I don't think that matters. Just document it as such. There is a shim with setTimeout, but I it defeats the purpose of this (people can just call Simpla.get in advance if they don't care about idle cycles), should this method just be pure prog enhancements for browsers that can handle it, like prefetch is.

Migrate all components to Babel 6 + Rollup, and refactor gulpfile

Rather than make the same issue on all our component repos, just thought I'd make a meta one here.

We should ditch Webpack and use Rollup as our bundler. Only headache here will be simpla-text, which relies on Scribe, which is AMD. Will need to either find our bake our own AMD -> CommonJS buildstep (which Rollup supports).

Also move everything to Babel 6.

Then we can refactor our gulpfiles, which are pretty horrid.

Rework edit mode (vs. authenticated)

There should be a distinction between authenticated and currently editing a page.

Thoughts:

  • If authenticated, show ‘edit this page’ button on site
  • Edit mode should have quick toggle to exit, but what happens to changes? Still show ‘save’ button somewhere?
  • Disable pointer events in edit mode, but not when just authenticated. Then if want to click link, exit edit mode (fixes #26)
  • #edit flow remains the same - If not authed #edit triggers login modal then enters edit mode on success. If authed, #edit enters edit mode on the current page.

Move storage to adapter

I'm submitting a

Feature request

Description

Right now Simpla is tightly coupled to using Github as a backend. Instead, we should split both Auth and Storage into adapters. Under this setup the auth adapter would handle everything to do with user management, rather than just authenticating an access token with github, and the storage adapter would just check with the auth adapter whether a change can be written, and then go ahead and write that change to where it's configured to.

Public API would stay relatively unchanged

Simpla.init({
  storage: new SimplaGithub({ repo: 'username/repo' }),
  auth: new SimplaNetlify({ site: 'mysite' }),
  ...
});

Search engine visibility

Simpla looks amazing, but from what I gather, content is injected into the page via JS so it would not be visible to web crawlers. Do you guys have a solution for this? Would you have to do the usual hash fragment trick?

Srcset, sizes, and/or the picture element

It would really help with responsive images if we could take advantage of srcset, sizes, and/or the picture element.

It's great that I can build a site essentially anyway I want and then hand it off to a client and they can edit it with virtually no training.

However, I can't seem to figure out a way that I could still have responsive image files using picturefill while using simpla.

That's something I'd REALLY like to be able to do!

Migrate to WC v1, JS, and NPM

The Simpla ecosystem is currently built on v0 of the Web Components specs (and Polymer 1). We should upgrade all elements to WC v1 specs, which will allow us to:

  • Make Simpla compatible with Polymer 2 projects
  • Strip Polymer from render bundles and use the raw browser APIs, greatly improving first-paint performance
  • Server side render content, using skatejs/ssr, fixing #66
  • Document element authorship, and make a generalised ES6 mixin to make building elements with any framework easy peasy
  • Finally move to ES6 modules and NPM

Prereqs

  • Port simpla-element-behavior to ES6 mixin

Elements

  • simpla-text
  • simpla-img
  • simpla-article
  • simpla-video
  • simpla-admin
  • simpla-link
  • simpla-collection
  • simpla-notify
  • simpla-markdown

Misc

  • Update docs (snippets, build step for IE, etc)
  • Publish elements to NPM, issue deprecation for bower, and manage in monorepo

Notes

  • Elements will be shipped as ES6 classes (see discussion below), which means a) we can strip out buildsteps and boilerplate in elements themselves but b) IE support will need a buildstep from the user

  • Ideally the render bundles of all elements should not need to pull in Polymer, to keep initial upgrade and render as performant as possible

  • Simpla-img will need to be turned into a wrapper element, since is="" type extension is hard deprecated in v1 🙃

  • Since the element behavior is now an ES6 mixin, it should be renamed and no longer rely on Polymer, but just hook up generic web component classes to Simlpla

  • The richtext behavior used by simpla-text and simpla-article should probably be split off into a generalised JS module, since it's not actually tied to Simpla in any way

Remove auto element imports

Right now Simpla handles the importing of elements, which can be configured on initialisation with elements: {}.

The thinking behind this was it would make Simpla very easy to get started with - just call Simpla() and go, with some sane defaults for included elements. The tradeoffs in flexibility seemed reasonable.

They are not. We shouldn't do this. It makes Simpla more opaque, more opinionated, less flexible, and hurts the growth of our ecosystem, for very little benefit. It should be up to the user to import elements themselves. We can still make getting up and running a one-click affair, by just including a few sane element imports in the setup snippet provided on simpla.io.

This will be a breaking change, but well worth it as we look to grow the Simpla ecosystem.

Investigate making Simpla AMP compliant

Not sure if it's possible/desirable for Simpla to be AMP compliant, since by definition loading content is render-blocking. But definitely worth investigating if we can at least be technically compliant, perhaps by init option.

[v2] Removing parent UID should remove child paths

Scenario

UID foo.bar.baz exists
Simpla.remove('foo.bar') called

Expected outcome

The foo.bar path is removed. That is, foo.bar and all of its children are removed.

Actual outcome

Only the specific identifier foo.bar is removed, so foo and foo.bar.baz exist, but foo.bar does not.

This will also play into the move from UIDs -> paths, but I imagine is a separate issue in terms of implementation.

Can I use simpla with this Elm like library?

Hello,

Escher is an elm like library for Julia that allows the creation of composable reactive web apps without using HTML/CSS, though it can express the full breadth of the latter.

It can wrap arbitrary web elements... would it be possible to use simpla with this?

[v2] Deprecations

Few things we should hard deprecate before shipping:

  • hideDefaultContent() (default-content hard deprecated in v2)

  • hashTracking (moved to simpla-admin)

  • webcomponents.js import - too fragile, include as bower/npm dep and tell users to include separately (or from cdnjs if we keep app.simpla.io CDN)

  • Slim down usageMonitoring and rename to ping or similar - should literally be a 200 okay from the SDK, no need for sessions or elements?

  • Use Babel plugins over core-js polyfills? Nicer to have it as part of our transform, rather than separate deps. Also often lighter than polyfills

  • Can we move the deprecatedConfig to v2-compat layer since it's just for elements?

get() should use no-cors mode

Fetches made with Simpla.get() should use no-cors mode, which skips preflight header checks (which we don't need). Significantly increased network perf.


Current setup:

  • Average total time for 500 requests: 4062.3ms
  • Average time per request: 8.1ms

Using no-cors mode:

  • Average total time for 500 requests: 837.3ms
  • Average time per request: 1.7ms

Note: Until all elements are migrated to using the SDK then this won't have effect.

[v2] Invalid paths should warn not throw

Invalid paths (eg: //some/path) currently throw errors. They should console warn and bail out of the request instead. You would expect a dodgy request to just not work, rather than blow your stack.

Thoughts @bedeoverend? Could argue it's up to component authors and SDK consumers to validate their inputs, but again I think that we're overreacting in terms of consequences atm.

Ability to run simpla on own server

I'm sure there are some projects that would greatly benefit from your idea, but they won't because of security issues or the fact that they work in LAN environment. Sometimes we just can't allow storing the data somewhere in the world.

I don't know how this relates to your idea but in my opinion there should be an option to install a simpla server locally and use it instead of public service. Just like the https://prerender.io/ - you can use it as is or install the prerender server locally.

Add querying support

I'm submitting a

Feature request

Description

When we moved to Simpla OSS we lost querying support (ie: the find method). We need to reimplement this functionality, using static indexes. The user will be able to define an array of indexes to build on Simpla.init, then fetch and query those indexes at any point later.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.