Second post in a small series about building a family games site with AI's help. I'm not a programmer; an AI wrote most of this code with me, and I test everything on a phone. This post was drafted with AI and reviewed by me.
Our site has a free birth chart and a weekly reading for the 12 zodiac signs. Once a week I need posts for the social networks: one text with all 12 signs and 12 images, one per sign, in four languages. Writing that by hand every Monday would kill the project, so we built a small generator into our admin panel. Here is how it works, and where I had to be careful.
Astrology is symbolic, the sky is not
Let me be upfront: the reading is a symbolic one, and the page says so. But the positions it starts from are real. Where the Sun, the Moon, Mercury, Venus and Mars are this week is plain astronomy, and getting that right was the fun part.
We use astronomy-engine (MIT licence), which runs entirely in the browser. No server, no API key, no quota.
function lon(A, body, ms) {
const t = A.MakeTime(new Date(ms));
if (body === 'sun') return A.SunPosition(t).elon;
if (body === 'moon') return A.EclipticGeoMoon(t).lon;
const name = { mer: 'Mercury', ven: 'Venus', mar: 'Mars' }[body];
return A.Ecliptic(A.GeoVector(name, t, true)).elon;
}
const sign = deg => Math.floor(((deg % 360) + 360) % 360 / 30); // 0 = Aries
Each sign is a 30° slice of the ecliptic, so turning a longitude into a sign is one line.
Retrograde, the lazy way
"Mercury is retrograde" is the line people actually read. Instead of looking up tables, we check whether the planet's longitude is going backwards: compare its position 12 hours later with 12 hours earlier.
function isRetro(A, body, ms) {
const d = ((lon(A, body, ms + 432e5) - lon(A, body, ms - 432e5)) % 360 + 360) % 360;
return d > 180; // moved "backwards" around the circle
}
The % 360 dance matters: a planet going from 359° to 1° moved forward 2°, not backwards 358°.
Which week is "this week"?
This sounds trivial and wasn't. If I open the panel on a Friday, I want next week's posts, not the week that is almost over. The rule we settled on: early in the week it shows the current week, and towards the end of the week it jumps to the next one. There is also a button to move one week ahead, so I can prepare posts in advance.
From positions to a reading
For each sign, the generator takes the middle of the week and asks where the Sun, Venus and Mars fall counted from that sign. That gives one of twelve "areas of life" (yourself, money, home, love, work, and so on), each written once per language. Then it walks the seven days and marks the days when the Moon is in a friendly position, in your own sign, or in a tense one.
So the text is assembled, not invented each time. I wrote the building blocks once, with care, in four languages, and the sky picks which ones apply.
The output
In the panel, for each language, I get:
- the post text with the 12 signs and a link to the full week on the site;
- 12 images of 1080 × 1350, one per sign, ready to download.
The link carries a small ?s= tag so our cookie-free counter can tell how many people came from those posts.
What I learned
- Put the boring weekly work in the admin panel. If a task repeats every week, it will eventually be skipped. A button that does it in seconds won't be.
- Real data makes symbolic content more honest. People can check that Mercury really is retrograde. That builds more trust than vague text.
- Edge cases hide in dates. Week boundaries, time zones and the 360° wrap caused more bugs than the astronomy.
- Say what is symbolic. One line under the reading is enough, and nobody complained.
Try it
The chart and the weekly reading are free, with no download and no sign-up: velmoxia.com/en/zodiac.
If you know astronomy better than I do (that is not hard), I'd love to hear what you would do differently, especially for the Moon, which moves a whole sign every two and a half days.
Top comments (0)